Two code-grounded tree-docs guidebooks under vibe/guidebooks/, drilling into the lab-ecosystem 02-tools and 03-cms pages (bidirectional): - tools/ : hub + components.md (Vault+VSO, Prometheus, Grafana, CrowdSec, pgbouncer, Redis/KeyDB, Plausible, ClickHouse; pgcat/tool as Tier-2) + secrets-and-vso.md (Vault engines/auth, the app_roles/app_policy modules = the <app> join-key machinery, VSO CRDs, secret-paths inventory). - cms/ : hub + site.md (Nuxt + dual Pages/k3s deploy) + cloudflare.md (zone via OVH->CF, Pages, cloudflared tunnel, Turnstile, R2 state) + zoho-email.md (OAuth, MX/SPF/DKIM/DMARC/BIMI, the 7 aliases). Sibling-repo code linked via full gitea URLs; vibe-internal links bidirectional. Reconciled the cloudflared tunnel token path to kvv2 cms/cloudflared (the chart VaultStaticSecret is kv-v2; the kvv1 tofu reference is a commented-out stub). 6 mermaid diagrams MCP-validated; zero dead links. Lab Cartographer cohort. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
5.3 KiB
Markdown
76 lines
5.3 KiB
Markdown
[vibe](../../README.md) > [Guidebooks](../README.md) > **CMS**
|
|
|
|
# CMS
|
|
|
|
> **Status:** ✅ Active
|
|
> **Last Updated:** 2026-06-23
|
|
> **Upstream:** [lab-ecosystem 03 · cms](../lab-ecosystem/03-cms.md)
|
|
> **Downstream:** [Site (Nuxt)](site.md) · [Cloudflare](cloudflare.md) · [Zoho email](zoho-email.md)
|
|
> **Related:** [tools CrowdSec](../tools/components.md) · [secrets-and-vault concept](../lab-ecosystem/secrets-and-vault.md) · [tofu CI flow](../factory-provisioning/opentofu/ci-apply-flow.md) · [safe-env ADR](../../ADR/0001-safe-prod-like-environment.md)
|
|
|
|
This guidebook maps the [`cms` repo](https://gitea.arcodange.lab/arcodange-org/cms) — the one app in the lab whose primary audience is the open Internet. It serves the public site **arcodange.fr** and owns the OpenTofu that wires its Cloudflare edge, its Cloudflared tunnel into the cluster, its Turnstile CAPTCHA, and its Zoho email.
|
|
|
|
## Two faces of one repo
|
|
|
|
The `cms` repo holds two distinct concerns that share a domain but live in different directories.
|
|
|
|
| Face | Where | What it is |
|
|
|---|---|---|
|
|
| **The SITE** | repo root ([`app/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/app), [`content/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/content), [`chart/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/chart)) | A **Nuxt 4** application (Nuxt Content + Nuxt Studio) built to static output and deployed **two ways**: to **Cloudflare Pages** (public `arcodange.fr` / `www`) and into **k3s** via a Helm chart (ArgoCD app **`cms`**) reachable through the Cloudflared tunnel (e.g. `cms-rec.arcodange.fr`, `www.arcodange.lab`) |
|
|
| **The IaC** | [`cloudflare/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/cloudflare) | **OpenTofu** managing the `arcodange.fr` zone (registered at OVH, DNS delegated to Cloudflare), Cloudflare **Pages**, the **Cloudflared** Zero-Trust tunnel into internal Traefik, a **Turnstile** CAPTCHA feeding CrowdSec, and **Zoho** email |
|
|
|
|
The site is *what visitors see*; the IaC is *how they reach it and how mail flows*. Both deploy from the same Gitea repo through Gitea Actions.
|
|
|
|
## Public request + email flow
|
|
|
|
```mermaid
|
|
%%{init: {'theme': 'base'}}%%
|
|
flowchart LR
|
|
classDef edge fill:#d97706,stroke:#b45309,color:#fff
|
|
classDef proc fill:#059669,stroke:#047857,color:#fff
|
|
classDef store fill:#7c3aed,stroke:#6d28d9,color:#fff
|
|
|
|
USER(["Visitor"]):::edge
|
|
CFDNS["Cloudflare DNS<br>arcodange.fr zone"]:::edge
|
|
PAGES["Cloudflare Pages<br>(static Nuxt build)"]:::proc
|
|
TUN["Cloudflared tunnel"]:::edge
|
|
TRAEFIK["internal Traefik"]:::proc
|
|
CS["CrowdSec bouncer<br>(Turnstile-backed)"]:::proc
|
|
CMS["cms pod (Nuxt)<br>cms-rec.arcodange.fr"]:::proc
|
|
MAIL(["Sender"]):::edge
|
|
ZOHO["Zoho<br>MX / SPF / DKIM / DMARC / BIMI"]:::store
|
|
|
|
USER --> CFDNS
|
|
CFDNS -- "arcodange.fr / www" --> PAGES
|
|
CFDNS -- "*.arcodange.fr" --> TUN
|
|
TUN --> TRAEFIK --> CS --> CMS
|
|
MAIL -- "MX lookup arcodange.fr" --> ZOHO
|
|
```
|
|
|
|
1. A **visitor** resolves a hostname under `arcodange.fr` through **Cloudflare DNS** (the zone OpenTofu manages).
|
|
2. The apex and `www` records (proxied CNAMEs) land on **Cloudflare Pages**, which serves the static Nuxt build directly from the edge.
|
|
3. Wildcard `*.arcodange.fr` hostnames route through the **Cloudflared** Zero-Trust tunnel — no home-LAN ports are opened — onto **internal Traefik**, which passes the request through the **CrowdSec** bouncer (its CAPTCHA challenge backed by Turnstile) to the in-cluster **`cms`** Nuxt pod (e.g. `cms-rec.arcodange.fr`).
|
|
4. Separately, **email** to `arcodange.fr` follows the **MX** record to **Zoho**, with **SPF/DKIM/DMARC/BIMI** authenticating and presenting the mail.
|
|
|
|
## Index
|
|
|
|
| Page | What it maps | Status |
|
|
|---|---|---|
|
|
| [Site (Nuxt)](site.md) | The Nuxt 4 app: Nuxt Content + Studio, static build, the dual deploy to Cloudflare Pages and to k3s via the Helm chart / ArgoCD app `cms` | ✅ Active |
|
|
| [Cloudflare](cloudflare.md) | The `cloudflare/` OpenTofu: zone (OVH-registered, CF-delegated), Pages, the Cloudflared tunnel into Traefik, and the Turnstile CAPTCHA for CrowdSec | ✅ Active |
|
|
| [Zoho email](zoho-email.md) | Zoho mail IaC: domain verification, MX/SPF/DKIM/DMARC/BIMI records, and the public aliases | ✅ Active |
|
|
|
|
## Maintenance rule
|
|
|
|
> [!IMPORTANT]
|
|
> **If any component documented in this guidebook is altered, update the page describing it in the same change.** A reference map that drifts from the real `cms` repo sends readers and agents down dead paths. The PR that changes a component is the PR that updates its CMS guidebook page.
|
|
|
|
## Cross-references
|
|
|
|
- [lab-ecosystem 03 · cms](../lab-ecosystem/03-cms.md) — the whole-lab view of where `cms` sits among `factory` + `tools`.
|
|
- [tools CrowdSec](../tools/components.md) — the Traefik bouncer the Turnstile challenge feeds for public-edge decisioning.
|
|
- [secrets-and-vault concept](../lab-ecosystem/secrets-and-vault.md) — where the Cloudflared tunnel token, Turnstile secret, and Cloudflare/Zoho/OVH credentials live in Vault.
|
|
- [tofu CI flow](../factory-provisioning/opentofu/ci-apply-flow.md) — the OpenTofu apply pipeline pattern the `cloudflare/` IaC follows in Gitea Actions.
|
|
- [safe-env ADR](../../ADR/0001-safe-prod-like-environment.md) — why public-facing surfaces like this one are isolated from a safe prod-like environment.
|
|
- Repo: [arcodange-org/cms](https://gitea.arcodange.lab/arcodange-org/cms).
|