Konfiguracja
Instalacja
Jak wdrożyć QuoteNode na własnej infrastrukturze za pomocą Docker Compose.
Instalacja
QuoteNode działa jako zestaw kontenerów Docker. Nie musisz instalować Java, Node.js ani PostgreSQL na swoim komputerze — Docker zajmuje się wszystkim.
Wymagania wstępne
- Docker Engine 24.0 lub nowszy (zainstaluj Dockera)
- Docker Compose v2 (dołączony do nowoczesnego Docker Desktop i Docker Engine)
- Maszyna z co najmniej 2 GB RAM i 10 GB wolnego miejsca na dysku
Aby zweryfikować konfigurację:
docker --version # Powinno pokazać 24.0+
docker compose version # Powinno pokazać v2.x
Szybki start (5 minut)
Poniższe kroki uruchamiają QuoteNode na Twoim lokalnym komputerze do testów. Nie jest to konfiguracja produkcyjna — zobacz niżej.
Krok 1 — Utwórz katalog projektu
mkdir quotenode && cd quotenode
Krok 2 — Utwórz plik konfiguracyjny
Utwórz plik o nazwie .env z minimalnymi wymaganymi ustawieniami:
# Baza danych
DB_URL=jdbc:postgresql://postgres:5432/quotenode
DB_USERNAME=quotenode
DB_PASSWORD=zmien-mnie-na-cos-losowego-min-32-znaki
DB_NAME=quotenode
# ============================================================
# SEKRETY BEZPIECZEŃSTWA — PRZECZYTAJ ZANIM PRZEJDZIESZ DALEJ
# Te wartości są UNIKALNE dla Twojej instalacji.
# Jeśli stracisz ten plik, NIE możesz wygenerować tych samych sekretów.
# ZAPISZ TEN PLIK i przechowuj bezpieczną kopię (lub nawet wydruk).
# ============================================================
DB_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TIMING_TOKEN_SECRET=zmien-mnie-timing-secret-min-32-znakow
PUBLIC_LINK_PASSWORD_SESSION_SECRET=zmien-mnie-session-secret-min-32
# Domena (dla CORS i Caddy)
CORS_ALLOWED_ORIGINS=http://localhost
DOMAIN=localhost
# Logowanie
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod
Zapisz plik
.envnatychmiast. Powyższe sekrety zostały losowo wygenerowane i są unikalne dla tej instalacji. Jeśli stracisz ten plik, nie możesz odtworzyć tych samych wartości. Bez oryginalnegoDB_ENCRYPTION_KEYzaszyfrowane dane (kody MFA, hasło SMTP, klucze API) stają się trwale nieczytelne. Skopiuj ten plik w bezpieczne miejsce — dla systemów produkcyjnych rozważ wydrukowanie sekretów i przechowywanie ich w fizycznym sejfie.
Krok 3 — Utwórz plik Docker Compose
Utwórz plik o nazwie docker-compose.yml:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
gotenberg:
image: gotenberg/gotenberg:8
environment:
LOG_LEVEL: info
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
backend:
image: ghcr.io/lesisty7/quotenode/quotenode-api:latest
depends_on:
postgres: { condition: service_healthy }
gotenberg: { condition: service_healthy }
env_file: .env
environment:
SPRING_PROFILES_ACTIVE: prod
JOBS_MODE: web
PDF_ENABLED: "true"
PDF_GOTENBERG_URL: http://gotenberg:3000
volumes:
- backend_uploads:/app/data/uploads
- backend_pdfs:/app/data/pdfs
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
interval: 15s
timeout: 10s
retries: 5
start_period: 45s
restart: unless-stopped
frontend:
image: ghcr.io/lesisty7/quotenode/quotenode-frontend:latest
depends_on:
backend: { condition: service_healthy }
ports:
- "80:80"
- "443:443"
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
volumes:
postgres_data:
backend_uploads:
backend_pdfs:
Krok 4 — Uruchom QuoteNode
docker compose up -d
Docker pobierze obrazy kontenerów (przy pierwszym uruchomieniu zajmie to kilka minut) i uruchomi wszystkie usługi. Możesz obserwować postęp startu:
docker compose logs -f backend
Poczekaj, aż zobaczysz linię Started QuoteNodeApplication — oznacza to, że backend jest gotowy.
Krok 5 — Otwórz QuoteNode
Przejdź do http://localhost w przeglądarce.
Domyślne dane logowania:
| Pole | Wartość |
|---|---|
[email protected] | |
| Hasło | Admin123! |
Zmień domyślne hasło natychmiast po zalogowaniu (Ustawienia > Mój profil > Zmień hasło).
Co właśnie uruchomiłeś?
Po docker compose up masz 4 kontenery:
| Kontener | Co robi | Zużycie RAM |
|---|---|---|
postgres | Przechowuje wszystkie dane | ~256 MB |
backend | Serwer API Java, logika biznesowa | ~512 MB – 1.5 GB |
gotenberg | Konwertuje HTML na PDF (Chromium) | ~200 MB |
frontend | Serwuje interfejs web + reverse proxy | ~20 MB |
Łącznie: około 1.5 – 2.5 GB RAM.
Przydatne komendy
# Sprawdź czy wszystkie usługi działają
docker compose ps
# Pokaż logi (wszystkie usługi)
docker compose logs -f
# Pokaż logi (tylko backend)
docker compose logs -f backend
# Zatrzymaj QuoteNode
docker compose down
# Zaktualizuj do najnowszej wersji
docker compose pull && docker compose up -d
Bezpieczeństwo sekretów
Twój plik .env zawiera kryptograficzne sekrety, które są unikalne dla Twojej instalacji. Zrozumienie, co chroni każdy sekret, pomoże Ci zaplanować strategię backupu:
| Sekret | Co chroni | Jeśli zgubiony |
|---|---|---|
DB_PASSWORD | Dostęp do bazy danych | Odzyskiwalny — reset przez narzędzia administracyjne PostgreSQL |
DB_ENCRYPTION_KEY | Kody MFA (TOTP), hasło SMTP, klucz API FX — oraz wszystkie pola PII gdy ENCRYPT_PII=true | Trwale nieczytelne — tych pól nie da się odszyfrować bez oryginalnego klucza |
TIMING_TOKEN_SECRET | Tokeny anty-timing-attack | Wygeneruj nowy — istniejące tokeny unieważnione, użytkownicy logują się ponownie |
PUBLIC_LINK_PASSWORD_SESSION_SECRET | Sesje publicznych linków | Wygeneruj nowy — aktywne sesje wygasają, linki nadal działają |
Krytycznym sekretem jest
DB_ENCRYPTION_KEY. Wszystkie inne sekrety można wygenerować ponownie z niewielką niedogodnością. AleDB_ENCRYPTION_KEYszyfruje dane w bazie — jego utrata oznacza, że te pola przepadają bezpowrotnie. JeśliENCRYPT_PII=true, dotyczy to również wszystkich danych osobowych klientów, kontaktów, dostawców i użytkowników (imiona, e-maile, telefony, NIP-y). Bez włączonego szyfrowania PII dane biznesowe są przechowywane bez szyfrowania i pozostają w pełni dostępne.
Dla systemów produkcyjnych zalecamy:
- Przechowuj kopię
.envw menedżerze haseł (1Password, Bitwarden itp.) - Dla maksymalnego bezpieczeństwa wydrukuj sekrety i przechowuj wydruk w fizycznym sejfie
- Nigdy nie commituj
.envdo repozytorium
Odzyskiwanie po utracie .env
Jeśli stracisz plik .env, ale masz niezaszyfrowany backup bazy danych (domyślny tryb backupu), możesz odzyskać swoje dane:
- Utwórz nowy plik
.envz nowymi sekretami - Przywróć bazę danych z backupu (
pg_dump/pg_restore) - Wszystkie dane biznesowe (klienci, oferty, produkty, użytkownicy) będą w pełni dostępne
- Tylko kilka pól jest utraconych: kody MFA (użytkownicy muszą ponownie skonfigurować), hasło SMTP (wprowadź ponownie w ustawieniach), klucz API FX (wprowadź ponownie w ustawieniach). Jeśli
ENCRYPT_PII=truebyło włączone, wszystkie dane osobowe (imiona, e-maile, telefony, NIP-y) są również utracone — rozważ to przed włączeniem szyfrowania PII
Jeśli Twoje backupy są zaszyfrowane GPG (przez BACKUP_GPG_RECIPIENT), musisz najpierw odszyfrować je kluczem prywatnym GPG.
Wdrożenie produkcyjne
Do użytku produkcyjnego musisz:
- Wygenerować właściwe sekrety — nigdy nie używaj przykładowych wartości z powyżej na produkcji:
# Wygeneruj 64-znakowy klucz hex do szyfrowania bazy
openssl rand -hex 32
# Wygeneruj losowe sekrety dla tokenów
openssl rand -base64 32
-
Skonfigurować domenę z HTTPS — ustaw
DOMAINiCORS_ALLOWED_ORIGINSna swoją prawdziwą domenę. Kontener frontend (Caddy) automatycznie uzyskuje certyfikaty Let’s Encrypt. -
Skonfigurować e-mail — dodaj ustawienia SMTP do
.env, aby włączyć wysyłkę ofert:
SMTP_HOST=smtp.twojdostawca.com
SMTP_PORT=587
SMTP_USERNAME=[email protected]
SMTP_PASSWORD=twoje-haslo-smtp
SMTP_AUTH=true
SMTP_STARTTLS=true
-
Wykonać kopię zapasową pliku
.env— przechowuj go bezpiecznie, zanim zrobisz cokolwiek innego. Zobacz Bezpieczeństwo sekretów powyżej. -
Włączyć kopie zapasowe bazy — zobacz przewodnik Backup & Recovery.
-
Przejrzeć wszystkie ustawienia — pobierz pełny .env.prod.example z repozytorium, aby zobaczyć wszystkie dostępne zmienne konfiguracyjne.
Zaawansowane opcje wdrożenia (Coolify PaaS, worker backupów, GeoIP) opisane są na stronie wiki Deployment Options.
Aktualizacja QuoteNode
Aby zaktualizować do najnowszej wersji:
docker compose pull && docker compose up -d
Plik
.envnigdy nie jest modyfikowany przez aktualizacje. Docker pobiera nowe obrazy kontenerów, ale Twoja konfiguracja i dane pozostają nienaruszone. Nie usuwaj ani nie twórz ponownie pliku.envpodczas aktualizacji — te same sekrety muszą być używane przez cały czas życia instalacji.
Migracje schematu bazy danych uruchamiają się automatycznie przy starcie backendu — żaden ręczny krok nie jest potrzebny.
Rozwiązywanie problemów
Backend nie startuje
Sprawdź logi: docker compose logs backend. Częste problemy:
- Baza danych nie gotowa — backend czeka na PostgreSQL. Jeśli PostgreSQL wolno startuje, backend ponawia próby automatycznie.
- Nieprawidłowe sekrety —
DB_ENCRYPTION_KEYmusi mieć dokładnie 64 znaki hex.DB_PASSWORDmusi być zgodne między kontenerami backend i PostgreSQL. - Konflikt portów — jeśli port 80 lub 443 jest już zajęty, zmień mapowanie
portswdocker-compose.yml.
Nie mogę połączyć się z QuoteNode
- Sprawdź, czy wszystkie kontenery działają:
docker compose ps - Sprawdź, czy kontener frontend pokazuje status “healthy”
- Spróbuj
http://localhost(niehttps://przy testach lokalnych bez prawdziwej domeny)
Zapomniałem hasła admina
Zatrzymaj stack, usuń wolumen PostgreSQL i uruchom ponownie — konto admina zostanie odtworzone przy pierwszym starcie:
docker compose down -v # UWAGA: usuwa wszystkie dane!
docker compose up -d
Na produkcji użyj zamiast tego funkcji resetu hasła w panelu administracyjnym.
Następne kroki
- Przewodnik konfiguracji — branding, szablony e-mail, ustawienia bezpieczeństwa
- Deployment Options — Coolify, topologia produkcyjna, worker backupów
- Backup & Recovery — automatyczne kopie zapasowe z szyfrowaniem