# TaskStream: web + API + infrastructure — production definition (Dokploy deploys this file). # No ports are published here: services only talk over the compose network, and the web is # exposed through the platform's proxy (Dokploy domain → service `web`, port 80). # # Locally, `docker compose` also loads docker-compose.override.yml, which publishes the ports: # docker compose up -d --build → everything: web on http://localhost:8080 # docker compose up -d postgres mongo redis → only infrastructure (then `npx nx serve api` / `npx nx serve web`) # # Building needs access to Pireon's Nexus (@pi/ui): set NEXUS_TOKEN in the environment or in .env # (Dokploy: Environment tab). It reaches the build as a secret and never lands in an image layer. services: web: build: context: . target: web secrets: [nexus_token] image: task-stream-web expose: ['80'] depends_on: api: { condition: service_healthy } restart: unless-stopped api: build: context: . target: api secrets: [nexus_token] image: task-stream-api expose: ['3000'] environment: POSTGRES_URL: postgres://taskstream:taskstream@postgres:5432/taskstream # No migrations yet: TypeORM creates the event store and lookup tables. POSTGRES_SYNCHRONIZE: 'true' MONGO_URL: mongodb://mongo:27017/taskstream_read REDIS_URL: redis://redis:6379 EVENT_STREAM_KEY: task-stream:events EVENTS_BRIDGE_ENABLED: 'true' PIREON_BASE_URL: https://oauth.pireon.dev PIREON_WEBHOOK_SECRET: ${PIREON_WEBHOOK_SECRET:-} PIREON_CLIENT_ID: ${PIREON_CLIENT_ID:-} PIREON_CLIENT_SECRET: ${PIREON_CLIENT_SECRET:-} GRAPHQL_PLAYGROUND: 'true' # The SDL file is only useful in development (codegen). GRAPHQL_SCHEMA_FILE: '' depends_on: postgres: { condition: service_healthy } mongo: { condition: service_healthy } redis: { condition: service_healthy } restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_USER: taskstream POSTGRES_PASSWORD: taskstream POSTGRES_DB: taskstream volumes: [postgres-data:/var/lib/postgresql/data] healthcheck: test: ['CMD-SHELL', 'pg_isready -U taskstream'] interval: 5s retries: 10 mongo: image: mongo:8 volumes: [mongo-data:/data/db] healthcheck: test: ['CMD', 'mongosh', '--quiet', '--eval', 'db.adminCommand("ping")'] interval: 5s retries: 10 redis: image: redis:7-alpine command: ['redis-server', '--appendonly', 'yes'] volumes: [redis-data:/data] healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 5s retries: 10 volumes: postgres-data: mongo-data: redis-data: secrets: nexus_token: environment: NEXUS_TOKEN