version: '3.8' services: # ── Frontend (nginx serving built Vue app) ─────────────────── app: build: context: . dockerfile: Dockerfile restart: unless-stopped ports: - "7777:7777" depends_on: - relay - api networks: - indeedhub-network labels: - "com.centurylinklabs.watchtower.enable=true" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:7777/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # ── Backend API (NestJS) ───────────────────────────────────── api: build: context: ./backend dockerfile: Dockerfile restart: unless-stopped env_file: - ./backend/.env depends_on: postgres: condition: service_healthy redis: condition: service_started minio: condition: service_started networks: - indeedhub-network healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/nostr-auth/health"] interval: 30s timeout: 10s retries: 5 start_period: 60s # ── PostgreSQL Database ────────────────────────────────────── postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: indeedhub POSTGRES_PASSWORD: indeedhub_dev_2026 POSTGRES_DB: indeedhub volumes: - postgres-data:/var/lib/postgresql/data networks: - indeedhub-network healthcheck: test: ["CMD-SHELL", "pg_isready -U indeedhub"] interval: 10s timeout: 5s retries: 5 start_period: 30s # ── Redis (BullMQ job queue) ───────────────────────────────── redis: image: redis:7-alpine restart: unless-stopped volumes: - redis-data:/data networks: - indeedhub-network # ── MinIO (S3-compatible object storage) ───────────────────── minio: image: minio/minio:latest restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin123 volumes: - minio-data:/data ports: - "9001:9001" networks: - indeedhub-network # ── MinIO bucket init (one-shot: creates required buckets) ─── minio-init: image: minio/mc:latest depends_on: - minio entrypoint: > /bin/sh -c " sleep 5; mc alias set local http://minio:9000 minioadmin minioadmin123; mc mb local/indeedhub-private --ignore-existing; mc mb local/indeedhub-public --ignore-existing; mc anonymous set download local/indeedhub-public; echo 'MinIO buckets initialized'; " networks: - indeedhub-network restart: "no" # ── FFmpeg Transcoding Worker ──────────────────────────────── ffmpeg-worker: build: context: ./backend dockerfile: Dockerfile.ffmpeg restart: unless-stopped env_file: - ./backend/.env depends_on: postgres: condition: service_healthy redis: condition: service_started minio: condition: service_started networks: - indeedhub-network # ── Mailpit (development email testing) ────────────────────── mailpit: image: axllent/mailpit:latest restart: unless-stopped ports: - "8025:8025" networks: - indeedhub-network # ── Nostr Relay (stores comments, reactions, profiles) ─────── relay: image: scsibug/nostr-rs-relay:latest restart: unless-stopped volumes: - relay-data:/usr/src/app/db networks: - indeedhub-network # ── Seeder (one-shot: seeds test data into relay, then exits) seeder: build: context: . dockerfile: Dockerfile.seed depends_on: - relay environment: - RELAY_URL=ws://relay:8080 - ORIGIN=http://localhost:7777 networks: - indeedhub-network restart: "no" # ── DB Seeder (one-shot: seeds content into PostgreSQL) ────── db-seeder: build: context: ./backend dockerfile: Dockerfile depends_on: postgres: condition: service_healthy minio: condition: service_started env_file: - ./backend/.env command: ["node", "dist/scripts/seed-content.js"] networks: - indeedhub-network restart: "no" networks: indeedhub-network: driver: bridge volumes: postgres-data: redis-data: minio-data: relay-data: