# Docker Compose for Coolify deployment of ECHODO. # # Usage in Coolify: # - New Resource → Docker Compose → connect this repo # - Build pack: Docker Compose # - Compose file path: docker/docker-compose.coolify.yml # - Set domains in Coolify on the `web` and `collab` services using http:// # (CT 100 Traefik handles TLS termination per AGENT-DEPLOY.md) # # Path conventions: # Coolify invokes `docker compose` with --project-directory set to the # repository root, NOT this file's directory. So all build contexts and # dockerfile paths below are written relative to the repo root. # # Differences vs. docker/docker-compose.yml: # - No bundled postgres / redis (uses shared CT 102 services) # - No host port mappings (Coolify's Traefik routes by container labels) # - Uses Coolify SERVICE_FQDN_* magic env vars so Coolify auto-wires Traefik labels # # Build strategy: # All three services share docker/Dockerfile and select runtime via `target:`. # The shared `deps` stage is hashed identically across targets, so BuildKit # runs `pnpm install` ONCE. # # `web` declares depends_on collab+mcp so Compose builds the lightweight # services first and the heavy `next build` (peak ~2.5 GB heap) gets the host # effectively to itself instead of fighting concurrent runtime-stage COPYs # for memory. services: web: build: context: . dockerfile: docker/Dockerfile target: web depends_on: - collab - mcp restart: unless-stopped environment: # Coolify FQDN magic var — set the domain in the Coolify UI for this service. # SERVICE_FQDN_WEB_3000 makes Coolify expose the container on port 3000 via Traefik. - SERVICE_FQDN_WEB_3000 - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - NEXTAUTH_URL=${NEXTAUTH_URL} - NEXTAUTH_SECRET=${NEXTAUTH_SECRET} - AUTH_SECRET=${AUTH_SECRET} - AUTH_DEV_PASSWORD=${AUTH_DEV_PASSWORD} - AUTH_GITHUB_ID=${AUTH_GITHUB_ID} - AUTH_GITHUB_SECRET=${AUTH_GITHUB_SECRET} - AUTH_GOOGLE_ID=${AUTH_GOOGLE_ID} - AUTH_GOOGLE_SECRET=${AUTH_GOOGLE_SECRET} - AUTH_AUTHENTIK_ID=${AUTH_AUTHENTIK_ID} - AUTH_AUTHENTIK_SECRET=${AUTH_AUTHENTIK_SECRET} - AUTH_AUTHENTIK_ISSUER=${AUTH_AUTHENTIK_ISSUER} - COLLAB_SERVER_URL=${COLLAB_SERVER_URL} - NEXT_PUBLIC_COLLAB_SERVER_URL=${NEXT_PUBLIC_COLLAB_SERVER_URL} - NEXT_PUBLIC_UMAMI_SCRIPT=${NEXT_PUBLIC_UMAMI_SCRIPT} - NEXT_PUBLIC_UMAMI_WEBSITE_ID=${NEXT_PUBLIC_UMAMI_WEBSITE_ID} - NEXT_PUBLIC_LIBREDESK_URL=${NEXT_PUBLIC_LIBREDESK_URL} - NEXT_PUBLIC_LIBREDESK_WIDGET_ID=${NEXT_PUBLIC_LIBREDESK_WIDGET_ID} - NEXT_PUBLIC_DIRECTUS_URL=${NEXT_PUBLIC_DIRECTUS_URL} - DIRECTUS_FEEDBACK_TOKEN=${DIRECTUS_FEEDBACK_TOKEN} - OPENAI_API_KEY=${OPENAI_API_KEY} - OPENAI_BASE_URL=${OPENAI_BASE_URL} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - NODE_ENV=production - NEXT_TELEMETRY_DISABLED=1 expose: - "3000" healthcheck: test: - CMD-SHELL - "wget -qO- --timeout=3 http://127.0.0.1:3000/ >/dev/null || exit 1" interval: 30s timeout: 5s retries: 3 start_period: 90s networks: - echodo collab: build: context: . dockerfile: docker/Dockerfile target: collab restart: unless-stopped environment: # Separate FQDN for the websocket service, e.g. collab.echodo.stillwell.cloud - SERVICE_FQDN_COLLAB_1234 - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - PORT=1234 - NODE_ENV=production expose: - "1234" healthcheck: test: - CMD-SHELL - 'node -e "const p=+(process.env.PORT||1234);require(''net'').createConnection(p,''127.0.0.1'').on(''connect'',()=>process.exit(0)).on(''error'',()=>process.exit(1))"' interval: 30s timeout: 5s retries: 3 start_period: 25s networks: - echodo # MCP server is stdio-based today; deploy only if you want it reachable on the LAN # for future HTTP/SSE transport. Comment the whole block out if not needed. mcp: build: context: . dockerfile: docker/Dockerfile target: mcp args: MCP_SERVER_PORT: ${MCP_SERVER_PORT:-3001} restart: unless-stopped environment: - DATABASE_URL=${DATABASE_URL} - MCP_SERVER_PORT=${MCP_SERVER_PORT:-3001} - NODE_ENV=production stdin_open: true expose: - "${MCP_SERVER_PORT:-3001}" healthcheck: test: - CMD-SHELL - "pgrep -f 'node.*dist/index\\.js' > /dev/null || exit 1" interval: 30s timeout: 5s retries: 3 start_period: 25s networks: - echodo networks: echodo: driver: bridge