VPS nasazení
Nasazení na VPS server
Tato dokumentace používá zástupné hodnoty (<VPS_IP>, <OWNER>) místo skutečných produkčních údajů. Nahraďte je reálnými hodnotami z vašeho prostředí.
Specifikace serveru
| Položka | Hodnota |
|---|---|
| IP adresa | <VPS_IP> |
| Poskytovatel | Hetzner Cloud |
| OS | Ubuntu 24.04 |
| SSH (deploy) | ssh deploy@<VPS_IP> |
| SSH (admin) | ssh root@<VPS_IP> |
| Adresář aplikace | /opt/apps/turtor |
Domény a DNS
Všechny tři domény směřují na stejný VPS a jsou obsluhovány přes nginx reverse proxy:
| Doména | Služba | Kontejner |
|---|---|---|
ckk.byadf.ai | Veřejný web | turtor-web (nginx SPA) |
api.ckk.byadf.ai | REST API | turtor-api (Node.js) |
admin.ckk.byadf.ai | Admin panel | turtor-admin (nginx SPA) |
Nginx reverse proxy
VPS používá sdílený nginx-proxy kontejner (/opt/nginx-proxy/) s konfigurací per-doména v /opt/nginx-proxy/conf.d/:
ckk.conf-- web frontendckk-api.conf-- API s WebSocket podporouckk-admin.conf-- admin frontend
Klíčové funkce nginx
- HTTP -> HTTPS přesměrování
- Let's Encrypt ACME challenge podpora
- Rate limiting: API 10 req/s (burst 20), obecný 30 req/s (burst 50)
- Gzip komprese
- Security headers (HSTS, X-Frame-Options, X-Content-Type-Options)
- SSL: TLSv1.2 + TLSv1.3
- WebSocket:
proxy_read_timeout 86400pro Socket.IO - Keepalive: 32 spojení na upstream
SSL certifikáty
SSL certifikáty se získávají přes Let's Encrypt pomocí skriptu na VPS:
# Získání certifikátu (DNS musí směřovat na VPS)
ssh deploy@<VPS_IP> "/opt/scripts/add-ssl ckk.byadf.ai noreply@turtor.cz"
ssh deploy@<VPS_IP> "/opt/scripts/add-ssl api.ckk.byadf.ai noreply@turtor.cz"
ssh deploy@<VPS_IP> "/opt/scripts/add-ssl admin.ckk.byadf.ai noreply@turtor.cz"Certbot automaticky obnovuje certifikáty. Přesto je doporučeno pravidelně kontrolovat platnost.
Remote Docker builder
Docker obrazy se staví vzdáleně na VPS přes Docker Buildx. Tím se obchází problém s QEMU emulací na Apple Silicon (ARM), kde esbuild padá na OOM:
# Vytvoření remote builderu (jednorázově)
docker buildx create --name vps-builder \
--driver docker-container \
--platform linux/amd64 \
"ssh://deploy@<VPS_IP>"
# Build se automaticky spustí na VPS
docker buildx build --builder vps-builder \
--platform linux/amd64 \
-f docker/Dockerfile.api \
-t ghcr.io/<OWNER>/turtor-api:latest \
--push .GHCR (GitHub Container Registry)
Docker obrazy se ukládají v GitHub Container Registry:
| Obraz | Registry |
|---|---|
| API | ghcr.io/<OWNER>/turtor-api |
| Web | ghcr.io/<OWNER>/turtor-web |
| Admin | ghcr.io/<OWNER>/turtor-admin |
# Přihlášení do GHCR na VPS
gh auth token | ssh deploy@<VPS_IP> "docker login ghcr.io -u <OWNER> --password-stdin"Záloha databáze
# Vytvoření zálohy (načte env proměnné z .env)
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && \
source .env && \
docker compose exec -T postgres pg_dump -U \$DATABASE_USER \$DATABASE_NAME > backup.sql"
# Obnovení ze zálohy
ssh deploy@<VPS_IP> "cd /opt/apps/turtor && \
source .env && \
docker compose exec -T postgres psql -U \$DATABASE_USER \$DATABASE_NAME < backup.sql"Vždy vytvořte zálohu databáze před spuštěním migrací na produkci. Nikdy nespouštějte docker volume rm na produkční databázový volume.
Rollback
# Nasazení konkrétní starší verze (stáhne daný tag z GHCR)
./scripts/deploy.sh v1.2.3Příkaz docker compose up -d --force-recreate bez změny tagu image provede pouze restart kontejnerů, nikoliv skutečný rollback. Pro rollback na starší verzi vždy použijte deploy skript s konkrétním tagem.