# Agencja AI - 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-agencja-ai-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 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): - `agencja-ai.com` - `www.agencja-ai.com` ← **wymagane** — 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`. 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 kontenera** — `git clone` publicznego repo do `/app` 2. **`generate-from-env.sh`** — buduje `index.html` i `site.webmanifest` ze zmiennych `.env` 3. **Kopiowanie** — `assets/`, `default.conf`, `nginx.conf` → nginx 4. **Cleanup** — `rm -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. `8081`) | | `SITE_TITLE`, `SITE_BASE_URL`, `SITE_DESCRIPTION` | Meta i SEO | | `FACEBOOK_DESCRIPTION`, `TWITTER_DESCRIPTION` | Opisy social media | | `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 | ## Lokalny development ```bash cp .env.example .env ./dev.sh up # Strona na http://localhost:${FRONTEND_PORT} (domyślnie 8081) # Edytuj .env → ./dev.sh config → F5 w przeglądarce ``` Produkcyjny build lokalnie: ```bash docker compose up -d --build ``` ## 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 ```bash # Strona działa curl -sI https://agencja-ai.com/ | head -5 # Wrażliwe pliki niedostępne (404) curl -sI https://agencja-ai.com/.env | grep HTTP curl -sI https://agencja-ai.com/generate-from-env.sh | grep HTTP curl -sI https://agencja-ai.com/random-path | grep HTTP # Nagłówki bezpieczeństwa curl -sI https://agencja-ai.com/ | grep -iE 'content-security-policy|referrer-policy|permissions-policy' # W kontenerze (na serwerze) docker logs agencja-ai-com-frontend --tail 30 docker exec agencja-ai-com-frontend ls /app 2>&1 # powinno: No such file docker exec agencja-ai-com-frontend head -3 /usr/share/nginx/html/index.html ``` ## Rozwiązywanie problemów ### Kontener `Restarting` / unhealthy ```bash docker logs agencja-ai-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://agencja-ai.com` — certyfikat Let's Encrypt OK - `https://www.agencja-ai.com` — **self-signed** (Traefik default, CN=`*`) → błąd na Androidzie / iPhone / WebView Facebooka **Naprawa w Dokploy (zalecane):** 1. **Domains** → **Add Domain** 2. Host: `www.agencja-ai.com`, Port: `80`, HTTPS: włączone, Certificate: **letsencrypt** 3. Deploy / poczekaj ~30 s na wystawienie certyfikatu 4. Sprawdź: `curl -I https://www.agencja-ai.com` (powinno być HTTP 200 lub 301, bez błędu SSL) 5. (Opcjonalnie) **Advanced → Redirects** → **www to non-www** **Facebook / in-app browser:** linki w postach powinny wskazywać `https://agencja-ai.com` (bez www).