Revert compose to public git clone with env-based HTML generation, allow inline scripts in CSP for YouTube player, and use window.location.origin for embed origin. Co-authored-by: Cursor <cursoragent@cursor.com>
Slavic Pulse - Frontend (Dokploy Deployment)
Statyczna strona z intro YouTube (short FHD 16:9 lub vertical 9:16 — wybór po formacie viewportu). Tło przed filmem to miniaturka z YouTube. Konfiguracja w .env, HTML generowany przy starcie kontenera.
Struktura projektu
site-slavic-pulse-com/
├── docker-compose.yml # Lokalny dev (build z Dockerfile)
├── Dockerfile
├── default.conf
├── nginx.conf
├── index.html.template # Szablon strony
├── generate-from-env.sh # Generator HTML z .env
├── assets/imgs/favico/ # Favicony
├── site.webmanifest.template
└── docker-compose-example/ # Pliki deploymentowe Dokploy
├── docker-compose.yml
├── .env.example
└── README.md
Dokploy deployment
Ten sam model co site-agencja-ai-com: Dokploy kopiuje na serwer tylko docker-compose.yml + .env — nie ma tam Dockerfile ani pełnego repo. Kontener przy starcie robi git clone publicznego repo, generuje HTML z .env i uruchamia nginx.
Kroki w Dokploy UI:
- Nowa aplikacja (Compose) → wklej
docker-compose-example/docker-compose.yml - Wklej
.env(na podstawie.env.example) — ustawFRONTEND_PORT,VIDEO_ID_*, opisy SEO - Domains → dodaj oba hosty (Container Port =
80, HTTPS = Let's Encrypt):slavic-pulse.comwww.slavic-pulse.com← wymagane — bez tego www dostaje domyślny cert Traefika (CN=*, self-signed) i telefony pokazują „serwer nie potrafi udowodnić tożsamości”
- (Opcjonalnie) Advanced → Redirects → preset www → non-www
- Deploy
Porty: compose mapuje ${FRONTEND_PORT}:80 (jak agencja-ai). Traefik/Dokploy dodatkowo routuje po FQDN do wewnętrznego portu 80 kontenera.
Repo musi być publiczne w Gitea — clone bez tokenu. Po git push zrób redeploy, żeby kontener pobrał nowy kod.
Jak to działa
- Start kontenera —
git clonepublicznego repo do/app generate-from-env.sh— budujeindex.htmlisite.webmanifestze zmiennych.env- Kopiowanie —
assets/,default.conf,nginx.conf→ nginx - Cleanup —
rm -rf /app(brak pełnego repo na dysku kontenera) - Intro wideo — YouTube IFrame API, autoplay; po filmie redirect lub tło
Konfiguracja (.env)
| Zmienna | Opis |
|---|---|
FRONTEND_PORT |
Port na hoście (np. 8082) |
VIDEO_ID_FHD / VIDEO_ID_VERTICAL |
ID shortów YouTube |
POST_VIDEO_REDIRECT_URL_* |
URL po zakończeniu filmu |
POST_VIDEO_REDIRECT_ENABLED |
true = redirect, false = zostaje tło |
Hardening bezpieczeństwa (wbudowany)
- Repo publiczne — brak tokena GITEA w kontenerze
- Po starcie
/appusuwane — brak compose/README/szablonów na dysku - nginx: whitelist ścieżek, blokada
.env/.sh/.template, nagłówki CSP/Referrer-Policy - CSP z
'unsafe-inline'dla skryptu YouTube (inline JS windex.html) server_tokens off— ukryta wersja nginx
Weryfikacja po deployu
# Strona działa
curl -sI https://slavic-pulse.com/ | head -5
# Wrażliwe pliki niedostępne (404)
curl -sI https://slavic-pulse.com/.env | grep HTTP
curl -sI https://slavic-pulse.com/generate-from-env.sh | grep HTTP
curl -sI https://slavic-pulse.com/random-path | grep HTTP
# Nagłówki bezpieczeństwa
curl -sI https://slavic-pulse.com/ | grep -iE 'content-security-policy|referrer-policy|permissions-policy'
# W kontenerze (na serwerze)
docker logs slavic-pulse-com-frontend --tail 30
docker exec slavic-pulse-com-frontend ls /app 2>&1 # powinno: No such file
docker exec slavic-pulse-com-frontend head -3 /usr/share/nginx/html/index.html
Rozwiązywanie problemów
Kontener Restarting / unhealthy
docker logs slavic-pulse-com-frontend --tail 50
Typowe przyczyny:
- Repo prywatne → ustaw jako Public w Gitea
- Brak lub błędny
.envw Dokploy - Błąd w
generate-from-env.sh(sprawdź logi)
Strona czarna / loader bez końca
- Sprawdź konsolę przeglądarki (CSP / YouTube)
- Upewnij się, że
VIDEO_ID_*są poprawne w.env - Po zmianie
default.conflub szablonu:git push+ redeploy
Zmiana konfiguracji po deployu
- Edytuj
.envw Dokploy - Redeploy / restart kontenera (przy starcie ponownie klonuje repo i generuje HTML)
Błąd certyfikatu SSL na telefonie („serwer nie potrafi udowodnić…”)
Diagnoza (stan typowy):
https://slavic-pulse.com— certyfikat Let's Encrypt OKhttps://www.slavic-pulse.com— self-signed (Traefik default, CN=*) → błąd na Androidzie / iPhone / WebView Facebooka
Strona wysyła Strict-Transport-Security: includeSubDomains, więc po wizycie na działającym apexie przeglądarka wymusza HTTPS także na www — a tam cert jest zły → twardy błąd.
Naprawa w Dokploy (zalecane):
- Domains → Add Domain
- Host:
www.slavic-pulse.com, Port:80, HTTPS: włączone, Certificate: letsencrypt - Deploy / poczekaj ~30 s na wystawienie certyfikatu
- Sprawdź:
curl -I https://www.slavic-pulse.com(powinno być HTTP 200 lub 301, bez błędu SSL) - (Opcjonalnie) Advanced → Redirects → www to non-www
Alternatywa w DNS (OVH): zamiast rekordu A dla www ustaw przekierowanie HTTP na https://slavic-pulse.com w panelu domeny.
Facebook / in-app browser: linki w postach powinny wskazywać https://slavic-pulse.com (bez www).
Odnowienie certyfikatu: Let's Encrypt odnawia cert automatycznie przez Traefik. Jeśli cert wygasa, w Dokploy sprawdź logi Traefik i czy port 80 jest dostępny z internetu (HTTP-01 challenge).