Repository navigation
Expand file tree
/
Copy pathdocker-compose.prod.yml
More file actions
99 lines (90 loc) · 4.41 KB
/
Copy pathdocker-compose.prod.yml
File metadata and controls
99 lines (90 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Configuración "pública" de QueueLab (#59): se APLICA ENCIMA de docker-compose.yml.
#
# docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.production up -d --wait
#
# Qué cambia respecto al Compose de desarrollo (ver docs/deployment/secrets-tls-access.md):
# - Las contraseñas NO tienen valor por defecto: si falta una, Compose se niega a arrancar.
# - PostgreSQL, RabbitMQ, Redis, la API y el dashboard dejan de publicar puertos en el host.
# - Un único punto de entrada, Caddy, termina HTTPS y exige usuario y contraseña (Basic) antes de llegar a nada.
# - Dashboard y API se sirven bajo el MISMO origen (https://<dominio>/ y https://<dominio>/api/v1/...).
# - Cada servicio con estado o con JVM tiene un límite de memoria (`mem_limit`), medido bajo carga: ver
# docs/deployment/deploy-compose.md. Las JVM usan el 75 % del límite como heap (ver docs/containers-backend.md).
# Los puertos de Prometheus y Grafana (perfil `observability`) siguen en 127.0.0.1 y no pasan por Caddy.
services:
postgres:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?defina POSTGRES_PASSWORD en .env.production}
ports: !reset []
mem_limit: 512m
rabbitmq:
environment:
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:?defina RABBITMQ_PASSWORD en .env.production}
ports: !reset []
mem_limit: 512m
volumes:
# Umbral de memoria absoluto por debajo del límite del contenedor (ver el fichero).
- ./deploy/rabbitmq.conf:/etc/rabbitmq/conf.d/20-queuelab.conf:ro
redis:
ports: !reset []
mem_limit: 64m
api:
environment:
QUEUELAB_DB_PASSWORD: ${POSTGRES_PASSWORD:?defina POSTGRES_PASSWORD en .env.production}
QUEUELAB_RABBITMQ_PASSWORD: ${RABBITMQ_PASSWORD:?defina RABBITMQ_PASSWORD en .env.production}
# Mismo origen que el dashboard: el navegador no hace peticiones entre orígenes y CORS no se usa.
QUEUELAB_CORS_ALLOWED_ORIGINS: ${QUEUELAB_PUBLIC_URL:?defina QUEUELAB_PUBLIC_URL en .env.production}
ports: !reset []
mem_limit: 512m
worker:
environment:
QUEUELAB_DB_PASSWORD: ${POSTGRES_PASSWORD:?defina POSTGRES_PASSWORD en .env.production}
QUEUELAB_RABBITMQ_PASSWORD: ${RABBITMQ_PASSWORD:?defina RABBITMQ_PASSWORD en .env.production}
mem_limit: 512m
dashboard:
environment:
# URL de la API tal como la ve el navegador: el mismo origen público (Caddy reparte /api/ hacia la API).
QUEUELAB_API_URL: ${QUEUELAB_PUBLIC_URL:?defina QUEUELAB_PUBLIC_URL en .env.production}
ports: !reset []
mem_limit: 256m
# Perfil `observability`: Prometheus recoge las métricas por el nombre de los servicios (la API y el worker ya no
# publican puertos en el host, así que la configuración «del host» no los alcanzaría).
prometheus:
volumes:
- ${PROMETHEUS_CONFIG:-./observability/prometheus/prometheus.compose.yml}:/etc/prometheus/prometheus.yml:ro
grafana:
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:?defina GRAFANA_PASSWORD en .env.production}
# El acceso anónimo de lectura es solo para el modo local: aquí se exige iniciar sesión.
GF_AUTH_ANONYMOUS_ENABLED: "false"
# Único servicio con puertos en el host. Por defecto escucha SOLO en 127.0.0.1; poner QUEUELAB_BIND=0.0.0.0 es la
# decisión consciente de abrirlo a la red (ver la política de acceso en el documento).
caddy:
image: caddy:2-alpine
environment:
QUEUELAB_DOMAIN: ${QUEUELAB_DOMAIN:-localhost}
QUEUELAB_BASIC_AUTH_USER: ${QUEUELAB_BASIC_AUTH_USER:?defina QUEUELAB_BASIC_AUTH_USER en .env.production}
QUEUELAB_BASIC_AUTH_HASH: ${QUEUELAB_BASIC_AUTH_HASH:?defina QUEUELAB_BASIC_AUTH_HASH (hash bcrypt) en .env.production}
ports:
- "${QUEUELAB_BIND:-127.0.0.1}:${QUEUELAB_HTTPS_PORT:-443}:443"
- "${QUEUELAB_BIND:-127.0.0.1}:${QUEUELAB_HTTP_PORT:-80}:80"
volumes:
- ./deploy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
depends_on:
api:
condition: service_healthy
dashboard:
condition: service_healthy
mem_limit: 64m
# La API de administración de Caddy solo escucha dentro del contenedor (127.0.0.1:2019): no se publica.
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
interval: 10s
timeout: 3s
retries: 6
start_period: 5s
restart: unless-stopped
volumes:
caddy-data:
caddy-config: