Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker-compose.monitoring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ services:
deploy:
resources:
limits:
memory: ${NETDATA_MEM_LIMIT:-320m}
memory: ${NETDATA_MEM_LIMIT:-768m}
cpus: "${NETDATA_CPU_LIMIT:-1.0}"

volumes:
Expand Down
18 changes: 11 additions & 7 deletions docs/konfiguracja/limity-zasobow.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ docierają do każdej instalacji przez `${VAR:-default}` w plikach compose, wię
out-of-the-box po `git pull && make up`.

!!! warning "Minimalne wymagania sprzętowe"
**Minimum: 12 GB RAM. Zalecane: 16 GB+ RAM.** Suma stałych limitów (~3,3 GB) +
minimalne progi usług zmiennych (dbserver/appserver/workery = 6,5 GB) + rezerwa OS
(2 GB) daje ~12 GB. Przy 12 GB wszystko się mieści, ale ciasno (dbserver na minimum,
zerowa nadwyżka). Dopiero od 16 GB nadwyżka realnie zasila bazę, aplikację i workery.
**Minimum: 12 GB RAM. Zalecane: 16 GB+ RAM.** Suma stałych limitów (~4,3 GB) +
minimalne progi usług zmiennych (dbserver/appserver/workerserver = 5 GB) + rezerwa OS
(2 GB) daje ~11,3 GB. Przy 12 GB wszystko się mieści, ale ciasno (usługi zmienne
niemal na minimum, ~0,7 GB nadwyżki). Dopiero od 16 GB nadwyżka realnie zasila bazę, aplikację i workery.
Poniżej 12 GB `configure-resources` ostrzega o ryzyku OOM.

