Files
headquarter/docker-compose.traefik.yml
alex 5f39267781 fix: use bind mount for instances in traefik compose
- Change from named volume instance_data to host bind mount
- Consistent with docker-compose.yml fix for clone mode

Refs: clone mode repo files not visible in containers
2026-05-24 11:42:29 +00:00

128 lines
4.1 KiB
YAML

# Docker Compose for deployment behind an existing Traefik reverse proxy
# All domains and the proxy web name are configurable via environment variables
services:
# PostgreSQL Database
postgres:
image: postgres:15-alpine
container_name: hq-postgres
environment:
POSTGRES_USER: ${POSTGRES_USER:-headquarter}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-headquarter}
POSTGRES_DB: ${POSTGRES_DB:-headquarter}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-headquarter} -d ${POSTGRES_DB:-headquarter}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
networks:
- backend
restart: unless-stopped
# Redis Cache
redis:
image: redis:7-alpine
container_name: hq-redis
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
start_period: 5s
networks:
- backend
restart: unless-stopped
# Web Frontend
headquarter-frontend:
build:
context: ./apps/web
dockerfile: Dockerfile
args:
VITE_API_BASE_URL: ${API_PUBLIC_URL:-https://${API_DOMAIN}}
VITE_APP_URL: ${WEB_PUBLIC_URL:-https://${WEB_DOMAIN}}
container_name: hq-web
environment:
VITE_API_BASE_URL: ${API_PUBLIC_URL:-https://${API_DOMAIN}}
VITE_APP_URL: ${WEB_PUBLIC_URL:-https://${WEB_DOMAIN}}
depends_on:
- headquarter-api
networks:
- backend
- traefik
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-frontend.rule=Host(`${WEB_DOMAIN}`)"
- "traefik.http.routers.headquarter-frontend.entrypoints=websecure"
- "traefik.http.routers.headquarter-frontend.tls=true"
- "traefik.http.routers.headquarter-frontend.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-frontend.loadbalancer.server.port=80"
# API Service
headquarter-api:
build:
context: ./apps/api
dockerfile: Dockerfile
container_name: hq-api
environment:
APP_ENV: production
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-headquarter}:${POSTGRES_PASSWORD:-headquarter}@postgres:5432/${POSTGRES_DB:-headquarter}
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
REDIS_URL: redis://redis:6379/0
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24}
REPO_BASE_PATH: /data/repos
INSTANCE_BASE_PATH: /data/instances
API_DOMAIN: ${API_DOMAIN}
WEB_DOMAIN: ${WEB_DOMAIN}
AUTHENTIK_DOMAIN: ${AUTHENTIK_DOMAIN}
API_PUBLIC_URL: ${API_PUBLIC_URL:-}
WEB_PUBLIC_URL: ${WEB_PUBLIC_URL:-}
AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:-headquarter-web}
AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET}
AUTHENTIK_APPLICATION_SLUG: ${AUTHENTIK_APPLICATION_SLUG:-headquarter-web}
AUTHENTIK_AUTHORIZE_URL: ${AUTHENTIK_AUTHORIZE_URL:-}
AUTHENTIK_TOKEN_URL: ${AUTHENTIK_TOKEN_URL:-}
volumes:
- repo_data:/data/repos
- /data/instances:/data/instances
- avatar_uploads:/app/uploads
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
- traefik
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.headquarter-api.rule=Host(`${API_DOMAIN}`)"
- "traefik.http.routers.headquarter-api.entrypoints=websecure"
- "traefik.http.routers.headquarter-api.tls=true"
- "traefik.http.routers.headquarter-api.tls.certresolver=${TRAEFIK_CERT_RESOLVER:-letsencrypt}"
- "traefik.http.services.headquarter-api.loadbalancer.server.port=8000"
volumes:
postgres_data:
redis_data:
repo_data:
avatar_uploads:
networks:
backend:
driver: bridge
traefik:
external: true
name: ${TRAEFIK_NETWORK:-traefik}