5. Zabezpieczenie VPS – Traefik
Dokumentacja konfiguracji Traefika jako reverse proxy dla backendów Palette i Tinting na VPS. Traefik obsługuje ruch na portach 80/443, wystawia certyfikaty Let's Encrypt i kieruje żądania do odpowiednich serwisów.
Środowisko
color-selector-backend (na VPS: color-selector-admin)
| Serwis | Port | Uwagi |
|---|---|---|
| Directus | 8055 | CMS Palette |
| n8n | 5678 | Basic Auth w zmiennych środowiskowych |
| PostgreSQL | – | Brak portu na hosta |
| Redis | – | Brak portu na hosta |
| Backup | – | Do AWS |
TRUST_PROXY i PUBLIC_URL muszą być ustawione w zmiennych środowiskowych.
color-tinting-backend
| Serwis | Port | Uwagi |
|---|---|---|
| Directus | 8056 | CMS Tinting (mapowanie host:8056→kontener:8055) |
| PostgreSQL | – | Port zakomentowany na produkcji |
| Redis | – | Brak portu na hosta |
| Adminer | – | Port zakomentowany na produkcji |
Architektura
Internet (80/443)
│
▼
[ Traefik ]
│
├── color-selector.pl/ → directus (color-selector-admin) :8055
├── color-selector.pl/tinting/ → directus (color-tinting-backend) :8055
└── color-selector.pl/n8n/ → n8n :5678
Mapowanie katalogów
| Na VPS | W repozytorium |
|---|---|
| color-selector-admin | color-selector-backend |
| color-tinting-backend | color-tinting-backend |
Funkcje Traefika
- Jeden punkt wejścia – porty 80/443; backends nie są wystawiane bezpośrednio na internet.
- Automatyczne certyfikaty Let's Encrypt (HTTP-01).
- Routing po domenie i ścieżce (host + PathPrefix).
- Konfiguracja przez labels w
docker-compose. - Redirect HTTP → HTTPS.
Konfiguracja
1. Sieć Docker
docker network create traefik-public
W każdym docker-compose (color-selector-backend, color-tinting-backend):
networks:
traefik-public:
external: true
2. Traefik
Katalog traefik/ zawiera:
traefik.yml– konfiguracja statycznadocker-compose.yml– serwis Traefikaletsencrypt/– katalog na certyfikaty (mkdir letsencrypt && chmod 700 letsencrypt)
traefik/traefik.yml
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: twoj@email.pl
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-public
Adres e-mail w acme.email musi być prawidłowy – Let's Encrypt używa go do powiadomień. Nie musi być w domenie serwisu.
traefik/docker-compose.yml
services:
traefik:
image: traefik:v3.2
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./letsencrypt:/letsencrypt
networks:
- traefik-public
environment:
- TRAEFIK_API_INSECURE=true
- DOCKER_HOST=unix:///var/run/docker.sock
networks:
traefik-public:
external: true
3. Labels – color-selector-backend
Directus (Palette)
directus:
networks:
- directus-network
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.directus-palette.rule=Host(`color-selector.pl`) && !PathPrefix(`/tinting`) && !PathPrefix(`/n8n`)"
- "traefik.http.routers.directus-palette.entrypoints=websecure"
- "traefik.http.routers.directus-palette.tls=true"
- "traefik.http.routers.directus-palette.tls.certresolver=letsencrypt"
- "traefik.http.routers.directus-palette.priority=10"
- "traefik.http.services.directus-palette.loadbalancer.server.port=8055"
n8n
n8n:
networks:
- directus-network
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`color-selector.pl`) && PathPrefix(`/n8n`)"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls=true"
- "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
- "traefik.http.routers.n8n.priority=20"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
- "traefik.http.middlewares.n8n-strip.stripprefix.prefixes=/n8n"
- "traefik.http.routers.n8n.middlewares=n8n-strip"
Middleware Stripprefix dla n8n jest wymagany – bez niego n8n zwraca HTML zamiast plików CSS/JS, co powoduje błędy MIME type w przeglądarce.
4. Labels – color-tinting-backend
Directus (Tinting)
directus:
networks:
- directus-test-network
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.directus-tinting.rule=Host(`color-selector.pl`) && PathPrefix(`/tinting`)"
- "traefik.http.routers.directus-tinting.entrypoints=websecure"
- "traefik.http.routers.directus-tinting.tls=true"
- "traefik.http.routers.directus-tinting.tls.certresolver=letsencrypt"
- "traefik.http.routers.directus-tinting.priority=20"
- "traefik.http.services.directus-tinting.loadbalancer.server.port=8055"
- "traefik.http.middlewares.tinting-strip.stripprefix.prefixes=/tinting"
- "traefik.http.routers.directus-tinting.middlewares=tinting-strip"
PUBLIC_URL w Directus (Tinting): https://color-selector.pl/tinting/ (ze slash na końcu).
Wyłączenie portów na hostzie
Po potwierdzeniu działania przez Traefik można usunąć mapowanie portów (ports:) z serwisów directus i n8n w color-selector-backend oraz z directusa w color-tinting-backend. Dostęp będzie wyłącznie przez Traefik.
Rozwiązywanie problemów
| Objaw | Działanie |
|---|---|
| Port 80 zajęty | sudo systemctl stop nginx && sudo systemctl disable nginx |
| „Error response from daemon” | Dodać DOCKER_HOST=unix:///var/run/docker.sock w environment Traefika |
| „unable to parse email address” | Ustawić prawidłowy adres e-mail w traefik.yml |
| n8n: MIME type text/html dla CSS/JS | Dodać middleware Stripprefix /n8n do routera n8n |
Wdrożenie
Szczegółowy przewodnik wdrożenia: traefik/WDROZENIE-VPS.md.
Wymagania przed startem
- Sieć
traefik-publicutworzona PUBLIC_URLw color-tinting-backend:https://color-selector.pl/tinting/- Prawidłowy adres e-mail w
traefik.yml(certyfikaty Let's Encrypt) - Nginx zatrzymany (jeśli wcześniej obsługiwał port 80)