Découvrez comment sécuriser un site WordPress en DMZ grâce à Podman rootless : isolation renforcée, images officielles, déploiement automatisé et bonnes pratiques DevSecOps.
Table of Contents
Introduction
De nombreuses organisations hébergent encore leurs sites web dans une DMZ (zone démilitarisée) sur des machines virtuelles classiques.
L’architecture typique repose sur une VM Debian/Ubuntu, avec Apache, PHP et MySQL installés à la main. Cette approche, encore répandue, présente plusieurs limites : mises à jour compliquées, dépendances figées, surfaces d’attaque élevées.
Aujourd’hui, il existe des solutions plus modernes, plus sûres et plus simples à maintenir. Dans cet article, nous allons voir comment moderniser l’hébergement d’un site WordPress en DMZ grâce à Podman rootless et aux images officielles WordPress/MariaDB validées par les éditeurs.
Hébergement legacy en VM : limites et risques
Un hébergement “à l’ancienne” repose généralement sur :
- VM Debian/Ubuntu en DMZ
- Apache + PHP + MySQL installés manuellement
- WordPress téléchargé et mis à jour via son interface
Inconvénients
- Mises à jour fastidieuses (OS + Apache + PHP + MySQL + WordPress).
- Risque de retard dans l’application des patchs de sécurité.
- Surfaces d’attaque multiples (chaque service peut contenir une faille).
- Peu d’automatisation possible.
En DMZ, où la surface d’attaque doit être minimisée, ces limites deviennent critiques.
Modernisation avec Podman rootless
Pourquoi Podman ?
Podman est un moteur de conteneurs Linux, compatible avec Docker, qui fonctionne sans démon root. En mode rootless, chaque utilisateur gère ses propres conteneurs, dans son namespace, sans privilèges administrateur.
Avantages
- Isolation renforcée : exécution rootless avec namespaces Linux.
- Sécurité accrue : pas de démon root exposé.
- Images officielles et signées : WordPress et MariaDB depuis Docker Hub.
- Maintenance simplifiée : mises à jour automatiques (
podman auto-update
). - Intégration systemd : gestion des conteneurs comme des services.
Pourquoi pas Kubernetes ?
Kubernetes est très puissant, mais surdimensionné pour un simple WordPress exposé en DMZ.
Podman est un compromis idéal :
- léger et simple,
- compatible avec YAML/Kube (via
podman generate kube
), - sans la complexité opérationnelle de Kubernetes.
Choisir l’OS hôte pour Podman en DMZ
L’OS hôte doit être :
- léger et minimal (réduire la surface d’attaque),
- maintenu et patché régulièrement,
- supportant Podman rootless nativement.
Recommandations
- Fedora Server ou CentOS Stream / RHEL : Podman est intégré et supporté par Red Hat.
- Debian 12 ou Ubuntu 22.04 LTS : stables, largement utilisés, installation de Podman simple via apt.
- Rocky Linux / AlmaLinux : alternatives RHEL compatibles.
👉 En DMZ, installez uniquement les paquets nécessaires : un hôte minimal réduit la surface d’attaque.
Installation de Podman
Sur Debian 12 / Ubuntu 22.04 LTS
sudo apt update
sudo apt -y install podman podman-compose
Sur CentOS Stream / Rocky / AlmaLinux
sudo dnf -y install podman podman-compose
Vérification
podman --version
podman info
Activer l’exécution rootless
sudo loginctl enable-linger webuser
Cela permet à systemd --user
de gérer les conteneurs, même sans session ouverte.
Tableau comparatif : VM Legacy vs Podman rootless
Critère | Legacy (VM Apache/MySQL) | Podman rootless (WordPress officiel) |
---|---|---|
Surface d’attaque | Large (OS + Apache + PHP + MySQL) | Réduite (containers isolés rootless) |
Mises à jour | Manuelles et fastidieuses | Automatisées via podman auto-update |
Isolation | Processus partagés sur la VM | Namespaces + cgroups rootless |
Complexité | Simple mais rigide | Léger, modulable, plus moderne |
Sécurité en DMZ | Risques élevés | Cloisonnement + images validées |
Évolutivité | Faible | Élevée (pods, compat YAML/Kube) |
Déploiement complet WordPress + MariaDB avec Podman rootless
Pré-requis
- Serveur minimal Debian/Ubuntu en DMZ
- Utilisateur non-root (ex.
webuser
) - Podman et podman-compose installés
1. Préparer l’environnement
sudo -iu webuser
mkdir -p ~/wordpress-stack/{data/wordpress,data/mariadb,secrets,logs}
podman network create wordpress-net
# Génération des secrets
openssl rand -base64 32 > ~/wordpress-stack/secrets/db_root_password
openssl rand -base64 32 > ~/wordpress-stack/secrets/db_user_password
podman secret create db_root_password ~/wordpress-stack/secrets/db_root_password
podman secret create db_user_password ~/wordpress-stack/secrets/db_user_password
2. Fichier Compose (clé en main)
~/wordpress-stack/docker-compose.yml
version: "3.8"
services:
mariadb:
image: docker.io/library/mariadb:11
restart: always
networks: [ wordpress-net ]
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD_FILE: /run/secrets/db_user_password
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
volumes:
- ./data/mariadb:/var/lib/mysql:Z
secrets:
- db_root_password
- db_user_password
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot --password=$$(cat /run/secrets/db_root_password) || exit 1"]
interval: 30s
timeout: 5s
retries: 5
labels:
io.containers.autoupdate: "registry"
read_only: true
tmpfs: ["/tmp","/run"]
cap_drop: [ "ALL" ]
security_opt: [ "no-new-privileges:true" ]
wordpress:
image: docker.io/library/wordpress:6-apache
restart: always
depends_on:
mariadb:
condition: service_healthy
networks: [ wordpress-net ]
environment:
WORDPRESS_DB_HOST: mariadb
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_user_password
WORDPRESS_TABLE_PREFIX: wp_
volumes:
- ./data/wordpress:/var/www/html:Z
secrets:
- db_user_password
ports:
- "8080:80"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/wp-login.php >/dev/null || exit 1"]
interval: 30s
timeout: 5s
retries: 5
labels:
io.containers.autoupdate: "registry"
read_only: true
tmpfs: ["/tmp","/run"]
cap_drop: [ "ALL" ]
security_opt: [ "no-new-privileges:true" ]
networks:
wordpress-net:
external: true
secrets:
db_root_password:
external: true
db_user_password:
external: true
3. Démarrage
cd ~/wordpress-stack
podman-compose up -d
WordPress est accessible sur http://<hôte>:8080
.
En DMZ, utilisez un reverse proxy (Nginx/HAProxy) en frontal avec SSL offloading.
4. Intégration systemd user
~/.config/systemd/user/wordpress-stack.service
[Unit]
Description=WordPress Stack (Podman rootless)
After=network-online.target
[Service]
Type=oneshot
WorkingDirectory=%h/wordpress-stack
ExecStart=/usr/bin/podman-compose up -d
ExecStop=/usr/bin/podman-compose down
RemainAfterExit=yes
[Install]
WantedBy=default.target
Activation :
systemctl --user daemon-reload
systemctl --user enable --now wordpress-stack.service
loginctl enable-linger $(whoami)
5. Mise à jour automatique
systemctl --user enable --now podman-auto-update.timer
Mise à jour forcée :
podman auto-update
Mises à jour majeures : au-delà de podman auto-update
L’option podman auto-update
permet de garder les conteneurs à jour sur leur branche actuelle :
- Exemple :
wordpress:6-apache
→ reçoit automatiquement les patchs de sécurité et mises à jour mineures publiées par WordPress pour la branche 6. - Exemple :
mariadb:11
→ suit les correctifs publiés par les mainteneurs.
👉 Limite : cette approche ne couvre pas les changements de version majeure (ex. WordPress 6 → 7, MariaDB 11 → 12).
Comment gérer les montées de version
- Surveiller les nouvelles releases (notes de version officielles WordPress/MariaDB).
- Modifier le tag dans
docker-compose.yml
:- image: docker.io/library/wordpress:6-apache
+ image: docker.io/library/wordpress:7-apache
- Redéployer après sauvegarde et tests :
podman-compose pull
podman-compose up -d
- Rollback facile si besoin (revenir à l’ancien tag).
Bonnes pratiques
- Utiliser
auto-update
pour rester à jour dans une branche stable. - Planifier des fenêtres de mise à jour contrôlées (ex. trimestrielles) pour les montées de version majeures.
- Vérifier la compatibilité PHP/MySQL avant un bump WordPress.
- Automatiser la détection des nouvelles versions avec un outil comme Renovate ou Watchtower, afin d’être notifié lorsqu’un nouveau tag est disponible.
Sécurisation en DMZ
- Base non exposée : MariaDB uniquement via
wordpress-net
. - Reverse proxy : Nginx/HAProxy avec SSL.
- Images officielles signées : WordPress/MariaDB Docker Hub.
- Isolation : rootless, SELinux,
cap_drop=ALL
. - Mises à jour automatisées : via Podman auto-update.
- Scanning vulnérabilités :
trivy image docker.io/library/wordpress:6-apache
. - Firewall strict : seuls 80/443 exposés.
- Sauvegardes : persistance des volumes
~/wordpress-stack/data/
.
Comparatif visuel : avant / après

