# Run from repository root (set variables via shell or --env-file .env): # docker compose -f docker/docker-compose.yml --env-file .env up -d # # Build images: # docker compose -f docker/docker-compose.yml build # # For a smaller build context, copy docker/.dockerignore to the repository root as .dockerignore. services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} POSTGRES_DB: ${POSTGRES_DB:-tasks} volumes: - postgres_data:/var/lib/postgresql/data ports: - "${POSTGRES_PORT:-5432}:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""] interval: 5s timeout: 5s retries: 10 start_period: 10s networks: - tasks redis: image: redis:7-alpine restart: unless-stopped command: ["redis-server", "--appendonly", "yes"] volumes: - redis_data:/data ports: - "${REDIS_PORT:-6379}:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 10 start_period: 5s networks: - tasks web: build: context: .. dockerfile: docker/Dockerfile target: web restart: unless-stopped environment: DATABASE_URL: ${DATABASE_URL} REDIS_URL: ${REDIS_URL} NEXTAUTH_URL: ${NEXTAUTH_URL} NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} COLLAB_SERVER_URL: ${COLLAB_SERVER_URL} NODE_ENV: production ports: - "${WEB_PORT:-3000}:3000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy 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: - tasks collab: build: context: .. dockerfile: docker/Dockerfile target: collab restart: unless-stopped environment: DATABASE_URL: ${DATABASE_URL} REDIS_URL: ${REDIS_URL} PORT: ${COLLAB_PORT:-1234} NODE_ENV: production ports: - "${COLLAB_PORT:-1234}:${COLLAB_PORT:-1234}" depends_on: postgres: condition: service_healthy redis: condition: service_healthy 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: - tasks # MCP image runs the current stdio-based server; the published port is reserved for a future HTTP/SSE transport. 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 ports: - "${MCP_SERVER_PORT:-3001}:${MCP_SERVER_PORT:-3001}" stdin_open: true depends_on: postgres: condition: service_healthy healthcheck: test: [ "CMD-SHELL", "pgrep -f 'node.*dist/index\\.js' > /dev/null || exit 1", ] interval: 30s timeout: 5s retries: 3 start_period: 25s networks: - tasks volumes: postgres_data: redis_data: networks: tasks: driver: bridge