Dokploy (Docker)
Web je server-rendered pomocí Astro Node adaptéru a Kafe-CMS, takže se
nasazuje jako dlouhoběžící Node server, nikoli statické soubory. Repozitář přináší
vícefázový Dockerfile, který sestaví samostatný server (dist/server/entry.mjs).
Nasazení na Dokploy
Section titled “Nasazení na Dokploy”- Pushněte repozitář na GitHub.
- V Dokploy vytvořte Application z repozitáře pomocí Dockerfile buildu.
- Připojte perzistentní svazek na
/app/data. Ten drží SQLite databázi (kafecms.db) a všechny lokální nahrané soubory, takže obsah přežije redeploye. - Nastavte proměnné prostředí (viz Proměnné prostředí):
SITE_URL,S3_*přihlašovací údaje Cloudflare R2 a případné volitelné analytické klíče. - Vystavte port 4321 a nasměrujte na službu svou doménu.
- Nasaďte. Na čerstvém svazku entrypoint automaticky naseeduje obsah (níže).
Cloudflare R2 média
Section titled “Cloudflare R2 média”V produkci se média ukládají do Cloudflare R2 přes jeho S3-kompatibilní API. Vytvořte
R2 bucket a S3 API token, poté nastavte S3_ENDPOINT, S3_BUCKET,
S3_ACCESS_KEY_ID a S3_SECRET_ACCESS_KEY. Pokud je S3_BUCKET nenastavený, Kafe-CMS spadne
zpět na úložiště v lokálním souborovém systému pod ./data/uploads.
Uploady jdou PUT přímo do R2 z prohlížeče přes presigned URL, takže bucket potřebuje
CORS politiku povolující origin vašeho webu (GET, PUT, HEAD). Bucket může zůstat
privátní — Kafe-CMS servíruje média přes vlastní proxy routu
(/kafecms/api/media/file/<key>), která streamuje objekty z R2, takže URL vždy vypadají
same-origin a S3_PUBLIC_URL není potřeba. Viz
Proměnné prostředí → Úložiště médií pro
přesnou CORS politiku a detaily.
Zapnutí komprese (gzip / Brotli)
Section titled “Zapnutí komprese (gzip / Brotli)”Astro Node adaptér servíruje HTML, CSS a JS nekomprimované — nemá vestavěnou kompresi. To samo o sobě sráží Lighthouse Performance dolů (~53 KB stylesheet se posílá celý, což nafukuje FCP/LCP), i když je server rychlý. Komprimujte na Traefik reverzní proxy, kterou Dokploy už provozuje.
V Dokploy: otevřete aplikaci → Advanced → Traefik a přidejte middleware compress,
poté ho připojte k routeru aplikace. Dynamická konfigurace vypadá takto:
http: middlewares: site-compress: compress: # Nekomprimujte Server-Sent Events — živý náhled Kafe-CMS je používá. excludedContentTypes: - text/event-stream routers: # Přidejte middleware k existujícímu routeru, který Dokploy pro tuto aplikaci vygeneroval: <existing-router-name>: middlewares: - site-compressPo uložení ověřte pomocí curl -sI -H "Accept-Encoding: br,gzip" https://your-domain/
— odpověď by měla obsahovat content-encoding: br (nebo gzip). To typicky posune
Lighthouse Performance z ~90 na ~100, protože render-blocking CSS a JS se teď přenášejí
za zlomek své velikosti.
Veřejné marketingové stránky posílají téměř žádný JavaScript (interaktivní části jsou prosté Astro + drobné inline skripty), takže komprese je hlavní zbývající páka. Těžké React bundly, které můžete vidět pod
/_astro, patří administraci Kafe-CMS a načítají se jen na routách/kafecms.
Bezpečnostní hlavičky (CSP / HSTS)
Section titled “Bezpečnostní hlavičky (CSP / HSTS)”Aplikace přináší middleware (src/middleware/security-headers.ts), který posílá skutečné
bezpečnostní hlavičky na veřejném webu: striktní Content-Security-Policy, plus
Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options,
Referrer-Policy, Permissions-Policy a Cross-Origin-Opener-Policy. CSP je
bez nonce a bez 'unsafe-inline' pro skripty — bufferuje každou HTML odpověď a
počítá SHA-256 hash pro každý inline <script>, který je skutečně vyemitovaný (dark-mode
bootstrap, analytické snippety, …) a automaticky whitelistuje externí skriptové originy, takže
zůstává striktní bez ruční údržby. Administrace Kafe-CMS (/kafecms) je ponechána vlastní
CSP. Nastavením DISABLE_SECURITY_HEADERS=1 middleware vypnete (např. pokud váš edge
tyto hlavičky už nastavuje).
Poznámka k pokrytí: Astro middleware běží jen pro server-rendered routy. Prerenderované Starlight stránky
/docs,404a statické assety pod/_astrojsou servírovány přímo Node adaptérem a middleware obcházejí. Pro plošné pokrytí (včetně těchto rout) nastavte hlavičky i na vrstvě Traefik — to je doporučené produkční nastavení:
http: middlewares: site-headers: headers: stsSeconds: 63072000 stsIncludeSubdomains: true stsPreload: true contentTypeNosniff: true referrerPolicy: strict-origin-when-cross-origin frameDeny: true permissionsPolicy: "camera=(), microphone=(), geolocation=(), browsing-topics=()" routers: <existing-router-name>: middlewares: - site-compress - site-headersCSP per-aplikaci ponechte middlewaru (liší se stránku od stránky), nebo zde replikujte statickou CSP, pokud chcete, aby proxy vlastnila vše.
Databáze, migrace a seedování
Section titled “Databáze, migrace a seedování”SQLite databáze je runtime stav a necommituje se do gitu — žije na svazku
/app/data. Při nasazení:
- Server spouští schema migrace automaticky při prvním požadavku, čímž vytvoří databázi a tabulky na svazku.
docker-entrypoint.shkontejneru spustíkafecms seedzeseed/seed.jsonjen tehdy, když ještě žádná databáze neexistuje (čerstvý svazek), takže první deploy naběhne naplněný a redeploye nikdy nepřepíšou vaše data.
Pro ruční seedování nebo re-seedování (např. mimo Docker):
pnpm exec kafecms seed --database data/kafecms.db --uploads-dir data/uploadsPoté se obsah upravuje přes administraci na /kafecms/admin (při první návštěvě vytvořte
účet vlastníka) a nevyžaduje žádný redeploy.
Lokální Docker test
Section titled “Lokální Docker test”docker build -t astro-kafecms .docker run --rm -p 4321:4321 -v "$PWD/data:/app/data" astro-kafecms