Installation
Zasoby systemowe i strojenie
Minimalne i zalecane RAM/CPU dla wdrożenia QuoteNode, jak działają limity kontenerów, jak je dostosować i jak uniknąć problemów z brakiem pamięci.
Zasoby systemowe i strojenie
QuoteNode działa jako niewielki zestaw kontenerów Docker. Pliki Compose mają limity pamięci i CPU dobrane pod VM z 4 GB RAM, a każdy limit można nadpisać zmienną środowiskową, więc stack łatwo dopasujesz do swojej maszyny.
Minimum i zalecenia
| Poziom | RAM hosta | CPU hosta | Uwagi |
|---|---|---|---|
| Minimum | 4 GB | 2 rdzenie | Profil domyślny. Wygodny dla małego zespołu (≈10 użytkowników / ≈1 000 produktów). |
| Zalecane | 8 GB | 4 rdzenie | Zapas na równoległe importy/eksporty i skoki generowania PDF. |
| Obciążony | 8–16 GB | 4–8 rdzeni | ≈100 użytkowników / ≈20 000 produktów z równoległymi operacjami masowymi. |
Stack jest lekki na biegu jałowym: w spoczynku cały stack zużywa około 1,5 GiB RAM niezależnie od ilości danych w bazie (nie ma cache encji w JVM — dane żyją w PostgreSQL). RAM rośnie wraz ze współbieżnością operacji masowych (import/eksport/PDF), a nie z liczbą użytkowników czy rekordów.
Jak działają limity kontenerów
mem_limit to twardy sufit, nie rezerwacja. Kontener zużywa tylko tyle, ile realnie dotknie, aż do limitu; kontener, który przekroczy limit, zostaje ubity przez OOM. Wyższy limit nie kosztuje pamięci — podnosi tylko granicę bezpieczeństwa.
Profil domyślny sumuje się do około 3 520 MiB sufitów, co mieści się na hoście 4 GB z ~575 MiB dla systemu operacyjnego. Ponieważ realne zużycie na biegu jałowym jest znacznie niższe (~1,5 GiB), sufity to zapas na skoki obciążenia, a nie spodziewane zużycie.
cpus to też sufit, ale CPU jest darmowe na biegu jałowym — szczodry sufit CPU nic nie kosztuje w spoczynku, a pozwala serwisowi sięgnąć po rdzenie, gdy ich potrzebuje. Wartość cpus większa niż liczba rdzeni hosta oznacza po prostu „użyj wszystkich dostępnych rdzeni”, więc domyślne wartości są bezpieczne na VM z 1–2 rdzeniami.
Domyślne limity per serwis (profil 4 GB)
| Serwis | Pamięć | CPU | Rola |
|---|---|---|---|
| backend | 1536m | 4.0 | Serwer API / web (heap JVM auto-skaluje do 70% tej wartości) |
| postgres | 512m | 4.0 | Baza danych |
| backup-worker | 832m | 2.0 | Zaplanowane backupy (pg_dump) |
| gotenberg | 448m | 2.0 | Renderowanie PDF w Chromium |
| frontend | 96m | 2.0 | Caddy serwujący statyczny build |
| caddy | 96m | 2.0 | Ingress TLS / reverse-proxy — podnieś CADDY_MEM_LIMIT przy ciężkim ruchu TLS |
Dostosowanie RAM
Każdy limit to opcjonalna zmienna środowiskowa. Ustaw ją w .env.prod, aby nadpisać domyślną:
# Przykład: maszyna 8 GB z większym obciążeniem równoległym
BACKEND_MEM_LIMIT=3g
POSTGRES_MEM_LIMIT=1g
GOTENBERG_MEM_LIMIT=768m
Heap Javy backendu auto-skaluje do 70% BACKEND_MEM_LIMIT (przez MaxRAMPercentage), więc podniesienie limitu samo zwiększa heap — bez edycji flag JVM. Analogicznie (proporcjonalnie) działa backup-worker (używa 45%).
Dostępne zmienne: BACKEND_MEM_LIMIT, BACKEND_CPUS, POSTGRES_MEM_LIMIT, POSTGRES_CPUS, WORKER_MEM_LIMIT, WORKER_CPUS, GOTENBERG_MEM_LIMIT, GOTENBERG_CPUS, FRONTEND_MEM_LIMIT, FRONTEND_CPUS, CADDY_MEM_LIMIT, CADDY_CPUS.
CPU
Zostaw domyślne wartości CPU szczodre. Jedyne miejsce, gdzie CPU realnie ma znaczenie, to zimny start: backend i worker (oparte na JVM) bootują duży kontekst aplikacji, co jest CPU-bound. Na jednym rdzeniu zimny start może trwać minuty; przy 2+ rdzeniach jest grubo poniżej minuty. Okres karencji health-checka workera już uwzględnia wolne starty, więc maszyna z ograniczonym CPU sama dochodzi do zdrowia bez pętli restartów.
Unikanie problemów z brakiem pamięci
- Nie zmniejszaj
WORKER_MEM_LIMITponiżej ~768m. Backup (pg_dump+tar+gzip+ JVM) ma szczyt około 607 MiB; przy mniejszym zapasie może zostać ubity w trakcie backupu. - Na VM z 2 GB profil domyślny jest za duży — obniż limity (np.
BACKEND_MEM_LIMIT=768m,POSTGRES_MEM_LIMIT=384m), aby suma była poniżej fizycznego RAM. Heap backendu podąża za limitem automatycznie. - Patrz na hosta, nie tylko na kontenery. Jeśli host obsługuje inne zadania, policz też ich pamięć — Docker egzekwuje sufity per kontener, a nie łączne zużycie hosta.
- Kontener wielokrotnie restartujący się z kodem wyjścia 137 oznacza ubicie przez OOM; podnieś
*_MEM_LIMITtego serwisu.