## Model: stałe capy + usługi zmienne
Expand Down Expand Up @@ -49,13 +49,14 @@ Wynik ląduje w `$BPP_CONFIGS_DIR/.env` jako `DBSERVER_MEM_LIMIT`, `REDIS_MEM_LI
oraz `REDIS_MAXMEMORY` (≈80% limitu Redisa, żeby eviction `allkeys-lru` wyprzedził
OOM kill). `.env` staje się jednym źródłem prawdy dla limitów RAM. CPU jest zapisywane
dla 6 usług (3 zmienne + `redis`/`loki`/`netdata`); pozostałe korzystają z CPU z compose.
`netdata` ma minimum **1.0 CPU** — niższej wartości kreator nie przyjmie.

## Usługi ze stałym capem

| Serwis | RAM | Uwagi |
|---|---|---|
| `redis` | 1g | broker + cache + result backend; `REDIS_MAXMEMORY` (`allkeys-lru`) ≈ 80% limitu |
| `netdata` | 320m | dbengine + auto-discovery; patrz uwaga niżej o retencji |
| `netdata` | 768m | dbengine + auto-discovery; **minimum 768m i 1.0 CPU** (podniesione z 320m; `make up` samo podnosi niższe wartości w `.env`) — patrz uwaga niżej o retencji |
| `authserver` | 320m | Django + gunicorn (SSO) |
| `celerybeat` | 480m | scheduler — pojedynczy proces; podniesione z 320m (Django + broker potrafiły dobić do twardego capu → OOM) |
| `denorm-queue` | 320m | most PG `LISTEN` → Celery, pojedynczy proces |
Expand All @@ -67,8 +68,9 @@ dla 6 usług (3 zmienne + `redis`/`loki`/`netdata`); pozostałe korzystają z CP
| `dozzle` | 64m | przeglądarka logów (Go) |
| `ofelia` | 64m | scheduler cron (Go) |
| `autoheal` | 32m | restart kontenerów po unhealthy |
| `pgbouncer` | 64m | pula połączeń appservera — patrz sekcja pgbouncer niżej |

Razem ≈ **3,8 GB**. Capy te są odejmowane od budżetu, a reszta trafia do usług zmiennych.
Razem ≈ **4,3 GB**. Capy te są odejmowane od budżetu, a reszta trafia do usług zmiennych.

## Usługi zmienne (dzielą pulę)

Expand Down Expand Up @@ -104,9 +106,11 @@ bo jego realny apetyt na RAM zależy od liczby procesów-dzieci prefork.
policzoną — oba usuwają nieużywane `WORKER_GENERAL_*`/`WORKER_DENORM_*`.

!!! tip "Netdata: cap kontra retencja"
Cap `netdata` (320m) to limit **twardy**. Jeśli wydłużasz historię metryk przez
Cap `netdata` (768m) to limit **twardy**. Jeśli wydłużasz historię metryk przez
`NETDATA_DBENGINE_TIER0_RETENTION_MB` / `NETDATA_DBENGINE_PAGE_CACHE_MB` w `.env`,
**podnieś również `NETDATA_MEM_LIMIT`** — inaczej netdata zostanie ubity przez OOM.
Minimum to **768m RAM i 1.0 CPU**: każde `make up` podnosi niższe
`NETDATA_MEM_LIMIT`/`NETDATA_CPU_LIMIT` w `.env` do tego progu (wyższe zostawia).
Plik `netdata.conf` jest [force-syncowany](architektura.md#netdataconf-renderowany-host-side) —
nie edytuj go ręcznie, używaj knobów `.env`.

Expand Down
18 changes: 11 additions & 7 deletions scripts/configure-resources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ CPU_BUDGET="$CPU_COUNT"
# Format: name:cap_mb. Przypisywane automatycznie (bez pytania).
FIXED_MEM=(
"redis:1024"
"netdata:320"
"netdata:768"
"authserver:320"
"celerybeat:480"
"denorm-queue:320"
Expand All @@ -150,7 +150,10 @@ VARIABLE_MEM=(
"workerserver:1536:35"
)

# CPU (limit miekki). Format: name:cpu_weight. Sumuja sie do CPU_TOTAL_WEIGHT.
# CPU (limit miekki). Format: name:cpu_weight[:min_cpu]. Wagi sumuja sie do
# CPU_TOTAL_WEIGHT. Opcjonalne min_cpu to minimum uslugi - podnosi default
# i odrzuca nizsza odpowiedz (bez niego obowiazuje MIN_CPU). Netdata ma 1.0:
# przy wadze 5% na malym hoscie dostawala ~0.2 CPU i nie nadazala ze zbieraniem.
# Po konsolidacji jeden worker przejmuje wage dwoch poprzednich (25+12.5
# zaokraglone do 30 - reszta puli i tak idzie do dbserver/appserver).
CPU_SERVICES=(
Expand All @@ -159,7 +162,7 @@ CPU_SERVICES=(
"workerserver:30"
"redis:7.5"
"loki:2.5"
"netdata:5"
"netdata:5:1.0"
)
# Suma wag CPU_SERVICES - uzywane jako startowa pula w redystrybucji.
CPU_TOTAL_WEIGHT=95
Expand Down Expand Up @@ -375,8 +378,9 @@ done
remaining_cpu=$CPU_BUDGET
remaining_cpu_weight=$CPU_TOTAL_WEIGHT
for entry in "${CPU_SERVICES[@]}"; do
IFS=: read -r svc cpu_w <<< "$entry"
default_cpu=$(LC_ALL=C awk -v r="$remaining_cpu" -v w="$cpu_w" -v t="$remaining_cpu_weight" -v min="$MIN_CPU" \
IFS=: read -r svc cpu_w svc_min_cpu <<< "$entry"
svc_min_cpu="${svc_min_cpu:-$MIN_CPU}"
default_cpu=$(LC_ALL=C awk -v r="$remaining_cpu" -v w="$cpu_w" -v t="$remaining_cpu_weight" -v min="$svc_min_cpu" \
'BEGIN { if (t <= 0) v = min; else v = r * w / t; if (v < min) v = min; printf "%.1f", v }')
cpu_answer=""
while true; do
Expand All @@ -386,8 +390,8 @@ for entry in "${CPU_SERVICES[@]}"; do
continue
fi
cpu_answer=$(round1 "$cpu_answer")
if LC_ALL=C awk -v v="$cpu_answer" -v m="$MIN_CPU" 'BEGIN { exit (v < m) ? 0 : 1 }'; then
echo " Blad: minimum to ${MIN_CPU} CPU (Docker odrzuci mniej)." >&2
if LC_ALL=C awk -v v="$cpu_answer" -v m="$svc_min_cpu" 'BEGIN { exit (v < m) ? 0 : 1 }'; then
echo " Blad: minimum dla $svc to ${svc_min_cpu} CPU." >&2
continue
fi
break
Expand Down
47 changes: 47 additions & 0 deletions scripts/ensure-config-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,53 @@ if [ -f "$_ENV" ]; then
_ensure_var LOKI_RETENTION_WEBSERVER "$(_loki_period webserver 4320h)" \
" + dopisano LOKI_RETENTION_WEBSERVER w .env"

# Minimum zasobow netdaty: 768m RAM, 1.0 CPU. `make configure-resources`
# wpisywal wczesniej do .env NETDATA_MEM_LIMIT=320m i NETDATA_CPU_LIMIT
# rzedu 0.2 (5% puli CPU), a Compose default dziala tylko gdy zmiennej
# brak - wiec samo podniesienie defaultow nie dotarloby do istniejacych
# instalacji. Podnosimy WYLACZNIE wartosci ponizej minimum; wyzsze (strojone
# przez operatora, np. pod dluzsza retencje dbengine) zostaja nietkniete.
# Brak zmiennej = nic nie robimy, bo wtedy obowiazuje default z compose.
# Niezrozumiala wartosc -> ostrzezenie, nie ruszamy (nie zgadujemy jednostek).
_set_existing_var() { # $1 = nazwa, $2 = nowa wartosc (zmienna musi istniec)
local _t="$_ENV.tmp.$$"
awk -v k="$1" -v v="$2" 'BEGIN { FS=OFS="=" } $1 == k { print k "=" v; next } { print }' \
"$_ENV" > "$_t" && mv "$_t" "$_ENV"
}
_mem_to_mb() { # Docker: liczba + opcjonalnie b/k/m/g (+ 'b'); goła liczba = bajty
printf '%s' "$1" | LC_ALL=C awk '
match(tolower($0), /^[0-9]+(\.[0-9]+)?(b|k|kb|m|mb|g|gb)?$/) {
v = $0 + 0; u = tolower($0); sub(/^[0-9.]+/, "", u)
if (u == "" || u == "b") v = v / 1048576
else if (u ~ /^k/) v = v / 1024
else if (u ~ /^g/) v = v * 1024
printf "%d", v; ok = 1
}
END { exit ok ? 0 : 1 }'
}
_nd_mem="$(grep -E '^NETDATA_MEM_LIMIT=' "$_ENV" | tail -1 | cut -d= -f2- | tr -d '\r' || true)"
if [ -n "$_nd_mem" ]; then
if _nd_mem_mb="$(_mem_to_mb "$_nd_mem")"; then
if [ "$_nd_mem_mb" -lt 768 ]; then
_set_existing_var NETDATA_MEM_LIMIT 768m
echo " ~ podniesiono NETDATA_MEM_LIMIT z ${_nd_mem} do minimum 768m"
fi
else
echo " ! OSTRZEZENIE: nie rozumiem NETDATA_MEM_LIMIT='${_nd_mem}' w .env - zostawiam (minimum to 768m)" >&2
fi
fi
_nd_cpu="$(grep -E '^NETDATA_CPU_LIMIT=' "$_ENV" | tail -1 | cut -d= -f2- | tr -d '\r' || true)"
if [ -n "$_nd_cpu" ]; then
if [[ "$_nd_cpu" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
if LC_ALL=C awk -v v="$_nd_cpu" 'BEGIN { exit (v < 1.0) ? 0 : 1 }'; then
_set_existing_var NETDATA_CPU_LIMIT 1.0
echo " ~ podniesiono NETDATA_CPU_LIMIT z ${_nd_cpu} do minimum 1.0"
fi
else
echo " ! OSTRZEZENIE: nie rozumiem NETDATA_CPU_LIMIT='${_nd_cpu}' w .env - zostawiam (minimum to 1.0)" >&2
fi
fi

# BPP_BACKUP_PG_IMAGE nie jest tu juz samouzdrawiana - zmienna jest MARTWA
# od 2026-09. Byla potrzebna, gdy backup-runner wspoldzielil obraz Postgresa
# z sentinelem trybu external; orkiestrator (docker:cli) obrazu Postgresa
Expand Down
50 changes: 49 additions & 1 deletion tests/test_makefile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1663,7 +1663,15 @@ test_configure_resources() {
assert_file_contains "alloy cap 192m" "ALLOY_MEM_LIMIT=192m" "$cfg/.env"
assert_file_contains "loki cap 512m" "LOKI_MEM_LIMIT=512m" "$cfg/.env"
assert_file_contains "flower cap 128m" "FLOWER_MEM_LIMIT=128m" "$cfg/.env"
assert_file_contains "netdata cap 320m" "NETDATA_MEM_LIMIT=320m" "$cfg/.env"
assert_file_contains "netdata cap 768m" "NETDATA_MEM_LIMIT=768m" "$cfg/.env"
# CPU netdaty zalezy od liczby rdzeni runnera - sprawdzamy tylko minimum 1.0.
local nd_cpu
nd_cpu=$(grep '^NETDATA_CPU_LIMIT=' "$cfg/.env" | cut -d= -f2 || true)
if [ -n "$nd_cpu" ] && LC_ALL=C awk -v v="$nd_cpu" 'BEGIN { exit (v >= 1.0) ? 0 : 1 }'; then
pass "netdata CPU >= 1.0 ($nd_cpu)"
else
fail "netdata CPU >= 1.0 (jest: '${nd_cpu}')"
fi
assert_file_contains "grafana cap 192m" "GRAFANA_MEM_LIMIT=192m" "$cfg/.env"
assert_file_contains "dozzle cap 64m" "DOZZLE_MEM_LIMIT=64m" "$cfg/.env"
assert_file_contains "pgbouncer cap 64m" "PGBOUNCER_MEM_LIMIT=64m" "$cfg/.env"
Expand Down Expand Up @@ -2082,6 +2090,45 @@ YAML
rm -rf "$cfg"
}

test_ensure_config_files_netdata_floor() {
yellow "=== Test: ensure-config-files podnosi limity netdaty do minimum ==="

local cfg
# Stary .env po configure-resources: 320m / 0.2 -> podniesione do 768m / 1.0.
cfg=$(mktemp -d)
printf 'BPP_CONFIGS_DIR=%s\nNETDATA_MEM_LIMIT=320m\nNETDATA_CPU_LIMIT=0.2\n' "$cfg" > "$cfg/.env"
if ! BPP_CONFIGS_DIR="$cfg" bash "$REPO_DIR/scripts/ensure-config-files.sh" >/dev/null 2>&1; then
fail "ensure-config-files zwrocil blad (netdata ponizej minimum)"
rm -rf "$cfg"; return
fi
assert_file_contains "netdata RAM 320m -> 768m" "^NETDATA_MEM_LIMIT=768m$" "$cfg/.env"
assert_file_contains "netdata CPU 0.2 -> 1.0" "^NETDATA_CPU_LIMIT=1.0$" "$cfg/.env"
if [ "$(grep -c '^NETDATA_MEM_LIMIT=' "$cfg/.env")" = "1" ]; then
pass "NETDATA_MEM_LIMIT wystepuje raz"
else
fail "NETDATA_MEM_LIMIT wystepuje raz"
fi
rm -rf "$cfg"

# Wartosci powyzej minimum (strojone przez operatora) zostaja nietkniete.
cfg=$(mktemp -d)
printf 'BPP_CONFIGS_DIR=%s\nNETDATA_MEM_LIMIT=1g\nNETDATA_CPU_LIMIT=2.5\n' "$cfg" > "$cfg/.env"
BPP_CONFIGS_DIR="$cfg" bash "$REPO_DIR/scripts/ensure-config-files.sh" >/dev/null 2>&1 \
|| fail "ensure-config-files zwrocil blad (netdata powyzej minimum)"
assert_file_contains "netdata RAM 1g bez zmian" "^NETDATA_MEM_LIMIT=1g$" "$cfg/.env"
assert_file_contains "netdata CPU 2.5 bez zmian" "^NETDATA_CPU_LIMIT=2.5$" "$cfg/.env"
rm -rf "$cfg"

# Brak zmiennych -> nie dopisujemy (obowiazuje default z compose).
cfg=$(mktemp -d)
printf 'BPP_CONFIGS_DIR=%s\n' "$cfg" > "$cfg/.env"
BPP_CONFIGS_DIR="$cfg" bash "$REPO_DIR/scripts/ensure-config-files.sh" >/dev/null 2>&1 \
|| fail "ensure-config-files zwrocil blad (brak zmiennych netdaty)"
assert_file_not_contains "brak NETDATA_MEM_LIMIT nie jest dopisywany" "NETDATA_MEM_LIMIT=" "$cfg/.env"
assert_file_not_contains "brak NETDATA_CPU_LIMIT nie jest dopisywany" "NETDATA_CPU_LIMIT=" "$cfg/.env"
rm -rf "$cfg"
}

test_ensure_config_files_altcha_selfheal() {
yellow "=== Test: ensure-config-files dosypuje ALTCHA do starego .env ==="

Expand Down Expand Up @@ -2359,6 +2406,7 @@ test_configure_resources_worker_consolidation
test_init_configs_generates_altcha
test_loki_retention_migration
test_ensure_config_files_altcha_selfheal
test_ensure_config_files_netdata_floor
test_init_configs_path_validation
test_install_docker_windows
test_rclone_single_source_of_truth
Expand Down
Loading