services: # ============================================= # PostgreSQL Database # Primary persistent data store for tasks # ============================================= postgres: image: postgres:16-alpine container_name: taskapp-postgres restart: unless-stopped environment: POSTGRES_DB: taskmanager POSTGRES_USER: taskuser POSTGRES_PASSWORD: taskpass volumes: - taskapp-pgdata:/var/lib/postgresql/data - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro networks: - backend-net healthcheck: test: ["CMD-SHELL", "pg_isready -U taskuser -d taskmanager"] interval: 10s timeout: 5s retries: 5 start_period: 10s # ============================================= # Redis Cache # Caching layer for API responses # ============================================= redis: image: redis:7-alpine container_name: taskapp-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - taskapp-redisdata:/data networks: - backend-net healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 5s # ============================================= # Node.js API Server # REST API for task CRUD operations # ============================================= api: build: context: ./api dockerfile: Dockerfile container_name: taskapp-api restart: unless-stopped environment: PORT: 3000 POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_DB: taskmanager POSTGRES_USER: taskuser POSTGRES_PASSWORD: taskpass REDIS_HOST: redis REDIS_PORT: 6379 depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - backend-net # ============================================= # Nginx Frontend # Serves static files + reverse proxies to API # ============================================= frontend: build: context: ./frontend dockerfile: Dockerfile container_name: taskapp-frontend restart: unless-stopped ports: - "5000:80" depends_on: - api networks: - frontend-net - backend-net # ============================================= # Adminer # Web-based database management interface # ============================================= adminer: image: adminer:latest container_name: taskapp-adminer restart: unless-stopped ports: - "5001:8080" environment: ADMINER_DEFAULT_SERVER: postgres ADMINER_DESIGN: dracula depends_on: postgres: condition: service_healthy networks: - frontend-net - backend-net # ============================================= # Named Volumes (persistent storage) # ============================================= volumes: taskapp-pgdata: name: taskapp-pgdata taskapp-redisdata: name: taskapp-redisdata # ============================================= # Virtual Networks # ============================================= networks: frontend-net: name: taskapp-frontend-net driver: bridge backend-net: name: taskapp-backend-net driver: bridge