101 lines
2.4 KiB
YAML
101 lines
2.4 KiB
YAML
|
|
# Production environment configuration
|
||
|
|
# Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||
|
|
|
||
|
|
services:
|
||
|
|
nginx:
|
||
|
|
ports:
|
||
|
|
- "80:80"
|
||
|
|
- "443:443"
|
||
|
|
volumes:
|
||
|
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||
|
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||
|
|
- ./ssl:/etc/nginx/ssl:ro # SSL certificates
|
||
|
|
restart: always
|
||
|
|
logging:
|
||
|
|
driver: "json-file"
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
|
||
|
|
frontend:
|
||
|
|
build:
|
||
|
|
context: ./frontend
|
||
|
|
dockerfile: Dockerfile.prod
|
||
|
|
args:
|
||
|
|
- NODE_ENV=production
|
||
|
|
environment:
|
||
|
|
- NODE_ENV=production
|
||
|
|
volumes: [] # No volumes in production (baked into image)
|
||
|
|
command: ["nginx", "-g", "daemon off;"]
|
||
|
|
restart: always
|
||
|
|
logging:
|
||
|
|
driver: "json-file"
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
|
||
|
|
backend:
|
||
|
|
build:
|
||
|
|
context: ./backend
|
||
|
|
dockerfile: Dockerfile.prod
|
||
|
|
args:
|
||
|
|
- NODE_ENV=production
|
||
|
|
environment:
|
||
|
|
- NODE_ENV=production
|
||
|
|
# Security: Strict for production
|
||
|
|
- RATE_LIMIT_ENABLED=true
|
||
|
|
- RATE_LIMIT_AUTH_MAX=5
|
||
|
|
- RATE_LIMIT_EMAIL_MAX=3
|
||
|
|
- ENABLE_CSRF=true
|
||
|
|
- BODY_SIZE_LIMIT=10kb
|
||
|
|
- LOG_LEVEL=warn
|
||
|
|
# Secrets should come from environment or secrets manager
|
||
|
|
# Do not hardcode in docker-compose.prod.yml
|
||
|
|
volumes: [] # No volumes in production
|
||
|
|
command: ["node", "src/server.js"]
|
||
|
|
restart: always
|
||
|
|
logging:
|
||
|
|
driver: "json-file"
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
deploy:
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpus: '1'
|
||
|
|
memory: 512M
|
||
|
|
reservations:
|
||
|
|
cpus: '0.5'
|
||
|
|
memory: 256M
|
||
|
|
|
||
|
|
db:
|
||
|
|
# In production, consider using managed database (AWS RDS, etc.)
|
||
|
|
# This is for self-hosted production
|
||
|
|
environment:
|
||
|
|
- POSTGRES_USER=${POSTGRES_USER}
|
||
|
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||
|
|
- POSTGRES_DB=${POSTGRES_DB}
|
||
|
|
volumes:
|
||
|
|
- postgres_data:/var/lib/postgresql/data
|
||
|
|
- ./backups:/backups # For database backups
|
||
|
|
# Don't expose port in production (only internal)
|
||
|
|
# ports: []
|
||
|
|
restart: always
|
||
|
|
logging:
|
||
|
|
driver: "json-file"
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
deploy:
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpus: '2'
|
||
|
|
memory: 2G
|
||
|
|
reservations:
|
||
|
|
cpus: '1'
|
||
|
|
memory: 1G
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
postgres_data:
|
||
|
|
driver: local
|