diff --git a/CLAUDE.md b/CLAUDE.md index 442fdd0..9e5bf34 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,13 +16,16 @@ sitemap e `robots.txt` dinamici, ricerca, e i test (nessun framework ancora conf ## Architettura ```text -Browser → Caddy ─┬─ /admin, /uploads → Strapi 5 → PostgreSQL - └─ tutto il resto → Nuxt 4 (SSR) → REST Strapi +Browser → Caddy ─┬─ /admin e i path dei plugin Strapi → Strapi 5 → PostgreSQL + └─ tutto il resto → Nuxt 4 (SSR) → REST Strapi ``` -Caddy instrada per **path**, non per sottodominio: `PUBLIC_DOMAIN` serve sia il sito che, -sotto `/admin` e `/uploads`, il pannello Strapi (Strapi 5 annida l'intera admin UI e la sua -API sotto `/admin`, senza toccare `/api`). Un solo dominio, un solo certificato TLS. +Caddy instrada per **path**, non per sottodominio: `PUBLIC_DOMAIN` serve sia il sito che il +pannello Strapi. Ogni plugin Strapi monta la propria API admin sul proprio path di primo +livello, non tutto sotto `/admin` (es. `/content-manager`, `/upload`, `/i18n`...): l'elenco +completo dei prefissi da instradare a Strapi vive nel `Caddyfile`. Se aggiungi un plugin +Strapi, aggiungi il suo prefisso lì. Niente di questo tocca `/api`, riservato agli endpoint +Nitro del frontend. Un solo dominio, un solo certificato TLS. - Strapi è la **sola** fonte di verità editoriale. Niente altro backend (no Express/Nest/Fastify): se serve logica server, sta in Nitro (`frontend/server/`) o in un controller Strapi. diff --git a/README.md b/README.md index 701217b..f1a21f4 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ Blog platform: a public website built with Nuxt, and a private Strapi CMS where articles are written. Everything runs behind Caddy via Docker Compose. ```text -Browser → Caddy ─┬─ /admin, /uploads → Strapi (CMS) → PostgreSQL - └─ everything else → Nuxt (website) +Browser → Caddy ─┬─ /admin and Strapi's plugin paths → Strapi (CMS) → PostgreSQL + └─ everything else → Nuxt (website) ``` There are no front-end accounts: sign-up is disabled and only administrators write @@ -94,7 +94,7 @@ reachable inside the Docker network — do not publish their ports. | `PUBLIC_DOMAIN` | `example.com` | | `ACME_EMAIL` | a mailbox you read — Let's Encrypt sends expiry warnings there | | `PUBLIC_SITE_URL` | `https://example.com` | -| `PUBLIC_STRAPI_URL` | `https://example.com` — same origin, Caddy proxies `/admin` and `/uploads` to Strapi | +| `PUBLIC_STRAPI_URL` | `https://example.com` — same origin, Caddy proxies `/admin` and Strapi's other plugin paths there (see `caddy/Caddyfile`) | | `STRAPI_URL` | leave it as `http://cms:1337` — internal address, never public | Then generate **fresh** secrets on that machine with the same loop as in development — @@ -111,9 +111,9 @@ already ignored. docker compose up -d --build ``` -This time Caddy is included: it serves both the website and, under `/admin` and -`/uploads`, the CMS on `PUBLIC_DOMAIN`, obtains and renews the TLS certificate on its own, -and adds HSTS and the other security headers. +This time Caddy is included: it serves both the website and, under `/admin` and Strapi's +other plugin paths, the CMS on `PUBLIC_DOMAIN`, obtains and renews the TLS certificate on +its own, and adds HSTS and the other security headers. **5. Create the administrator account** at `https://example.com/admin`, immediately, before anyone else finds the URL — the first visitor to that form is the one who gets the diff --git a/caddy/Caddyfile b/caddy/Caddyfile index 5e7fae4..5e1e6aa 100644 --- a/caddy/Caddyfile +++ b/caddy/Caddyfile @@ -16,11 +16,18 @@ import security_headers encode zstd gzip - # /admin and /uploads go to Strapi; everything else to the frontend. - # Strapi 5 nests the whole admin panel (UI + its own API) under /admin, - # so this single prefix is enough - it never touches /api, which stays - # reserved for the frontend's own Nitro endpoints. - @cms path /admin* /uploads* + # Strapi mounts each of its (and its plugins') admin APIs at its own + # top-level path, not all under /admin - the admin panel's dashboard + # widgets, media library, i18n, etc each call their own plugin prefix. + # This list is every @strapi/* package in cms/package.json plus the + # core-bundled plugins (content-manager, content-type-builder, upload, + # i18n, email, content-releases, review-workflows). Adding a new Strapi + # plugin later means adding its prefix here too. + # None of this touches /api, reserved for the frontend's own Nitro + # endpoints. + @cms path /admin* /content-manager* /content-type-builder* /upload*\ + /i18n* /email* /content-releases* /review-workflows*\ + /users-permissions* /cloud* handle @cms { # Uploaded media can be large; Strapi's own limit still applies. request_body {