126 lines
3.4 KiB
YAML
126 lines
3.4 KiB
YAML
services:
|
|
# ==========================================================
|
|
# Caddy — Reverse Proxy with Automatic HTTPS
|
|
# Provisions Let's Encrypt TLS certificates automatically.
|
|
# ==========================================================
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
container_name: taskapp-caddy
|
|
restart: always
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- caddy_data:/data
|
|
- caddy_config:/config
|
|
- access_logs:/data
|
|
environment:
|
|
- DOMAIN_NAME=${DOMAIN_NAME:-localhost}
|
|
depends_on:
|
|
- frontend
|
|
networks:
|
|
- frontend-net
|
|
|
|
# ==========================================================
|
|
# Frontend — Nginx serving static files + reverse proxy to API
|
|
# ==========================================================
|
|
frontend:
|
|
build: ./frontend
|
|
container_name: taskapp-frontend
|
|
restart: always
|
|
expose:
|
|
- "80"
|
|
depends_on:
|
|
- api
|
|
networks:
|
|
- frontend-net
|
|
|
|
# ==========================================================
|
|
# API — Node.js Express REST Backend
|
|
# ==========================================================
|
|
api:
|
|
build: ./api
|
|
container_name: taskapp-api
|
|
restart: always
|
|
expose:
|
|
- "3000"
|
|
environment:
|
|
- PORT=3000
|
|
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
|
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
|
|
- POSTGRES_DB=${POSTGRES_DB:-taskmanager}
|
|
- POSTGRES_USER=${POSTGRES_USER:-taskuser}
|
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-taskpass}
|
|
- REDIS_HOST=${REDIS_HOST:-redis}
|
|
- REDIS_PORT=${REDIS_PORT:-6379}
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
networks:
|
|
- frontend-net
|
|
- backend-net
|
|
|
|
# ==========================================================
|
|
# PostgreSQL — Primary persistent database
|
|
# ==========================================================
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: taskapp-postgres
|
|
restart: always
|
|
environment:
|
|
- POSTGRES_DB=${POSTGRES_DB:-taskmanager}
|
|
- POSTGRES_USER=${POSTGRES_USER:-taskuser}
|
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-taskpass}
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-taskuser} -d ${POSTGRES_DB:-taskmanager}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
networks:
|
|
- backend-net
|
|
|
|
# ==========================================================
|
|
# Redis — In-memory cache for fast API responses
|
|
# ==========================================================
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: taskapp-redis
|
|
restart: always
|
|
command: redis-server --appendonly yes
|
|
volumes:
|
|
- redisdata:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- backend-net
|
|
|
|
# Named volumes for data persistence
|
|
volumes:
|
|
pgdata:
|
|
name: taskapp-pgdata
|
|
redisdata:
|
|
name: taskapp-redisdata
|
|
caddy_data:
|
|
name: taskapp-caddy-data
|
|
caddy_config:
|
|
name: taskapp-caddy-config
|
|
access_logs:
|
|
name: taskapp-access-logs
|
|
|
|
# Virtual networks for service isolation
|
|
networks:
|
|
frontend-net:
|
|
name: taskapp-frontend-net
|
|
backend-net:
|
|
name: taskapp-backend-net
|