Files

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:

  1. Nowa aplikacja (Compose) → wklej docker-compose-example/docker-compose.yml
  2. Wklej .env (na podstawie .env.example) — ustaw FRONTEND_PORT, VIDEO_ID_*, opisy SEO
  3. Domains → dodaj oba hosty (Container Port = 80, HTTPS = Let's Encrypt):
    • slavic-pulse.com
    • www.slavic-pulse.comwymagane — bez tego www dostaje domyślny cert Traefika (CN=*, self-signed) i telefony pokazują „serwer nie potrafi udowodnić tożsamości”
  4. (Opcjonalnie) Advanced → Redirects → preset www → non-www
  5. 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

  1. Start konteneragit clone publicznego repo do /app
  2. generate-from-env.sh — buduje index.html i site.webmanifest ze zmiennych .env
  3. Kopiowanieassets/, default.conf, nginx.conf → nginx
  4. Cleanuprm -rf /app (brak pełnego repo na dysku kontenera)
  5. 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 /app usuwane — 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 w index.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 .env w 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.conf lub szablonu: git push + redeploy

Zmiana konfiguracji po deployu

  1. Edytuj .env w Dokploy
  2. 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 OK
  • https://www.slavic-pulse.comself-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):

  1. DomainsAdd Domain
  2. Host: www.slavic-pulse.com, Port: 80, HTTPS: włączone, Certificate: letsencrypt
  3. Deploy / poczekaj ~30 s na wystawienie certyfikatu
  4. Sprawdź: curl -I https://www.slavic-pulse.com (powinno być HTTP 200 lub 301, bez błędu SSL)
  5. (Opcjonalnie) Advanced → Redirectswww 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).