Main robotique tapant sur un clavier devant un logo WordPress holographique — généré par FLUX.2-dev

Déployer un blog WordPress piloté par Claude Code

⏱ 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.php bloqué 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

Comments

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

~/blog-tech · Marc · Sysadmin Linux · Propulsé par WordPress + Claude Code

Images générées par FLUX.2-dev · Hébergé sur TrueNAS · RSS