Architektura konfiguracji¶
Modularny Docker Compose (dyrektywa include)¶
Wymaga Compose v2.20+. Główna orkiestracja jest rozbita na pliki tematyczne:
docker-compose.yml # Główna orkiestracja
├── docker-compose.monitoring.yml # Netdata, Loki, Grafana, Alloy, Dozzle
├── docker-compose.database.yml # PostgreSQL + wolumen postgresql_data
├── docker-compose.infrastructure.yml # Nginx, Redis
├── docker-compose.application.yml # appserver, authserver, ofelia, autoheal + wolumeny staticfiles/media
├── docker-compose.workers.yml # Celery (general, denorm, beat, flower, denorm-queue)
└── docker-compose.backup.yml # backup-runner
Wolumeny są definiowane w pliku, który jest ich właścicielem, ale referowane między
plikami (np. staticfiles/media zdefiniowane w application.yml, używane przez workery).
Każdy wpis include: ma env_file: ${BPP_CONFIGS_DIR}/.env, żeby interpolacja ${VAR}
działała w dołączanym YAML-u. BPP_CONFIGS_DIR jest odczytywany z repo-lokalnego .env
automatycznie przez Compose — docker compose up działa bezpośrednio, bez make.
Katalog konfiguracyjny (BPP_CONFIGS_DIR)¶
Konfiguracja żyje poza repozytorium (np. ~/publikacje-uczelnia/). Tworzony przy
pierwszym make przez init-configs. Zawartość: .env, ssl/, rclone/, alloy/,
loki/, netdata/{go.d,health.d}/, grafana/provisioning/{datasources,dashboards}/.
Bind-mountowany bezpośrednio do kontenerów.
Katalog defaults/ repozytorium trzyma szablonowe configi kopiowane przez init-configs
bez nadpisywania istniejących (copy_if_missing) — więc dostrojone przez użytkownika
configi (loki/, netdata/health.d/, netdata/go.d/, alloy/) przeżywają aktualizacje.
Pliki force-syncowane (nadpisywane przy każdym deploy)¶
Wyjątek od copy_if_missing
Trzy artefakty są nadpisywane z defaults/ przy każdym ensure-config-files
(czyli każdym make up / refresh / run) przez copy_always (tylko gdy treść
się różni):
grafana/provisioning/dashboards/*grafana/provisioning/datasources/datasources.yaml.tplnetdata/netdata.conf
To dlatego, że są to wersjonowane, „read-only-w-UI" artefakty: zaktualizowany dashboard
albo datasource w repo ma trafić na żywe wdrożenie automatycznie z git pull && make up,
bez ręcznego cp.
netdata.conf — renderowany host-side¶
netdata.conf jest renderowany z defaults/netdata/netdata.conf.tpl (tak jak
go.d/postgres.conf.tpl) — bo netdata.conf nie umie interpolować ${VAR}, a hostname
wdrożenia musi trafić do [registry] registry to announce = https://<host>/netdata.
Ten URL steruje przyciskiem „View node" w powiadomieniach ntfy — bez nadpisywania
istniejąca instalacja trzymałaby stary config i przycisk wskazywałby registry.my-netdata.io.
Pokrętła dla użytkownika (retencja dbengine) są parametryzowane przez .env
(NETDATA_DBENGINE_TIER0_RETENTION_MB, NETDATA_DBENGINE_PAGE_CACHE_MB), żeby
force-overwrite nie kasował ręcznego strojenia. Nie edytuj netdata.conf ręcznie —
strój przez .env.
datasources.yaml.tpl — dlaczego force-sync¶
Z copy_if_missing zaktualizowana instalacja trzymałaby stary .tpl, więc zmiana typu
„Grafana łączy się przez read-only rolę bpp_monitor zamiast superusera aplikacji"
nigdy nie dotarłaby do istniejących wdrożeń. Renderowany datasources.yaml (ze skryptu
scripts/generate-grafana-datasources.sh, który czyta .env z dysku — nie
parse-time export make'a, więc świeżo wygenerowane DJANGO_BPP_PG_MONITOR_PASSWORD nie
jest renderowane jako puste przy pierwszym make up) jest plikiem żywym; .tpl to jego
źródło.
Dashboardy usunięte z defaults/ są zostawiane na miejscu (nie kasowane); dashboardy
tworzone w UI Grafany żyją w jej bazie i nie są ruszane.
Staticfiles — kontrakt z obrazem appservera¶
Wolumen staticfiles jest wypełniany przez appserver (mount /staticroot) i serwowany
przez webserver/nginx (mount /var/www/html/staticroot). Źródłem jest
/app/staticroot.baked/ wbudowane w obraz appservera na etapie build (gdy dostępne jest
node_modules — runtime już go nie ma).
- Entrypoint appservera w Fazie 2 robi
cp -ru /app/staticroot.baked/. "$STATIC_ROOT/". cp -ruzasiewa pusty wolumen i dokłada nowsze pliki przy upgrade obrazu, bez kasowania istniejącej treści.- Runtime nie odpala
collectstatic— katalog.bakedto ten sam output. Fallback odpalacollectstatictylko dla obrazów sprzed.baked.
STATIC_ROOT=/staticroot/ w .env nadpisuje domyślne /app/staticroot z obrazu.
Po make refresh lub make prune-orphan-volumes wolumen jest ponownie wypełniany z .baked.
Pierwsze uruchomienie — dwa przebiegi make¶
make # Pierwszy raz: pyta o katalog konfiguracyjny, hostname, admina,
# webhook, katalog backupów, wersję PostgreSQL. Generuje losowe hasła.
make # Drugi raz: startuje usługi normalnie.
Patrz Pierwsze uruchomienie.