feat: add flexible docker-compose architecture with profiles
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Add OpenBao services to docker-compose.yml with profiles (openbao, full) - Add docker-compose.build.yml for local builds vs registry pulls - Make PostgreSQL and Valkey optional via profiles (database, cache) - Create example compose files for common deployment scenarios: - docker/docker-compose.example.turnkey.yml (all bundled) - docker/docker-compose.example.external.yml (all external) - docker/docker.example.hybrid.yml (mixed deployment) - Update documentation: - Enhance .env.example with profiles and external service examples - Update README.md with deployment mode quick starts - Add deployment scenarios to docs/OPENBAO.md - Create docker/DOCKER-COMPOSE-GUIDE.md with comprehensive guide - Clean up repository structure: - Move shell scripts to scripts/ directory - Move documentation to docs/ directory - Move docker compose examples to docker/ directory - Configure for external Authentik with internal services: - Comment out Authentik services (using external OIDC) - Comment out unused volumes for disabled services - Keep postgres, valkey, openbao as internal services This provides a flexible deployment architecture supporting turnkey, production (all external), and hybrid configurations via Docker Compose profiles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,7 @@ services:
|
||||
# PostgreSQL Database
|
||||
# ======================
|
||||
postgres:
|
||||
build:
|
||||
context: ./docker/postgres
|
||||
dockerfile: Dockerfile
|
||||
image: git.mosaicstack.dev/mosaic/stack-postgres:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -29,6 +27,9 @@ services:
|
||||
start_period: 30s
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- database
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=database"
|
||||
- "com.mosaic.description=PostgreSQL 17 with pgvector"
|
||||
@@ -57,6 +58,9 @@ services:
|
||||
start_period: 10s
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- cache
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=cache"
|
||||
- "com.mosaic.description=Valkey Redis-compatible cache"
|
||||
@@ -64,43 +68,212 @@ services:
|
||||
# ======================
|
||||
# Authentik PostgreSQL
|
||||
# ======================
|
||||
authentik-postgres:
|
||||
image: postgres:17-alpine
|
||||
container_name: mosaic-authentik-postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
POSTGRES_PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
POSTGRES_DB: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
volumes:
|
||||
- authentik_postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${AUTHENTIK_POSTGRES_USER:-authentik}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- authentik
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=auth-database"
|
||||
- "com.mosaic.description=Authentik PostgreSQL database"
|
||||
# authentik-postgres:
|
||||
# image: postgres:17-alpine
|
||||
# container_name: mosaic-authentik-postgres
|
||||
# restart: unless-stopped
|
||||
# environment:
|
||||
# POSTGRES_USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
# POSTGRES_PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
# POSTGRES_DB: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
# volumes:
|
||||
# - authentik_postgres_data:/var/lib/postgresql/data
|
||||
# healthcheck:
|
||||
# test: ["CMD-SHELL", "pg_isready -U ${AUTHENTIK_POSTGRES_USER:-authentik}"]
|
||||
# interval: 10s
|
||||
# timeout: 5s
|
||||
# retries: 5
|
||||
# start_period: 20s
|
||||
# networks:
|
||||
# - mosaic-internal
|
||||
# profiles:
|
||||
# - authentik
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=auth-database"
|
||||
# - "com.mosaic.description=Authentik PostgreSQL database"
|
||||
|
||||
# ======================
|
||||
# Authentik Redis
|
||||
# ======================
|
||||
authentik-redis:
|
||||
image: valkey/valkey:8-alpine
|
||||
container_name: mosaic-authentik-redis
|
||||
# authentik-redis:
|
||||
# image: valkey/valkey:8-alpine
|
||||
# container_name: mosaic-authentik-redis
|
||||
# restart: unless-stopped
|
||||
# command: valkey-server --save 60 1 --loglevel warning
|
||||
# volumes:
|
||||
# - authentik_redis_data:/data
|
||||
# healthcheck:
|
||||
# test: ["CMD", "valkey-cli", "ping"]
|
||||
# interval: 10s
|
||||
# timeout: 5s
|
||||
# retries: 5
|
||||
# start_period: 10s
|
||||
# networks:
|
||||
# - mosaic-internal
|
||||
# profiles:
|
||||
# - authentik
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=auth-cache"
|
||||
# - "com.mosaic.description=Authentik Redis cache"
|
||||
|
||||
# ======================
|
||||
# Authentik Server
|
||||
# ======================
|
||||
# authentik-server:
|
||||
# image: ghcr.io/goauthentik/server:2025.10.2
|
||||
# container_name: mosaic-authentik-server
|
||||
# restart: unless-stopped
|
||||
# command: server
|
||||
# environment:
|
||||
# AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-change-this-to-a-random-secret}
|
||||
# AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING:-false}
|
||||
# AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
|
||||
# AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
# AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
# AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
# AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
# AUTHENTIK_REDIS__HOST: authentik-redis
|
||||
# AUTHENTIK_REDIS__PORT: 6379
|
||||
# AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD:-admin}
|
||||
# AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL:-admin@localhost}
|
||||
# AUTHENTIK_COOKIE_DOMAIN: ${AUTHENTIK_COOKIE_DOMAIN:-.localhost}
|
||||
# ports:
|
||||
# - "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||
# - "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||
# volumes:
|
||||
# - authentik_media:/media
|
||||
# - authentik_templates:/templates
|
||||
# depends_on:
|
||||
# authentik-postgres:
|
||||
# condition: service_healthy
|
||||
# authentik-redis:
|
||||
# condition: service_healthy
|
||||
# healthcheck:
|
||||
# test:
|
||||
# [
|
||||
# "CMD",
|
||||
# "wget",
|
||||
# "--no-verbose",
|
||||
# "--tries=1",
|
||||
# "--spider",
|
||||
# "http://localhost:9000/-/health/live/",
|
||||
# ]
|
||||
# interval: 30s
|
||||
# timeout: 10s
|
||||
# retries: 3
|
||||
# start_period: 90s
|
||||
# networks:
|
||||
# - mosaic-internal
|
||||
# - mosaic-public
|
||||
# profiles:
|
||||
# - authentik
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=auth-server"
|
||||
# - "com.mosaic.description=Authentik OIDC server"
|
||||
# # Traefik labels (activated when TRAEFIK_MODE=bundled or upstream)
|
||||
# - "traefik.enable=${TRAEFIK_ENABLE:-false}"
|
||||
# - "traefik.http.routers.mosaic-auth.rule=Host(`${MOSAIC_AUTH_DOMAIN:-auth.mosaic.local}`)"
|
||||
# - "traefik.http.routers.mosaic-auth.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||
# - "traefik.http.routers.mosaic-auth.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||
# - "traefik.http.services.mosaic-auth.loadbalancer.server.port=9000"
|
||||
# - "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-mosaic-public}"
|
||||
# # Let's Encrypt (if enabled)
|
||||
# - "traefik.http.routers.mosaic-auth.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||
|
||||
# ======================
|
||||
# Authentik Worker
|
||||
# ======================
|
||||
# authentik-worker:
|
||||
# image: ghcr.io/goauthentik/server:2025.10.2
|
||||
# container_name: mosaic-authentik-worker
|
||||
# restart: unless-stopped
|
||||
# command: worker
|
||||
# environment:
|
||||
# AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-change-this-to-a-random-secret}
|
||||
# AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING:-false}
|
||||
# AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
|
||||
# AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
# AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
# AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
# AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
# AUTHENTIK_REDIS__HOST: authentik-redis
|
||||
# AUTHENTIK_REDIS__PORT: 6379
|
||||
# volumes:
|
||||
# - authentik_media:/media
|
||||
# - authentik_certs:/certs
|
||||
# - authentik_templates:/templates
|
||||
# depends_on:
|
||||
# authentik-postgres:
|
||||
# condition: service_healthy
|
||||
# authentik-redis:
|
||||
# condition: service_healthy
|
||||
# networks:
|
||||
# - mosaic-internal
|
||||
# profiles:
|
||||
# - authentik
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=auth-worker"
|
||||
# - "com.mosaic.description=Authentik background worker"
|
||||
|
||||
# ======================
|
||||
# Ollama (Optional AI Service)
|
||||
# ======================
|
||||
# ollama:
|
||||
# image: ollama/ollama:latest
|
||||
# container_name: mosaic-ollama
|
||||
# restart: unless-stopped
|
||||
# ports:
|
||||
# - "${OLLAMA_PORT:-11434}:11434"
|
||||
# volumes:
|
||||
# - ollama_data:/root/.ollama
|
||||
# healthcheck:
|
||||
# test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
|
||||
# interval: 30s
|
||||
# timeout: 10s
|
||||
# retries: 3
|
||||
# start_period: 60s
|
||||
# networks:
|
||||
# - mosaic-internal
|
||||
# profiles:
|
||||
# - ollama
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=ai"
|
||||
# - "com.mosaic.description=Ollama LLM service"
|
||||
# # Uncomment if you have GPU support
|
||||
# # deploy:
|
||||
# # resources:
|
||||
# # reservations:
|
||||
# # devices:
|
||||
# # - driver: nvidia
|
||||
# # count: 1
|
||||
# # capabilities: [gpu]
|
||||
|
||||
# ======================
|
||||
# OpenBao Secrets Management (Optional)
|
||||
# ======================
|
||||
openbao:
|
||||
image: git.mosaicstack.dev/mosaic/stack-openbao:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-openbao
|
||||
restart: unless-stopped
|
||||
command: valkey-server --save 60 1 --loglevel warning
|
||||
user: root
|
||||
ports:
|
||||
- "127.0.0.1:${OPENBAO_PORT:-8200}:8200"
|
||||
volumes:
|
||||
- authentik_redis_data:/data
|
||||
- openbao_data:/openbao/data
|
||||
- openbao_init:/openbao/init
|
||||
environment:
|
||||
VAULT_ADDR: http://0.0.0.0:8200
|
||||
SKIP_SETCAP: "true"
|
||||
command: ["bao", "server", "-config=/openbao/config/config.hcl"]
|
||||
cap_add:
|
||||
- IPC_LOCK
|
||||
healthcheck:
|
||||
test: ["CMD", "valkey-cli", "ping"]
|
||||
test: ["CMD-SHELL", "nc -z 127.0.0.1 8200 || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
@@ -108,193 +281,76 @@ services:
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- authentik
|
||||
- openbao
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=auth-cache"
|
||||
- "com.mosaic.description=Authentik Redis cache"
|
||||
- "com.mosaic.service=secrets"
|
||||
- "com.mosaic.description=OpenBao secrets management"
|
||||
|
||||
# ======================
|
||||
# Authentik Server
|
||||
# ======================
|
||||
authentik-server:
|
||||
image: ghcr.io/goauthentik/server:2024.12.1
|
||||
container_name: mosaic-authentik-server
|
||||
openbao-init:
|
||||
image: git.mosaicstack.dev/mosaic/stack-openbao:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-openbao-init
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
user: root
|
||||
volumes:
|
||||
- openbao_init:/openbao/init
|
||||
environment:
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-change-this-to-a-random-secret}
|
||||
AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING:-false}
|
||||
AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
|
||||
AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
AUTHENTIK_REDIS__HOST: authentik-redis
|
||||
AUTHENTIK_REDIS__PORT: 6379
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD:-admin}
|
||||
AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL:-admin@localhost}
|
||||
AUTHENTIK_COOKIE_DOMAIN: ${AUTHENTIK_COOKIE_DOMAIN:-.localhost}
|
||||
ports:
|
||||
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||
volumes:
|
||||
- authentik_media:/media
|
||||
- authentik_templates:/templates
|
||||
VAULT_ADDR: http://openbao:8200
|
||||
command: ["/openbao/init.sh"]
|
||||
depends_on:
|
||||
authentik-postgres:
|
||||
condition: service_healthy
|
||||
authentik-redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"wget",
|
||||
"--no-verbose",
|
||||
"--tries=1",
|
||||
"--spider",
|
||||
"http://localhost:9000/-/health/live/",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 90s
|
||||
networks:
|
||||
- mosaic-internal
|
||||
- mosaic-public
|
||||
profiles:
|
||||
- authentik
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=auth-server"
|
||||
- "com.mosaic.description=Authentik OIDC server"
|
||||
# Traefik labels (activated when TRAEFIK_MODE=bundled or upstream)
|
||||
- "traefik.enable=${TRAEFIK_ENABLE:-false}"
|
||||
- "traefik.http.routers.mosaic-auth.rule=Host(`${MOSAIC_AUTH_DOMAIN:-auth.mosaic.local}`)"
|
||||
- "traefik.http.routers.mosaic-auth.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||
- "traefik.http.routers.mosaic-auth.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||
- "traefik.http.services.mosaic-auth.loadbalancer.server.port=9000"
|
||||
- "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-mosaic-public}"
|
||||
# Let's Encrypt (if enabled)
|
||||
- "traefik.http.routers.mosaic-auth.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||
|
||||
# ======================
|
||||
# Authentik Worker
|
||||
# ======================
|
||||
authentik-worker:
|
||||
image: ghcr.io/goauthentik/server:2024.12.1
|
||||
container_name: mosaic-authentik-worker
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:-change-this-to-a-random-secret}
|
||||
AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING:-false}
|
||||
AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
|
||||
AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik_password}
|
||||
AUTHENTIK_REDIS__HOST: authentik-redis
|
||||
AUTHENTIK_REDIS__PORT: 6379
|
||||
volumes:
|
||||
- authentik_media:/media
|
||||
- authentik_certs:/certs
|
||||
- authentik_templates:/templates
|
||||
depends_on:
|
||||
authentik-postgres:
|
||||
condition: service_healthy
|
||||
authentik-redis:
|
||||
openbao:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- authentik
|
||||
- openbao
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=auth-worker"
|
||||
- "com.mosaic.description=Authentik background worker"
|
||||
|
||||
# ======================
|
||||
# Ollama (Optional AI Service)
|
||||
# ======================
|
||||
ollama:
|
||||
image: ollama/ollama:latest
|
||||
container_name: mosaic-ollama
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${OLLAMA_PORT:-11434}:11434"
|
||||
volumes:
|
||||
- ollama_data:/root/.ollama
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
networks:
|
||||
- mosaic-internal
|
||||
profiles:
|
||||
- ollama
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=ai"
|
||||
- "com.mosaic.description=Ollama LLM service"
|
||||
# Uncomment if you have GPU support
|
||||
# deploy:
|
||||
# resources:
|
||||
# reservations:
|
||||
# devices:
|
||||
# - driver: nvidia
|
||||
# count: 1
|
||||
# capabilities: [gpu]
|
||||
- "com.mosaic.service=secrets-init"
|
||||
- "com.mosaic.description=OpenBao auto-initialization sidecar"
|
||||
|
||||
# ======================
|
||||
# Traefik Reverse Proxy (Optional - Bundled Mode)
|
||||
# ======================
|
||||
# Enable with: COMPOSE_PROFILES=traefik-bundled or --profile traefik-bundled
|
||||
# Set TRAEFIK_MODE=bundled in .env
|
||||
traefik:
|
||||
image: traefik:v3.2
|
||||
container_name: mosaic-traefik
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- "--configFile=/etc/traefik/traefik.yml"
|
||||
ports:
|
||||
- "${TRAEFIK_HTTP_PORT:-80}:80"
|
||||
- "${TRAEFIK_HTTPS_PORT:-443}:443"
|
||||
- "${TRAEFIK_DASHBOARD_PORT:-8080}:8080"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./docker/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
- ./docker/traefik/dynamic:/etc/traefik/dynamic:ro
|
||||
- traefik_letsencrypt:/letsencrypt
|
||||
environment:
|
||||
- TRAEFIK_ACME_EMAIL=${TRAEFIK_ACME_EMAIL:-}
|
||||
networks:
|
||||
- mosaic-public
|
||||
profiles:
|
||||
- traefik-bundled
|
||||
- full
|
||||
labels:
|
||||
- "com.mosaic.service=reverse-proxy"
|
||||
- "com.mosaic.description=Traefik reverse proxy and load balancer"
|
||||
healthcheck:
|
||||
test: ["CMD", "traefik", "healthcheck", "--ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
# traefik:
|
||||
# image: traefik:v3.2
|
||||
# container_name: mosaic-traefik
|
||||
# restart: unless-stopped
|
||||
# command:
|
||||
# - "--configFile=/etc/traefik/traefik.yml"
|
||||
# ports:
|
||||
# - "${TRAEFIK_HTTP_PORT:-80}:80"
|
||||
# - "${TRAEFIK_HTTPS_PORT:-443}:443"
|
||||
# - "${TRAEFIK_DASHBOARD_PORT:-8080}:8080"
|
||||
# volumes:
|
||||
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
# - ./docker/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
# - ./docker/traefik/dynamic:/etc/traefik/dynamic:ro
|
||||
# - traefik_letsencrypt:/letsencrypt
|
||||
# environment:
|
||||
# - TRAEFIK_ACME_EMAIL=${TRAEFIK_ACME_EMAIL:-}
|
||||
# networks:
|
||||
# - mosaic-public
|
||||
# profiles:
|
||||
# - traefik-bundled
|
||||
# - full
|
||||
# labels:
|
||||
# - "com.mosaic.service=reverse-proxy"
|
||||
# - "com.mosaic.description=Traefik reverse proxy and load balancer"
|
||||
# healthcheck:
|
||||
# test: ["CMD", "traefik", "healthcheck", "--ping"]
|
||||
# interval: 30s
|
||||
# timeout: 10s
|
||||
# retries: 3
|
||||
# start_period: 20s
|
||||
|
||||
# ======================
|
||||
# Mosaic API
|
||||
# ======================
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./apps/api/Dockerfile
|
||||
args:
|
||||
- NODE_ENV=production
|
||||
image: git.mosaicstack.dev/mosaic/stack-api:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-api
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -316,6 +372,10 @@ services:
|
||||
JWT_EXPIRATION: ${JWT_EXPIRATION:-24h}
|
||||
# Ollama (optional)
|
||||
OLLAMA_ENDPOINT: ${OLLAMA_ENDPOINT:-http://ollama:11434}
|
||||
# OpenBao (optional)
|
||||
OPENBAO_ADDR: ${OPENBAO_ADDR:-http://openbao:8200}
|
||||
volumes:
|
||||
- openbao_init:/openbao/init:ro
|
||||
ports:
|
||||
- "${API_PORT:-3001}:${API_PORT:-3001}"
|
||||
depends_on:
|
||||
@@ -353,9 +413,7 @@ services:
|
||||
# Mosaic Orchestrator
|
||||
# ======================
|
||||
orchestrator:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./apps/orchestrator/Dockerfile
|
||||
image: git.mosaicstack.dev/mosaic/stack-orchestrator:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-orchestrator
|
||||
restart: unless-stopped
|
||||
# Run as non-root user (node:node, UID 1000)
|
||||
@@ -387,7 +445,8 @@ services:
|
||||
api:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1"]
|
||||
test:
|
||||
["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -401,7 +460,7 @@ services:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE
|
||||
read_only: false # Cannot be read-only due to workspace writes
|
||||
read_only: false # Cannot be read-only due to workspace writes
|
||||
tmpfs:
|
||||
- /tmp:noexec,nosuid,size=100m
|
||||
labels:
|
||||
@@ -415,11 +474,7 @@ services:
|
||||
# Mosaic Web
|
||||
# ======================
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./apps/web/Dockerfile
|
||||
args:
|
||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:3001}
|
||||
image: git.mosaicstack.dev/mosaic/stack-web:${IMAGE_TAG:-dev}
|
||||
container_name: mosaic-web
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -466,27 +521,33 @@ volumes:
|
||||
valkey_data:
|
||||
name: mosaic-valkey-data
|
||||
driver: local
|
||||
authentik_postgres_data:
|
||||
name: mosaic-authentik-postgres-data
|
||||
# authentik_postgres_data:
|
||||
# name: mosaic-authentik-postgres-data
|
||||
# driver: local
|
||||
# authentik_redis_data:
|
||||
# name: mosaic-authentik-redis-data
|
||||
# driver: local
|
||||
# authentik_media:
|
||||
# name: mosaic-authentik-media
|
||||
# driver: local
|
||||
# authentik_certs:
|
||||
# name: mosaic-authentik-certs
|
||||
# driver: local
|
||||
# authentik_templates:
|
||||
# name: mosaic-authentik-templates
|
||||
# driver: local
|
||||
# ollama_data:
|
||||
# name: mosaic-ollama-data
|
||||
# driver: local
|
||||
openbao_data:
|
||||
name: mosaic-openbao-data
|
||||
driver: local
|
||||
authentik_redis_data:
|
||||
name: mosaic-authentik-redis-data
|
||||
driver: local
|
||||
authentik_media:
|
||||
name: mosaic-authentik-media
|
||||
driver: local
|
||||
authentik_certs:
|
||||
name: mosaic-authentik-certs
|
||||
driver: local
|
||||
authentik_templates:
|
||||
name: mosaic-authentik-templates
|
||||
driver: local
|
||||
ollama_data:
|
||||
name: mosaic-ollama-data
|
||||
driver: local
|
||||
traefik_letsencrypt:
|
||||
name: mosaic-traefik-letsencrypt
|
||||
openbao_init:
|
||||
name: mosaic-openbao-init
|
||||
driver: local
|
||||
# traefik_letsencrypt:
|
||||
# name: mosaic-traefik-letsencrypt
|
||||
# driver: local
|
||||
orchestrator_workspace:
|
||||
name: mosaic-orchestrator-workspace
|
||||
driver: local
|
||||
|
||||
Reference in New Issue
Block a user