[Legacy]
Internet ──> [Firewall DMZ] ──> [VM Debian]
├─ Apache + PHP + WordPress
└─ MySQL
[Modernisé]
Internet ──> [Firewall DMZ] ──> [Host Debian minimal]
├─ Podman rootless (webuser)
│ ├─ WordPress (image officielle)
│ └─ MariaDB (isolé)
└─ Reverse Proxy (SSL, filtrage)
FAQ (SEO)
Pourquoi utiliser Podman rootless pour WordPress en DMZ ?
Parce qu’il renforce l’isolation (pas de démon root), réduit la surface d’attaque et simplifie les mises à jour.
Quelle différence entre Docker et Podman rootless ?
Docker fonctionne avec un démon root, Podman rootless n’en nécessite pas. Cela réduit l’impact potentiel d’une compromission.
Est-il nécessaire d’avoir Kubernetes ?
Non. Pour un simple WordPress en DMZ, Podman rootless suffit. Kubernetes est adapté à des architectures multi-sites ou multi-services complexes.
Comment mettre à jour WordPress automatiquement ?
Avec podman auto-update
et les labels io.containers.autoupdate=registry
.
Liens utiles
Conclusion
Migrer un site WordPress legacy hébergé en DMZ vers un déploiement Podman rootless offre :
- Une sécurité renforcée (isolation utilisateur, images validées, surface d’attaque réduite).
- Une maintenance simplifiée (mises à jour automatiques, containers jetables).
- Une architecture moderne et légère, sans la complexité de Kubernetes.
C’est une solution idéale pour sécuriser rapidement un site WordPress exposé en DMZ, tout en préparant une éventuelle évolution vers des environnements plus complexes.