diff --git a/README.md b/README.md index 035bc04..ccfb9b9 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ docker stack ps mosaic **Important Notes:** - Swarm does NOT support docker-compose profiles -- To use external services (PostgreSQL, Authentik, etc.), manually comment them out in `docker/docker-compose.swarm.yml` +- To use external services (PostgreSQL, Authentik, etc.), manually comment them out in `docker-compose.swarm.yml` - OpenBao requires manual initialization (no auto-init sidecar in swarm mode) See [Docker Swarm Deployment Guide](docs/SWARM-DEPLOYMENT.md) and [Quick Reference](docs/SWARM-QUICKREF.md) for complete documentation. diff --git a/docker-compose.swarm.yml b/docker-compose.swarm.yml index 1294ca6..60babf3 100644 --- a/docker-compose.swarm.yml +++ b/docker-compose.swarm.yml @@ -1,3 +1,28 @@ +# ============================================== +# Mosaic Stack - Docker Swarm Deployment +# ============================================== +# +# IMPORTANT: Docker Swarm does NOT support docker-compose profiles +# To disable services (e.g., for external alternatives), manually comment them out +# +# Current Configuration: +# - PostgreSQL: ENABLED (internal) +# - Valkey: ENABLED (internal) +# - OpenBao: ENABLED (internal) +# - Authentik: DISABLED (commented out - using external OIDC) +# - Ollama: ENABLED (internal) +# +# For detailed deployment instructions, see: +# docs/SWARM-DEPLOYMENT.md +# +# Quick Start: +# 1. cp .env.swarm.example .env +# 2. nano .env # Configure environment +# 3. ./scripts/deploy-swarm.sh mosaic +# 4. Initialize OpenBao manually (see docs/SWARM-DEPLOYMENT.md) +# +# ============================================== + services: # ====================== # PostgreSQL Database @@ -81,125 +106,119 @@ services: condition: on-failure # ====================== - # Authentik PostgreSQL + # Authentik - COMMENTED OUT (Using External Authentik) # ====================== - authentik-postgres: - image: postgres:17-alpine - env_file: .env - 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: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Authentik Redis - # ====================== - authentik-redis: - image: valkey/valkey:8-alpine - env_file: .env - 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: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Authentik Server - # ====================== - authentik-server: - image: ghcr.io/goauthentik/server:2024.12.1 - env_file: .env - 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:-.mosaicstack.dev} - volumes: - - authentik_media:/media - - authentik_templates:/templates - healthcheck: - test: - [ - "CMD", - "wget", - "--no-verbose", - "--tries=1", - "--spider", - "http://localhost:9000/-/health/live/", - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 90s - networks: - - internal - - traefik-public - deploy: - restart_policy: - condition: on-failure - labels: - - "traefik.enable=true" - - "traefik.http.routers.mosaic-auth.rule=Host(`${MOSAIC_AUTH_DOMAIN:-auth.mosaicstack.dev}`)" - - "traefik.http.routers.mosaic-auth.entrypoints=web" - - "traefik.http.services.mosaic-auth.loadbalancer.server.port=9000" - - # ====================== - # Authentik Worker - # ====================== - authentik-worker: - image: ghcr.io/goauthentik/server:2024.12.1 - env_file: .env - 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 - networks: - - internal - deploy: - restart_policy: - condition: on-failure + # Uncomment these services if you want to run Authentik internally + # For external Authentik, configure OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in .env + # + # authentik-postgres: + # image: postgres:17-alpine + # env_file: .env + # 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: + # - internal + # deploy: + # restart_policy: + # condition: on-failure + # + # authentik-redis: + # image: valkey/valkey:8-alpine + # env_file: .env + # 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: + # - internal + # deploy: + # restart_policy: + # condition: on-failure + # + # authentik-server: + # image: ghcr.io/goauthentik/server:2024.12.1 + # env_file: .env + # 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:-.mosaicstack.dev} + # volumes: + # - authentik_media:/media + # - authentik_templates:/templates + # healthcheck: + # test: + # [ + # "CMD", + # "wget", + # "--no-verbose", + # "--tries=1", + # "--spider", + # "http://localhost:9000/-/health/live/", + # ] + # interval: 30s + # timeout: 10s + # retries: 3 + # start_period: 90s + # networks: + # - internal + # - traefik-public + # deploy: + # restart_policy: + # condition: on-failure + # labels: + # - "traefik.enable=true" + # - "traefik.http.routers.mosaic-auth.rule=Host(`${MOSAIC_AUTH_DOMAIN:-auth.mosaicstack.dev}`)" + # - "traefik.http.routers.mosaic-auth.entrypoints=web" + # - "traefik.http.services.mosaic-auth.loadbalancer.server.port=9000" + # + # authentik-worker: + # image: ghcr.io/goauthentik/server:2024.12.1 + # env_file: .env + # 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 + # networks: + # - internal + # deploy: + # restart_policy: + # condition: on-failure # ====================== # Ollama (Optional AI Service) @@ -345,11 +364,12 @@ volumes: openbao_data: openbao_logs: openbao_init: - authentik_postgres_data: - authentik_redis_data: - authentik_media: - authentik_certs: - authentik_templates: + # Authentik volumes - commented out (using external Authentik) + # authentik_postgres_data: + # authentik_redis_data: + # authentik_media: + # authentik_certs: + # authentik_templates: ollama_data: orchestrator_workspace: diff --git a/docker/docker-compose.swarm.yml b/docker/docker-compose.swarm.yml deleted file mode 100644 index 60babf3..0000000 --- a/docker/docker-compose.swarm.yml +++ /dev/null @@ -1,383 +0,0 @@ -# ============================================== -# Mosaic Stack - Docker Swarm Deployment -# ============================================== -# -# IMPORTANT: Docker Swarm does NOT support docker-compose profiles -# To disable services (e.g., for external alternatives), manually comment them out -# -# Current Configuration: -# - PostgreSQL: ENABLED (internal) -# - Valkey: ENABLED (internal) -# - OpenBao: ENABLED (internal) -# - Authentik: DISABLED (commented out - using external OIDC) -# - Ollama: ENABLED (internal) -# -# For detailed deployment instructions, see: -# docs/SWARM-DEPLOYMENT.md -# -# Quick Start: -# 1. cp .env.swarm.example .env -# 2. nano .env # Configure environment -# 3. ./scripts/deploy-swarm.sh mosaic -# 4. Initialize OpenBao manually (see docs/SWARM-DEPLOYMENT.md) -# -# ============================================== - -services: - # ====================== - # PostgreSQL Database - # ====================== - postgres: - image: git.mosaicstack.dev/mosaic/stack-postgres:${IMAGE_TAG:-latest} - env_file: .env - environment: - POSTGRES_USER: ${POSTGRES_USER:-mosaic} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mosaic_dev_password} - POSTGRES_DB: ${POSTGRES_DB:-mosaic} - POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-256MB} - POSTGRES_EFFECTIVE_CACHE_SIZE: ${POSTGRES_EFFECTIVE_CACHE_SIZE:-1GB} - POSTGRES_MAX_CONNECTIONS: ${POSTGRES_MAX_CONNECTIONS:-100} - volumes: - - postgres_data:/var/lib/postgresql/data - - ./docker/postgres/init-scripts:/docker-entrypoint-initdb.d:ro - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mosaic} -d ${POSTGRES_DB:-mosaic}"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - networks: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Valkey Cache - # ====================== - valkey: - image: valkey/valkey:8-alpine - env_file: .env - command: - - valkey-server - - --maxmemory ${VALKEY_MAXMEMORY:-256mb} - - --maxmemory-policy allkeys-lru - - --appendonly yes - volumes: - - valkey_data:/data - healthcheck: - test: ["CMD", "valkey-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 10s - networks: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # OpenBao Secrets Vault - # ====================== - openbao: - image: git.mosaicstack.dev/mosaic/stack-openbao:${IMAGE_TAG:-latest} - env_file: .env - environment: - OPENBAO_ADDR: ${OPENBAO_ADDR:-http://0.0.0.0:8200} - OPENBAO_DEV_ROOT_TOKEN_ID: ${OPENBAO_DEV_ROOT_TOKEN_ID:-root} - volumes: - - openbao_data:/openbao/data - - openbao_logs:/openbao/logs - - openbao_init:/openbao/init - cap_add: - - IPC_LOCK - healthcheck: - test: - ["CMD", "wget", "--spider", "--quiet", "http://localhost:8200/v1/sys/health?standbyok=true"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - networks: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Authentik - COMMENTED OUT (Using External Authentik) - # ====================== - # Uncomment these services if you want to run Authentik internally - # For external Authentik, configure OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in .env - # - # authentik-postgres: - # image: postgres:17-alpine - # env_file: .env - # 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: - # - internal - # deploy: - # restart_policy: - # condition: on-failure - # - # authentik-redis: - # image: valkey/valkey:8-alpine - # env_file: .env - # 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: - # - internal - # deploy: - # restart_policy: - # condition: on-failure - # - # authentik-server: - # image: ghcr.io/goauthentik/server:2024.12.1 - # env_file: .env - # 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:-.mosaicstack.dev} - # volumes: - # - authentik_media:/media - # - authentik_templates:/templates - # healthcheck: - # test: - # [ - # "CMD", - # "wget", - # "--no-verbose", - # "--tries=1", - # "--spider", - # "http://localhost:9000/-/health/live/", - # ] - # interval: 30s - # timeout: 10s - # retries: 3 - # start_period: 90s - # networks: - # - internal - # - traefik-public - # deploy: - # restart_policy: - # condition: on-failure - # labels: - # - "traefik.enable=true" - # - "traefik.http.routers.mosaic-auth.rule=Host(`${MOSAIC_AUTH_DOMAIN:-auth.mosaicstack.dev}`)" - # - "traefik.http.routers.mosaic-auth.entrypoints=web" - # - "traefik.http.services.mosaic-auth.loadbalancer.server.port=9000" - # - # authentik-worker: - # image: ghcr.io/goauthentik/server:2024.12.1 - # env_file: .env - # 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 - # networks: - # - internal - # deploy: - # restart_policy: - # condition: on-failure - - # ====================== - # Ollama (Optional AI Service) - # ====================== - ollama: - image: ollama/ollama:latest - env_file: .env - 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: - - internal - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Mosaic API - # ====================== - api: - image: git.mosaicstack.dev/mosaic/stack-api:${IMAGE_TAG:-latest} - env_file: .env - environment: - NODE_ENV: production - PORT: ${API_PORT:-3001} - API_HOST: ${API_HOST:-0.0.0.0} - DATABASE_URL: postgresql://${POSTGRES_USER:-mosaic}:${POSTGRES_PASSWORD:-mosaic_dev_password}@postgres:5432/${POSTGRES_DB:-mosaic} - VALKEY_URL: redis://valkey:6379 - OIDC_ISSUER: ${OIDC_ISSUER} - OIDC_CLIENT_ID: ${OIDC_CLIENT_ID} - OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET} - OIDC_REDIRECT_URI: ${OIDC_REDIRECT_URI:-http://localhost:3001/auth/callback} - JWT_SECRET: ${JWT_SECRET:-change-this-to-a-random-secret} - JWT_EXPIRATION: ${JWT_EXPIRATION:-24h} - OLLAMA_ENDPOINT: ${OLLAMA_ENDPOINT:-http://ollama:11434} - OPENBAO_ADDR: ${OPENBAO_ADDR:-http://openbao:8200} - ENCRYPTION_KEY: ${ENCRYPTION_KEY} - healthcheck: - test: - [ - "CMD-SHELL", - 'node -e "require(''http'').get(''http://localhost:${API_PORT:-3001}/health'', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"', - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - networks: - - internal - - traefik-public - deploy: - restart_policy: - condition: on-failure - labels: - - "traefik.enable=true" - - "traefik.http.routers.mosaic-api.rule=Host(`${MOSAIC_API_DOMAIN:-api.mosaicstack.dev}`)" - - "traefik.http.routers.mosaic-api.entrypoints=web" - - "traefik.http.services.mosaic-api.loadbalancer.server.port=${API_PORT:-3001}" - - # ====================== - # Mosaic Orchestrator - # ====================== - orchestrator: - image: git.mosaicstack.dev/mosaic/stack-orchestrator:${IMAGE_TAG:-latest} - env_file: .env - user: "1000:1000" - environment: - NODE_ENV: production - ORCHESTRATOR_PORT: 3001 - VALKEY_URL: redis://valkey:6379 - CLAUDE_API_KEY: ${CLAUDE_API_KEY} - DOCKER_SOCKET: /var/run/docker.sock - GIT_USER_NAME: "Mosaic Orchestrator" - GIT_USER_EMAIL: "orchestrator@mosaicstack.dev" - KILLSWITCH_ENABLED: "true" - SANDBOX_ENABLED: "true" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - orchestrator_workspace:/workspace - healthcheck: - test: - ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - networks: - - internal - # Note: security_opt not supported in swarm mode - # Security hardening done via cap_drop/cap_add - cap_drop: - - ALL - cap_add: - - NET_BIND_SERVICE - tmpfs: - - /tmp:noexec,nosuid,size=100m - deploy: - restart_policy: - condition: on-failure - - # ====================== - # Mosaic Web - # ====================== - web: - image: git.mosaicstack.dev/mosaic/stack-web:${IMAGE_TAG:-latest} - env_file: .env - environment: - NODE_ENV: production - PORT: ${WEB_PORT:-3000} - NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:3001} - healthcheck: - test: - [ - "CMD-SHELL", - 'node -e "require(''http'').get(''http://localhost:${WEB_PORT:-3000}'', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"', - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - networks: - - traefik-public - deploy: - restart_policy: - condition: on-failure - labels: - - "traefik.enable=true" - - "traefik.http.routers.mosaic-web.rule=Host(`${MOSAIC_WEB_DOMAIN:-mosaic.mosaicstack.dev}`)" - - "traefik.http.routers.mosaic-web.entrypoints=web" - - "traefik.http.services.mosaic-web.loadbalancer.server.port=${WEB_PORT:-3000}" - -# ====================== -# Volumes -# ====================== -volumes: - postgres_data: - valkey_data: - openbao_data: - openbao_logs: - openbao_init: - # Authentik volumes - commented out (using external Authentik) - # authentik_postgres_data: - # authentik_redis_data: - # authentik_media: - # authentik_certs: - # authentik_templates: - ollama_data: - orchestrator_workspace: - -# ====================== -# Networks -# ====================== -networks: - internal: - driver: overlay - traefik-public: - external: true diff --git a/docs/SWARM-DEPLOYMENT.md b/docs/SWARM-DEPLOYMENT.md index 551de8d..d028840 100644 --- a/docs/SWARM-DEPLOYMENT.md +++ b/docs/SWARM-DEPLOYMENT.md @@ -108,7 +108,7 @@ cd /opt/mosaic/stack # Or manually IMAGE_TAG=dev docker stack deploy \ - -c docker/docker-compose.swarm.yml \ + -c docker-compose.swarm.yml \ --with-registry-auth mosaic ```