⏱ Temps de lecture : 7 min · 1323 mots
Déployer un blog WordPress piloté par Claude Code
$ cat /var/log/blog-deployment.log | head -1
[2026-04-05 15:20:01] Projet initialisé. L'IA prend les commandes.
Ce blog que tu es en train de lire n’a pas été monté comme les autres. Il est piloté par une IA. Claude Code — l’assistant en ligne de commande d’Anthropic — gère la rédaction des articles, la génération des images, et la publication dans WordPress. Mon rôle : donner un sujet, relire, et cliquer sur « Publier ».
Voici comment tout ça tient debout.
L’idée
J’en avais marre de ne jamais documenter ce que je fais. Des heures passées à résoudre des problèmes d’infra, et rien de noté. La solution classique — « je monterai un blog un jour » — n’a jamais fonctionné parce que le goulot d’étranglement, c’est la rédaction.
L’idée : déléguer le travail répétitif (recherche, premier jet, images, publication) à une IA, et ne garder que la partie qui compte — la validation technique et l’angle éditorial.
Le stack
Internet ──→ Routeur (OpenWRT) ──→ NPM (443/SSL) ──→ WordPress (Docker)
│
TrueNAS SCALE
| Composant | Techno | Rôle |
|---|---|---|
| CMS | WordPress 6 + MariaDB 11 | Hébergement du contenu |
| Conteneurisation | Docker Compose | Isolation des services |
| Hébergement | TrueNAS SCALE | NAS qui fait tout tourner |
| Reverse proxy | Nginx Proxy Manager | Terminaison SSL + routing |
| SSL | Let’s Encrypt (DNS challenge) | HTTPS automatique |
| DNS | IONOS API | Enregistrement A automatisé |
| Images IA | FLUX.2-dev sur RTX 5090 | Génération locale |
| Orchestrateur | Claude Code | Rédaction + publication |
| Versionnement | Gitea (self-hosted) | Tout est dans le repo |
Phase 1 — Le repo Gitea
Tout commence par un repo. Claude Code l’a créé via l’API Gitea et y a poussé la structure complète :
blog-tech/
├── docker-compose.yml
├── .env.example
├── scripts/
│ ├── 01-setup-dns.sh
│ ├── 02-setup-wordpress.sh
│ ├── 03-setup-npm.sh
│ ├── 04-setup-wp-plugins.sh
│ ├── 05-setup-wp-user.sh
│ ├── publish.py
│ ├── generate-image-flux.py
│ └── generate-image-nanob.py
├── config/
├── content/
│ ├── drafts/
│ └── published/
├── images/
├── theme/
│ └── custom-terminal.css
└── docs/
Les secrets (mots de passe, tokens API) ne sont jamais dans le repo — tout passe par un .env gitignored.
Phase 2 — WordPress sur Docker
Le docker-compose.yml est minimal :
services:
db:
image: mariadb:11
container_name: blog-tech-db
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: blog_tech
MYSQL_USER: blog_user
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- ./db_data:/var/lib/mysql
wordpress:
image: wordpress:6-php8.3-apache
container_name: blog-tech-wp
depends_on:
- db
ports:
- "8081:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: blog_tech
WORDPRESS_DB_USER: blog_user
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
volumes:
- ./wp_data:/var/www/html
Déployé sur TrueNAS dans /mnt/V2TB/docker/blog-tech/. Un docker compose up -d et c’est lancé.
La configuration WordPress est faite via WP-CLI directement dans le conteneur :
# Installation
docker exec -u www-data blog-tech-wp wp core install \
--url="https://blog.artyy.me" \
--title="~/blog-tech" \
--admin_user="admin" \
--admin_email="marc@example.com" \
--locale=fr_FR
# Permaliens propres
docker exec -u www-data blog-tech-wp wp rewrite structure '/%postname%/'
# Plugins essentiels
docker exec -u www-data blog-tech-wp wp plugin install \
wordpress-seo \
syntax-highlighting-code-block \
wp-fastest-cache \
limit-login-attempts-reloaded \
--activate
Phase 3 — DNS automatisé via IONOS
Un simple appel API pour créer l’enregistrement A :
curl -X POST "https://api.hosting.ionos.com/dns/v1/zones/${ZONE_ID}/records" \
-H "X-API-Key: ${IONOS_API_KEY}" \
-d '[{
"name": "blog.artyy.me",
"type": "A",
"content": "${PUBLIC_IP}",
"ttl": 3600
}]'
Propagation DNS : instantanée chez IONOS. En moins de 10 secondes, le sous-domaine pointait vers la bonne IP.
Phase 4 — Reverse proxy et SSL
Nginx Proxy Manager gère le routing et le certificat Let’s Encrypt :
blog.artyy.me→<IP_NAS>:8081(WordPress)- SSL via DNS challenge (IONOS provider)
- Force SSL + HTTP/2 + HSTS
- Block exploits activé
xmlrpc.phpbloqué en 403
La config a été poussée via l’API NPM — pas besoin de toucher l’interface.
Phase 5 — Le thème Terminal Vibes
Le blog devait avoir un look de terminal. Un CSS custom chargé via un micro-plugin WordPress :
:root {
--bg-primary: #0d1117;
--text-primary: #c9d1d9;
--green: #3fb950;
--border: #30363d;
}
body {
background-color: var(--bg-primary) !important;
font-family: 'JetBrains Mono', monospace !important;
}
h1::before { content: "# "; color: var(--green); }
h2::before { content: "## "; color: var(--green); }
.site-title::after {
content: "█";
animation: blink 1s step-end infinite;
color: var(--green);
}
Le curseur clignotant dans le titre du site — c’est le genre de détail qui fait plaisir.
Phase 6 — Génération d’images avec FLUX.2
Les images hero sont générées par FLUX.2-dev de Black Forest Labs, qui tourne en local sur une RTX 5090 (32 Go VRAM). Pas de cloud, pas de coût par image.
Le pipeline :
from diffusers import DiffusionPipeline
import torch
pipe = DiffusionPipeline.from_pretrained(
"black-forest-labs/FLUX.2-dev",
torch_dtype=torch.bfloat16
)
pipe.enable_sequential_cpu_offload()
image = pipe(
prompt="dark terminal aesthetic, cyberpunk...",
width=1024, height=576,
num_inference_steps=28
).images[0]
Le modèle fait ~24 Go — trop gros pour tenir entièrement en VRAM. L’astuce : enable_sequential_cpu_offload() ne charge en GPU que le composant actif (text encoder, puis transformer, puis VAE). Résultat : ~3 minutes par image, qualité excellente.
Phase 7 — Le workflow de publication
C’est là que Claude Code entre en jeu. Le workflow complet :
Marc donne un sujet
│
▼
Claude Code : Recherche + Rédaction (Markdown)
│
▼
Claude Code : Génération image hero (FLUX.2)
│
▼
Claude Code : Upload image → WP media library
│
▼
Claude Code : Conversion MD → HTML → Brouillon WP
│
▼
Claude Code : Commit dans Gitea
│
▼
Marc : Relecture → Publication manuelle
│
▼
Claude Code : Archivage drafts/ → published/
La publication passe par l’API REST de WordPress avec un utilisateur dédié (claude-code, rôle éditeur) et un Application Password. Chaque article est versionné en Markdown dans Gitea avant d’être converti en HTML pour WordPress.
L’humain garde le contrôle : Claude Code ne publie jamais directement. Tout passe en brouillon, je relis, j’ajuste si nécessaire, et je clique sur Publier.
Sécurité
Quelques mesures en place :
- OpenWRT en front : seuls les ports 80/443 sont forwardés
- SSL forcé + HSTS sur tous les sites
- xmlrpc.php bloqué au niveau du reverse proxy
- Limit Login Attempts : anti-brute force sur wp-login
- Block exploits activé dans NPM
- Pas de secrets dans le repo : tout est en variables d’environnement
- Gitea, NPM admin, Home Assistant : inaccessibles depuis Internet
Ce que ça coûte
| Poste | Coût |
|---|---|
| Domaine (artyy.me) | Déjà payé |
| Sous-domaine blog.artyy.me | Gratuit |
| Hébergement (TrueNAS) | Déjà en place |
| SSL (Let’s Encrypt) | Gratuit |
| FLUX.2-dev | Gratuit (Apache 2.0, non-commercial) |
| Claude Code | Abonnement Anthropic |
Le seul coût récurrent est l’abonnement Claude. Tout le reste tourne sur l’infra existante.
Temps de mise en place
Du repo Gitea vide au premier article publié avec image hero : moins de 2 heures. Et une bonne partie de ce temps, c’est le téléchargement du modèle FLUX.2 (~24 Go).
Conclusion
$ uptime
blog-tech: up since 2026-04-05, articles: 2, images: generated locally
$ echo "L'IA fait le gros du travail. L'humain fait les choix."
L'IA fait le gros du travail. L'humain fait les choix.
Ce n’est pas un blog auto-piloté. C’est un blog assisté. La différence est importante : l’IA accélère la production, mais chaque mot publié passe par un humain qui connaît son sujet.
Le code source complet est dans le repo Gitea. Si tu veux reproduire ce setup, tout est là — scripts, config, docker-compose, CSS.
Et si tu te demandes : oui, cet article aussi a été rédigé avec l’aide de Claude Code. Meta, non ?
Stack complet : WordPress 6 / Docker / TrueNAS SCALE / NPM / Let’s Encrypt / IONOS / FLUX.2-dev / Claude Code / Gitea

Laisser un commentaire