-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.application.yml
More file actions
199 lines (184 loc) · 8.18 KB
/
Copy pathdocker-compose.application.yml
File metadata and controls
199 lines (184 loc) · 8.18 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
x-logging: &default-logging
driver: "local"
options:
max-size: "${LOG_MAX_SIZE:-150m}"
max-file: "${LOG_MAX_FILE:-5}"
services:
# Ofelia to taki cron...
ofelia:
image: mcuadros/ofelia:0.3.21
restart: always
logging: *default-logging
env_file: ${BPP_CONFIGS_DIR}/.env
depends_on:
- appserver
command: daemon --docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
resources:
limits:
memory: ${OFELIA_MEM_LIMIT:-64m}
cpus: "${OFELIA_CPU_LIMIT:-0.25}"
labels:
ofelia.email-to: "${DJANGO_BPP_ADMIN_EMAIL}"
# Bez referencji do DJANGO_BPP_HOSTNAME, zeby compose nie wypisywal
# "variable not set" w trybie multi-host (gdzie tylko HOSTNAMES jest
# ustawione). I tak emaile nie sa wysylane - to tylko adres From.
ofelia.email-from: "Ofelia <${DJANGO_BPP_ADMIN_EMAIL}>"
ofelia.slack-webhook: "${DJANGO_BPP_SLACK_WEBHOOK}"
autoheal:
# Restartuje kontenery z labelka `autoheal=true` gdy ich healthcheck zglasza
# status `unhealthy`. Standardowo Docker NIE restartuje na podstawie failed
# healthcheck (`restart: always` reaguje tylko na exit) - autoheal wypelnia te luke.
# Krytyczne dla workerow Celery, ktore moga utknac w reconnect loop po
# zerwanym connection do brokera (proces zyje, healthcheck `celery inspect
# ping` falluje - bez autohealu czeka na rece administratora).
image: willfarrell/autoheal:1.2.0
restart: always
logging: *default-logging
environment:
AUTOHEAL_CONTAINER_LABEL: autoheal
AUTOHEAL_INTERVAL: "10" # check co 10s (default 5)
AUTOHEAL_DEFAULT_STOP_TIMEOUT: "30"
volumes:
# docker.sock musi byc rw - autoheal wywoluje docker restart przez API.
# Ofelia obok ma ro (tylko `docker exec`); to jest swiadomy tradeoff
# (wieksze permission, ale jedyna droga do reactive restartu).
- /var/run/docker.sock:/var/run/docker.sock
deploy:
resources:
limits:
memory: ${AUTOHEAL_MEM_LIMIT:-32m}
cpus: "${AUTOHEAL_CPU_LIMIT:-0.1}"
authserver:
# Lightweight auth server for nginx authentication
# Starts quickly (seconds) - no migrations, no collectstatic
# Used by nginx auth_request for Grafana, Dozzle, etc.
image: iplweb/bpp_authserver:${DOCKER_VERSION:-latest}
restart: always
logging: *default-logging
environment:
- DJANGO_SETTINGS_MODULE=django_bpp.settings.auth_server
env_file: ${BPP_CONFIGS_DIR}/.env
depends_on:
dbserver:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:8001/health/"]
interval: 30s
timeout: 3s
start_period: 10s
retries: 3
deploy:
resources:
limits:
memory: ${AUTHSERVER_MEM_LIMIT:-320m}
cpus: "${AUTHSERVER_CPU_LIMIT:-1.0}"
appserver:
image: iplweb/bpp_appserver:${DOCKER_VERSION:-latest}
restart: always
logging: *default-logging
env_file: ${BPP_CONFIGS_DIR}/.env
environment:
DJANGO_BPP_ENABLE_PROMETHEUS: ${DJANGO_BPP_ENABLE_PROMETHEUS:-false}
volumes:
- staticfiles:/staticroot
- media:/mediaroot
depends_on:
redis:
condition: service_healthy
dbserver:
condition: service_healthy
healthcheck:
# interval: 10s zeby workery (depends_on appserver: service_healthy)
# ruszyly szybciej po faktycznym ready gunicorna. start_period 1800s
# zostaje - to grace dla Phase 1 (migracje).
test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health/"]
interval: 10s
timeout: 5s
start_period: 1800s
retries: 3
deploy:
resources:
limits:
memory: ${APPSERVER_MEM_LIMIT:-2g}
cpus: "${APPSERVER_CPU_LIMIT:-2.0}"
labels:
ofelia.enabled: "true"
ofelia.job-exec.denorm_rebuild.schedule: "0 0 22 * * *"
ofelia.job-exec.denorm_rebuild.command: "python src/manage.py denorm_rebuild --no-flush"
ofelia.job-exec.refresh_sitemap.schedule: "0 30 1 * * *"
ofelia.job-exec.refresh_sitemap.command: "python src/manage.py refresh_sitemap -v0"
ofelia.job-exec.rebuild_kolejnosc.schedule: "0 30 3 * * *"
ofelia.job-exec.rebuild_kolejnosc.command: "python src/manage.py rebuild_kolejnosc"
ofelia.job-exec.rebuild_autor_jednostka.schedule: "0 30 4 * * *"
ofelia.job-exec.rebuild_autor_jednostka.command: "python src/manage.py rebuild_autor_jednostka"
ofelia.job-exec.pbn_integrator.schedule: "0 30 21 * * 6"
ofelia.job-exec.pbn_integrator.command: "python src/manage.py tee pbn_integrator --enable-all --disable-multiprocessing"
# Nocny restart zbija skumulowany memory leak gunicorna (appserver potrafi puchnac
# do kilkunastu GiB po kilku dniach uptime). kill 1 -> SIGTERM do PID 1 ->
# graceful shutdown gunicorna -> Docker restart:always wskrzesza kontener.
# Staggered wzgledem workerow (workerserver 05:05, flower 05:15,
# celerybeat 05:20, denorm-queue 05:25) zeby nie zrestartowac calego
# stacka naraz. Slot 05:00 (appserver) jest wolny od innych jobow - po
# backup (02:30), rebuild_kolejnosc (03:30), rebuild_autor_jednostka
# (04:30), przed godzinami pracy.
ofelia.job-exec.restart_self.schedule: "0 0 5 * * *"
ofelia.job-exec.restart_self.command: "kill 1"
# === Let's Encrypt: codzienny renew ===
# job-run spawnuje swiezy kontener certbot/certbot, robi certbot renew
# (idempotentny - pomija certy z >30 dni do wygaśniecia, exit 0 gdy nic
# do zrobienia, take same exit gdy katalog letsencrypt jest pusty).
# Po sukcesie deploy-hook tworzy sentinel /etc/letsencrypt/.reload-needed,
# ktory webserver podnosi 5 minut pozniej (label ofelia.job-exec na
# webserverze w docker-compose.infrastructure.yml) i robi nginx -s reload.
#
# Codziennie zamiast co 60 dni: certbot renew nie kontaktuje sie z LE
# gdy nie trzeba, wiec koszt to ~5s spawn kontenera. Plus: jezeli renew
# sie wysypie, mamy 30 dni okna na alarm zamiast 1.
#
# SSL_MODE=manual: katalog letsencrypt/ pusty, certbot renew exit 0 bez
# akcji - bezpieczny no-op.
ofelia.job-run.letsencrypt_renew.schedule: "0 0 4 * * *"
ofelia.job-run.letsencrypt_renew.image: "certbot/certbot:v3.3.0"
ofelia.job-run.letsencrypt_renew.volume: "${COMPOSE_PROJECT_NAME}_acme-challenge:/var/www/certbot,${BPP_CONFIGS_DIR}/letsencrypt:/etc/letsencrypt"
ofelia.job-run.letsencrypt_renew.command: "renew --webroot -w /var/www/certbot --quiet --deploy-hook \"touch /etc/letsencrypt/.reload-needed\""
# === html2docx ===
# OPCJONALNY sidecar konwersji HTML->DOCX (fallback gdy pandoc padnie, np.
# core dump na VMWare ESX). Domyslnie WYLACZONY - startuje tylko gdy profil
# `html2docx` jest w COMPOSE_PROFILES (repo-lokalny .env). Deployment, ktory
# go wlacza, musi tez ustawic DJANGO_BPP_HTML2DOCX_URL w ${BPP_CONFIGS_DIR}/.env
# (patrz .env.sample) - inaczej appserver/worker maja fallback wylaczony
# (miekka degradacja, bez crasha).
#
# Bez published portu (tylko siec wewnetrzna projektu, osiagalny jako
# `html2docx:3030`). Bez healthchecka: obraz .NET nie ma curl/wget,
# restart:always wystarcza. Bez docker.sock - to byla cala pointa zmiany.
# Obraz wersjonowany niezaleznie od DOCKER_VERSION bpp (pin przez
# HTML2DOCX_VERSION w .env).
html2docx:
image: iplweb/html2docx:${HTML2DOCX_VERSION:-latest}
profiles: ['html2docx']
restart: always
logging: *default-logging
# === Certbot ===
# Sidecar uruchamiany na zadanie ('docker compose run --rm certbot ...')
# przez make ssl-letsencrypt-issue / make ssl-letsencrypt-renew. NIE startuje
# z 'make up' (profile letsencrypt = nie aktywny domyslnie).
#
# Codzienny renew odbywa sie przez Ofelia job-run (label na appserver wyzej),
# ktora spawnuje swoj wlasny kontener z tego samego image i wolumenow.
certbot:
image: certbot/certbot:v3.3.0
profiles: ['letsencrypt']
logging: *default-logging
env_file: ${BPP_CONFIGS_DIR}/.env
volumes:
- acme-challenge:/var/www/certbot
- ${BPP_CONFIGS_DIR}/letsencrypt:/etc/letsencrypt
volumes:
staticfiles:
media: