[vibe](../../README.md) > [Guidebooks](../README.md) > [Lab ecosystem](README.md) > **03 · cms** # 03 · cms > **Status:** ✅ Active > **Last Updated:** 2026-06-23 > **Upstream:** [01 · factory](01-factory.md) > **Related:** [02 · tools](02-tools.md) · [secrets-and-vault.md](secrets-and-vault.md) The [`cms` repo](https://gitea.arcodange.lab/arcodange-org/cms) is the **public-facing site** of the lab: a Nuxt static site served at **`arcodange.fr`**, plus the OpenTofu that owns its Cloudflare edge and its Zoho email. It is the one app whose primary audience is the open Internet, so it ties together the public-DNS, tunnel, CAPTCHA, and email plumbing. ## The Nuxt site | Aspect | Detail | |---|---| | App | Static **Nuxt** site | | Chart | [`chart/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/chart) — Helm chart, deployed as ArgoCD app **`cms`** into the `cms` namespace | | Image | Built in CI to the Gitea registry; ArgoCD **Image Updater** tracks `gitea.arcodange.lab/arcodange-org/cms:latest` with the **digest** strategy (see [01 · factory](01-factory.md)) | | Hostname | `arcodange.fr` (public) | ## Cloudflare edge ([`cloudflare/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/cloudflare)) OpenTofu (state in cloud object storage) manages the `arcodange.fr` zone. The domain is **registered at OVH** (factory's [`iac/ovh.tf`](../../../iac/ovh.tf) grants the CMS an OVH OAuth2 client to edit nameservers) but its **DNS is delegated to Cloudflare**. The Cloudflare API token + account ID are pushed into the CMS Gitea repo as action secrets and mirrored into Vault by factory's [`iac/cloudflare.tf`](../../../iac/cloudflare.tf). | Cloudflare object | Purpose | |---|---| | Zone `arcodange.fr` | Public DNS for the site + email records | | Cloudflare **Pages** option | Static-hosting alternative for the Nuxt build | | **Cloudflared** Zero-Trust tunnel | Exposes **internal Traefik** to the Internet without opening home-LAN ports | | **Turnstile** CAPTCHA | Bot challenge on forms; wired to **CrowdSec** for decisioning | The Cloudflared tunnel token and Turnstile secret are stored in **Vault** (see [secrets-and-vault.md](secrets-and-vault.md)); the Turnstile → CrowdSec link is the public-edge guard documented in [02 · tools](02-tools.md). ## Zoho email ([`zoho/`](https://gitea.arcodange.lab/arcodange-org/cms/src/branch/main/zoho)) Sets up email for `arcodange.fr`: org/account lookup via the Zoho API + shell scripts, the full DNS authentication record set, and the public aliases. | DNS record | Role | |---|---| | CNAME (verify) | Domain ownership verification | | **MX** | Mail routing to Zoho | | **SPF** | Authorized senders | | **DKIM** | Outbound signing | | **DMARC** | Alignment + reporting policy | | **BIMI** | Brand logo in inboxes | Seven aliases are provisioned: **bonjour, contact, analytics, books, abonnements, helloworld, bureaux**. ## Public request + email path ```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 CF["Cloudflare
DNS + Turnstile"]:::edge TUN["Cloudflared tunnel"]:::edge TRAEFIK["internal Traefik"]:::proc CS["CrowdSec bouncer"]:::proc CMS["cms pod (Nuxt)
arcodange.fr"]:::proc MAIL(["Sender"]):::edge ZOHO["Zoho
MX / SPF / DKIM / DMARC / BIMI"]:::store USER --> CF -- "Turnstile challenge" --> TUN --> TRAEFIK --> CS --> CMS MAIL -- "MX lookup arcodange.fr" --> ZOHO ``` 1. A **visitor** resolves `arcodange.fr` through **Cloudflare** DNS; form submissions hit a **Turnstile** challenge. 2. Traffic enters the home LAN through the **Cloudflared** Zero-Trust tunnel — no home-LAN ports are opened. 3. The tunnel lands on **internal Traefik**, which routes through the **CrowdSec** bouncer (fed Turnstile/decision signals) to the **`cms`** Nuxt pod. 4. Separately, **email** to `arcodange.fr` follows the **MX** record to **Zoho**, with **SPF/DKIM/DMARC/BIMI** authenticating and presenting the mail; the seven aliases land there. ## Cross-references - [Lab ecosystem hub](README.md) — the whole-lab map. - [01 · factory](01-factory.md) — the ArgoCD app `cms`, and `iac/cloudflare.tf` / `iac/ovh.tf` that grant the CMS its Cloudflare token and OVH nameserver-edit rights. - [02 · tools](02-tools.md) — **CrowdSec** (the Traefik bouncer the Turnstile challenge feeds). - [secrets-and-vault.md](secrets-and-vault.md) — the Cloudflared tunnel token and Turnstile/Cloudflare secrets stored in Vault. - Repo: [arcodange-org/cms](https://gitea.arcodange.lab/arcodange-org/cms).