L'infrastructure LORVA utilise Cloudflare comme gestionnaire DNS pour les deux zones principales :
lorva.dev — services infra, outils internes, site vitrinetaskori.app — services applicatifs Taskori (prod)Tout le trafic HTTP/HTTPS entrant passe par Traefik sur lorva-public (10.10.30.10), lui-même derrière l'IP publique unique du serveur OVH KS-16 : 192.99.35.93.
Les certificats TLS sont générés automatiquement par Traefik via le challenge DNS-01 Cloudflare — jamais HTTP-01, car les domaines sont en proxy Cloudflare (orange cloud), ce qui rend HTTP-01 impossible.
Internet
│
▼
Cloudflare (DNS + proxy orange cloud)
│ 192.99.35.93
▼
Proxmox host (OVH KS-16)
│ pfSense NAT/routing
▼
lorva-public (10.10.30.10) — Traefik
│
├──▶ lorva-infra (10.10.10.10) — GitLab, NetBox, Dockhand...
├──▶ taskori-prod (10.10.20.10) — microservices Taskori
└──▶ local containers — Mailcow, Chatwoot, Wiki.js, Kavita-demo...
Le serveur n'expose jamais son IP publique directement pour HTTP/HTTPS — Cloudflare agit comme proxy et masque l'IP réelle.
Traefik (sur lorva-public) obtient et renouvelle automatiquement les certificats Let's Encrypt via le challenge DNS-01. Ce challenge consiste à créer un enregistrement TXT _acme-challenge.<domaine> dans Cloudflare, prouver le contrôle du domaine à Let's Encrypt, puis supprimer l'enregistrement.
Avantages du DNS-01 dans ce contexte :
*.lorva.dev, *.taskori.app)Dans le docker-compose.yml de Traefik sur lorva-public :
environment:
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
command:
- "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare"
- "--certificatesresolvers.letsencrypt.acme.email=benjamin.chianese@lorva.dev"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
Dans traefik.yml (fichier de config statique) :
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /letsencrypt/acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Le token API Cloudflare est stocké dans :
~/.config/lorva/secrets
Variable : CF_DNS_API_TOKEN
Voir Flatnotes (reference_lorva_secrets) pour la valeur exacte. Ne jamais écrire le token en clair dans un fichier de config ou dans ce wiki.
Permissions requises pour le token DNS-01 :
_acme-challenge)Permissions supplémentaires si gestion Page Rules / Transform Rules :
labels:
- "traefik.enable=true"
- "traefik.http.routers.mon-service.rule=Host(`mon-service.lorva.dev`)"
- "traefik.http.routers.mon-service.entrypoints=websecure"
- "traefik.http.routers.mon-service.tls.certresolver=letsencrypt"
- "traefik.http.services.mon-service.loadbalancer.server.port=3000"
Traefik détecte le nouveau container, résout le certificat via DNS-01 Cloudflare, et commence à router le trafic. Aucune intervention sur Cloudflare n'est nécessaire côté certificat.
| Nom | Type | Cible | Proxied CF | Notes |
|---|---|---|---|---|
lorva.dev |
A | 192.99.35.93 | Non | Site vitrine |
www.lorva.dev |
A | 192.99.35.93 | Non | Site vitrine (redirect → lorva.dev) |
gitlab.lorva.dev |
CNAME | srv.lorva.dev | Oui | GitLab CE |
registry.lorva.dev |
A | 192.99.35.93 | Non | GitLab Container Registry (non proxied — Docker push/pull) |
netbox.lorva.dev |
A | 192.99.35.93 | Oui | NetBox |
dockhand.lorva.dev |
CNAME | srv.lorva.dev | Oui | Dockhand (container updater) |
config.lorva.dev |
A | 192.99.35.93 | Oui | Config-sync (basic auth) |
pve.lorva.dev |
CNAME | srv.lorva.dev | Oui | Proxmox Web UI — https://pve.lorva.dev |
fw.lorva.dev |
CNAME | srv.lorva.dev | Oui | pfSense WebUI |
traefik.lorva.dev |
CNAME | srv.lorva.dev | Non | Traefik Dashboard (accès restreint) |
mail.lorva.dev |
CNAME | srv.lorva.dev | Non | Mailcow (HTTPS + ports directs SMTP/IMAP) |
autoconfig.lorva.dev |
CNAME | srv.lorva.dev | Non | Autoconfig mail (doit être direct pour les clients mail) |
klibri.lorva.dev |
CNAME | klibri.lorva.dev | Non | Kavita demo Klibri |
wiki.lorva.dev |
CNAME | gitlab.lorva.dev | Oui | Wiki.js |
srv.lorva.dev |
A | 192.99.35.93 | Non | Alias interne — cible des CNAMEs |
Enregistrements mail (Mailcow) :
| Nom | Type | Valeur | Notes |
|---|---|---|---|
lorva.dev |
MX | mail.lorva.dev (prio 10) |
Serveur de messagerie |
lorva.dev |
TXT | v=spf1 mx ~all |
SPF |
dkim._domainkey.lorva.dev |
TXT | (clé DKIM Mailcow — voir Flatnotes) | DKIM |
_dmarc.lorva.dev |
TXT | v=DMARC1; p=quarantine; rua=mailto:... |
DMARC |
| Nom | Type | Cible | Proxied CF | Notes |
|---|---|---|---|---|
taskori.app |
A | 192.99.35.93 | Oui | Frontend principal |
www.taskori.app |
A | 192.99.35.93 | Oui | Redirect → taskori.app |
admin.taskori.app |
A | 192.99.35.93 | Oui | Admin Taskori |
manage.taskori.app |
A | 192.99.35.93 | Oui | Manage (gestion équipe/plan) |
portal.taskori.app |
A | 192.99.35.93 | Oui | Portal (accès client) |
project.taskori.app |
A | 192.99.35.93 | Oui | Project (projets/tâches) |
share.taskori.app |
A | 192.99.35.93 | Oui | Share (partage fichiers AES-256) |
ts.taskori.app |
A | 192.99.35.93 | Oui | TS (time tracking / refonte) |
dl.taskori.app |
A | 192.99.35.93 | Oui | DL (téléchargements / desktop sync) |
auth.taskori.app |
A | 192.99.35.93 | Oui | Auth (DNS only — routing via taskori.app) |
support.taskori.app |
CNAME | srv.lorva.dev | Non | Chatwoot (support client) |
Cloudflare cache agressivement les fichiers statiques, ce qui peut poser des problèmes pour dl.taskori.app (Taskori Sync — updater desktop).
Symptome : latest.json retourne une version obsolète après un déploiement — le client desktop ne voit pas la nouvelle version.
Solution — Header Cache-Control sur les réponses du service taskori-dl-web :
# Dans le docker-compose ou la config du serveur qui sert /releases/
# Forcer no-store sur latest.json
Ou via une Transform Rule Cloudflare (requiert un token avec droits Zone — Transform Rules — Edit) :
Si: URI Path commence par /releases/ ET URI Path se termine par latest.json
Alors: Set Header → Cache-Control: no-store, no-cache, must-revalidate
Les fichiers binaires (.AppImage, .exe, .dmg) peuvent rester cachés — seul latest.json (et éventuellement *.sig) doit être en no-store.
Quand un domaine est en proxy Cloudflare (orange cloud) :
192.99.35.93 n'est jamais exposée dans les DNS publics/.well-known/acme-challenge/CF_DNS_API_TOKEN dans Traefik)Certains services nécessitent une connexion directe (non proxiée) et doivent rester en mode DNS only (nuage gris) :
| Domaine | Raison |
|---|---|
registry.lorva.dev |
Docker push/pull — protocole non-HTTP/HTTPS standard |
mail.lorva.dev |
Ports SMTP/IMAP (25, 465, 587, 143, 993, 995) — CF ne proxyifie pas ces ports |
autoconfig.lorva.dev |
Clients mail se connectent directement |
traefik.lorva.dev |
Dashboard interne — pas besoin du proxy CF |
Requiert un token Cloudflare avec droits Zone — Page Rules — Edit.
Exemple : rediriger www.lorva.dev → lorva.dev :
lorva.dev → Rules → Page Ruleswww.lorva.dev/*https://lorva.dev/$1Requiert un token avec droits Zone — Transform Rules — Edit.
Exemple : forcer Cache-Control: no-store sur latest.json :
taskori.app → Rules → Transform Rules → Response Header Modification(http.request.uri.path contains "/releases/") and (http.request.uri.path ends_with "latest.json")Cache-Control → no-store, no-cache, must-revalidate# Lire le token depuis les secrets
source ~/.config/lorva/secrets
# Créer un enregistrement DNS
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "A",
"name": "nouveau-service.lorva.dev",
"content": "192.99.35.93",
"proxied": true,
"ttl": 1
}'
Les IDs de zone (CF_ZONE_ID) sont dans Flatnotes (reference_lorva_secrets).
| Interdit | Raison |
|---|---|
| Utiliser HTTP-01 challenge | Incompatible avec proxy Cloudflare orange cloud |
Ecrire CF_DNS_API_TOKEN en clair |
Toujours référencer Flatnotes ou les variables CI/CD GitLab |
| Utiliser des alias de noms de VMs non LORVA | Utiliser lorva-infra, lorva-public, taskori-prod |
| SSH vers une IP directe depuis lorva-infra | Utiliser les alias SSH (ssh lorva-infra, ssh lorva-public, etc.) |
1. Ecrire le docker-compose du service (avec labels Traefik)
└── traefik.http.routers.xxx.tls.certresolver=letsencrypt
2. Créer l'enregistrement DNS dans Cloudflare
└── A/CNAME → 192.99.35.93, proxied=true (ou false selon le cas)
3. Déployer via GitLab CI (push → pipeline → runner → docker compose up)
└── Ne jamais redémarrer manuellement — les runners GitLab gèrent le déploiement
4. Traefik détecte le container, déclenche DNS-01 via CF_DNS_API_TOKEN
└── Let's Encrypt émet le certificat (~30s-2min)
5. Vérifier
curl -I https://nouveau-service.lorva.dev
# HTTP/2 200 + certificat Let's Encrypt valide
| Sujet | Où trouver |
|---|---|
Token CF_DNS_API_TOKEN |
Flatnotes : reference_lorva_secrets |
| IDs de zone Cloudflare | Flatnotes : reference_lorva_secrets |
| Clés DKIM Mailcow | Flatnotes : section Mailcow |
| Config Traefik complète | lorva-public:/opt/traefik/traefik.yml |
| Secrets infra LORVA | ~/.config/lorva/secrets sur lorva-public |
| Architecture infra complète | Flatnotes : taskori-infra, project_lorva_infra |
| Proxmox Web UI | https://pve.lorva.dev |