# Copyright 2023 Specter Ops, Inc. # # Licensed under the Apache License, Version 2.0 # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 services: proxy: image: docker.io/library/traefik:latest command: - --api.insecure=true - --providers.docker - --providers.docker.exposedbydefault=false ports: - ${WEB_PORT:-127.0.0.1:80}:80 - ${TRAEFIK_PORT:-127.0.0.1:8000}:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro app-db: profiles: - dev - api-only - ui-only - debug-api - pg-only - sso image: docker.io/library/postgres:16 environment: - PGUSER=${BH_POSTGRES_USER:-bloodhound} - POSTGRES_USER=${BH_POSTGRES_USER:-bloodhound} - POSTGRES_PASSWORD=${BH_POSTGRES_PASSWORD:-bloodhoundcommunityedition} - POSTGRES_DB=${BH_POSTGRES_DB:-bloodhound} ports: - ${BH_POSTGRES_PORT:-127.0.0.1:5432}:5432 volumes: - ${BH_POSTGRES_VOLUME:-postgres-data}:/var/lib/postgresql/data healthcheck: test: [ "CMD-SHELL", "pg_isready -U ${BH_POSTGRES_USER:-bloodhound} -d 'dbname=${BH_POSTGRES_DB:-bloodhound}' -h 127.0.0.1 -p 5432", ] interval: 10s timeout: 5s retries: 5 start_period: 30s pgadmin: profiles: - dev - api-only - ui-only - debug-api - pg-only - sso build: context: tools/docker-compose dockerfile: pgadmin.Dockerfile environment: PGADMIN_DEFAULT_EMAIL: ${BH_PG_ADMIN_EMAIL:-bloodhound@specterops.io} PGADMIN_DEFAULT_PASSWORD: ${BH_PG_ADMIN_PASSWORD:-bloodhoundcommunityedition} PGADMIN_LISTEN_PORT: 5050 ports: - ${BH_PG_ADMIN_PORT:-127.0.0.1:5050}:5050 labels: - traefik.enable=true - traefik.http.routers.pgadmin.rule=Host(`${BH_PG_ADMIN_HOSTNAME:-pgadmin.localhost}`) - traefik.http.routers.pgadmin.service=pgadmin - traefik.http.services.pgadmin.loadbalancer.server.port=5050 depends_on: app-db: condition: service_healthy graph-db: profiles: - dev - api-only - ui-only - debug-api - sso build: args: memconfig: true context: tools/docker-compose dockerfile: neo4j.Dockerfile environment: - NEO4J_AUTH=${BH_NEO4J_AUTH:-neo4j/bloodhoundcommunityedition} - NEO4J_dbms_allow__upgrade=${BH_NEO4J_ALLOW_UPGRADE:-true} ports: - ${BH_NEO4J_PORT:-127.0.0.1:7687}:7687 - ${BH_NEO4J_WEB_PORT:-127.0.0.1:7474}:7474 volumes: - ${BH_NEO4J_VOLUME:-neo4j-data}:/data labels: - traefik.enable=true - traefik.http.routers.neo4jbrowser.rule=Host(`${BH_NEO4J_HOSTNAME:-neo4j.localhost}`) - traefik.http.routers.neo4jbrowser.service=neo4jbrowser - traefik.http.services.neo4jbrowser.loadbalancer.server.port=7474 healthcheck: test: ["CMD-SHELL", "wget -O /dev/null -q http://localhost:7474 || exit 1"] interval: 10s timeout: 5s retries: 5 start_period: 30s bh-api: &bh-api profiles: - dev - api-only build: context: tools/docker-compose dockerfile: api.Dockerfile command: "-c .air.toml ${AIR_FLAGS:-''}" environment: bhe_disable_cypher_complexity_limit: ${bhe_disable_cypher_complexity_limit:-false} bhe_enable_cypher_mutations: ${bhe_enable_cypher_mutations:-false} bhe_graph_query_memory_limit: ${bhe_graph_query_memory_limit:-2} bhe_enable_text_logger: ${bhe_enable_text_logger:-true} bhe_recreate_default_admin: ${bhe_recreate_default_admin:-false} ports: - ${BH_API_PORT:-127.0.0.1:8080}:8080 - ${TOOLAPI_PORT:-127.0.0.1:2112}:2112 labels: - traefik.enable=true - traefik.http.routers.bhapi.rule=Host(`${BH_HOSTNAME:-bloodhound.localhost}`) && PathPrefix(`/api`) - traefik.http.routers.bhapi.service=bhapi - traefik.http.services.bhapi.loadbalancer.server.port=8080 volumes: - .:/bloodhound:ro - ./local-harnesses/${BH_CONFIG_FILE:-build.config.json}:/build.config.json:ro - go-pkg-mod:/go/pkg/mod depends_on: app-db: condition: service_healthy graph-db: condition: service_healthy bh-ui: profiles: - dev - ui-only - debug-api - sso build: context: . dockerfile: tools/docker-compose/ui.Dockerfile command: sh -c "yarn dev" labels: - traefik.enable=true - traefik.http.routers.bhui.rule=Host(`${BH_HOSTNAME:-bloodhound.localhost}`) - traefik.http.middlewares.add-bh-ui.addprefix.prefix=/ui - traefik.http.routers.bhui.service=bhui - traefik.http.services.bhui.loadbalancer.server.port=3000 volumes: - ./cmd/ui/public:/bloodhound/cmd/ui/public:ro - ./cmd/ui/src:/bloodhound/cmd/ui/src:ro - ./packages/javascript/bh-shared-ui/src:/bloodhound/packages/javascript/bh-shared-ui/src:ro - ./packages/javascript/js-client-library/src:/bloodhound/packages/javascript/js-client-library/src:ro - ui-cache:/.cache debug-api: profiles: - debug-api build: context: tools/docker-compose dockerfile: api.Dockerfile command: "-c .air.debug.toml ${AIR_FLAGS:-''}" environment: bhe_disable_cypher_complexity_limit: ${bhe_disable_cypher_complexity_limit:-false} bhe_enable_cypher_mutations: ${bhe_enable_cypher_mutations:-false} bhe_graph_query_memory_limit: ${bhe_graph_query_memory_limit:-2} bhe_enable_text_logger: ${bhe_enable_text_logger:-true} bhe_recreate_default_admin: ${bhe_recreate_default_admin:-false} ports: - ${BH_API_PORT:-127.0.0.1:8080}:8080 - ${TOOLAPI_PORT:-127.0.0.1:2112}:2112 - ${DEBUG_PORT:-127.0.0.1:3456}:2345 labels: - traefik.enable=true - traefik.http.routers.debugapi.rule=Host(`${BH_HOSTNAME:-bloodhound.localhost}`) && PathPrefix(`/api`) - traefik.http.routers.debugapi.service=debugapi - traefik.http.services.debugapi.loadbalancer.server.port=8080 volumes: - .:/bloodhound:ro - ./local-harnesses/${BH_CONFIG_FILE:-build.config.json}:/build.config.json:ro depends_on: app-db: condition: service_healthy graph-db: condition: service_healthy bh-api-sso: <<: *bh-api profiles: - sso links: - authentik:authentik.localhost authentik: profiles: - sso - sso-only image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7} restart: unless-stopped command: server environment: AUTHENTIK_LISTEN__HTTP: 0.0.0.0:80 AUTHENTIK_REDIS__HOST: authentik-valkey AUTHENTIK_POSTGRESQL__HOST: authentik-db AUTHENTIK_POSTGRESQL__USER: ${ATK_BH_PG_USER:-authentik} AUTHENTIK_POSTGRESQL__NAME: ${ATK_BH_PG_DB:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition} AUTHENTIK_SECRET_KEY: ${ATK_BH_SECRET:-bloodhoundcommunityedition} labels: - traefik.enable=true - traefik.http.routers.authentik.rule=Host(`${BH_AUTHENTIK_HOSTNAME:-authentik.localhost}`) - traefik.http.routers.authentik.service=authentik - traefik.http.services.authentik.loadbalancer.server.port=80 ports: - "${COMPOSE_PORT_HTTP:-9000}:80" - "${COMPOSE_PORT_HTTPS:-9443}:9443" depends_on: - authentik-db - authentik-valkey authentik-worker: profiles: - sso - sso-only image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7} restart: unless-stopped command: worker environment: AUTHENTIK_REDIS__HOST: authentik-valkey AUTHENTIK_POSTGRESQL__HOST: authentik-db AUTHENTIK_POSTGRESQL__USER: ${ATK_BH_PG_USER:-authentik} AUTHENTIK_POSTGRESQL__NAME: ${ATK_BH_PG_DB:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition} AUTHENTIK_SECRET_KEY: ${ATK_BH_SECRET:-bloodhoundcommunityedition} depends_on: - authentik-db - authentik-valkey authentik-valkey: profiles: - sso - sso-only image: docker.io/valkey/valkey:alpine command: --save 60 1 --loglevel warning restart: unless-stopped volumes: - authentik-valkey:/data authentik-db: profiles: - sso - sso-only image: docker.io/library/postgres:13.2-alpine restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] start_period: 20s interval: 30s retries: 5 timeout: 5s volumes: - authentik-db:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition} POSTGRES_USER: ${ATK_BH_PG_USER:-authentik} POSTGRES_DB: ${ATK_BH_PG_DB:-authentik} volumes: neo4j-data: postgres-data: go-pkg-mod: ui-cache: authentik-valkey: authentik-db: