Aller au contenu

Publier son site MkDocs en production : de `serve` à `build`

Pourquoi mkdocs serve ne convient pas en production

Quand on lance mkdocs serve, MkDocs démarre un serveur de développement avec livereload. Ce serveur a un comportement problématique : il génère les URLs dynamiquement à partir de son adresse d'écoute.

Résultat : si votre conteneur écoute sur 0.0.0.0:8000, votre sitemap.xml contiendra des entrées comme :

<loc>http://0.0.0.0:8000/ma-page/</loc>

Impact SEO

Google Search Console rejette ces URLs et ne peut pas indexer votre site. Le sitemap est inutilisable.

En mode build en revanche, MkDocs génère des fichiers statiques et utilise la valeur de site_url définie dans mkdocs.yml — les bonnes URLs, propres et indexables.


Prérequis

  • Un site MkDocs fonctionnel avec un mkdocs.yml
  • Docker et Docker Compose installés dans le LXC
  • Un Nginx Proxy Manager (ou équivalent) pour exposer le site

Étape 1 : configurer site_url dans mkdocs.yml

C'est la base. Sans cette ligne, même mkdocs build génère un sitemap vide ou incorrect.

mkdocs.yml
site_name: Mon Site
site_url: https://monsite.fr/  # (1)!

theme:
  name: material
# ... reste de la config
  1. L'URL doit correspondre exactement à votre domaine public, avec le slash final.

Étape 2 : adapter le docker-compose.yml

On remplace le conteneur unique en mode serve par deux services :

  • mkdocs : génère les fichiers statiques (s'arrête après le build)
  • web : nginx qui sert les fichiers statiques en permanence
docker-compose.yml
services:
  mkdocs:
    build: .
    container_name: mkdocs_wiki
    working_dir: /docs
    user: "0:0"  # (1)!
    volumes:
      - /opt/mkdocs:/docs  # (2)!
    command: build
    restart: "no"  # (3)!

  web:
    image: nginx:alpine
    volumes:
      - /opt/mkdocs/site:/usr/share/nginx/html:ro
    ports:
      - "80:80"
    restart: unless-stopped
  1. Nécessaire si le montage SMB appartient à root (voir section Proxmox ci-dessous).
  2. Chemin absolu recommandé dans un contexte LXC.
  3. Le conteneur mkdocs s'arrête après le build — pas besoin de redémarrage automatique.

Mettre à jour le site

Pour régénérer le site après modification de vos fichiers :

docker compose run mkdocs
Nginx sert immédiatement les nouveaux fichiers sans redémarrage.


Étape 3 : configurer Nginx Proxy Manager

Dans l'interface NPM, modifiez votre entrée pour pointer vers le port 80 (nginx) au lieu de 8000 (serve) :

Champ Valeur
Forward Hostname IP ou nom du LXC
Forward Port 80
Scheme http

N'oubliez pas d'activer Force SSL et HTTP/2 si vous avez un certificat Let's Encrypt.


Problèmes de permissions avec Proxmox + LXC + Samba

C'est la partie la plus délicate. Voici l'environnement typique qui pose problème :

Proxmox (hôte)
  └── Montage SMB dans /etc/fstab  →  /mnt/smb1/Informatique/mkdocs
        └── LXC non-privilégié (CT 111)
              └── mp0: /mnt/smb1/Informatique/mkdocs,mp=/opt/mkdocs
                    └── Docker (mkdocs + nginx)

Pourquoi les permissions posent problème

Dans un LXC non-privilégié, les UIDs sont remappés :

uid 0  (root dans le LXC)  →  uid 100000  (sur l'hôte Proxmox)
uid 1000 (user dans le LXC) →  uid 101000  (sur l'hôte Proxmox)

Si le montage SMB appartient à root (uid=0) sur Proxmox, personne dans le LXC ne peut écrire dedans — même pas root du LXC, qui est en réalité uid=100000 côté Proxmox.

Symptôme

PermissionError: [Errno 13] Permission denied: '/docs/site'
Même avec user: "0:0" dans Docker, l'écriture échoue.

Diagnostic

Depuis l'hôte Proxmox, vérifiez le propriétaire du dossier :

ls -lan /mnt/smb1/Informatique/mkdocs/

Si vous voyez root root (uid=0), c'est le problème. Il faut transférer la propriété à uid=100000 :

# Depuis Proxmox
chown -R 100000:100000 /mnt/smb1/Informatique/mkdocs/

Rendre le fix permanent via /etc/fstab

Le chown sera perdu au prochain remontage. Pour le rendre permanent, modifiez la ligne du montage SMB dans /etc/fstab sur Proxmox :

/etc/fstab
# Montage utilisé par Plex (inchangé)
//192.168.1.15/Informatique  /mnt/smb1/Informatique  cifs  uid=0,gid=0,...  0 0

# Montage dédié mkdocs avec uid LXC non-privilégié
//192.168.1.15/Informatique/mkdocs  /mnt/smb_mkdocs  cifs  uid=100000,gid=100000,forceuid,forcegid,file_mode=0755,dir_mode=0755,username=user,password=pass,vers=3.0  0 0

Partager le SMB entre plusieurs LXC

Si votre partage SMB est aussi utilisé par d'autres conteneurs (Plex, etc.), créez un point de montage séparé pour mkdocs plutôt que de modifier le montage global. Chaque LXC a ses propres besoins en uid/gid.

Mettez ensuite à jour la config du LXC dans Proxmox :

/etc/pve/lxc/111.conf
mp0: /mnt/smb_mkdocs,mp=/opt/mkdocs

Puis redémarrez le LXC :

pct stop 111 && pct start 111

Vérification

Depuis le LXC, testez l'écriture :

touch /opt/mkdocs/test.txt && echo "✅ Écriture OK" || echo "❌ Permission refusée"
rm /opt/mkdocs/test.txt

Vérifier le sitemap

Une fois le site déployé, vérifiez que le sitemap contient les bonnes URLs :

curl https://monsite.fr/sitemap.xml | grep "<loc>"

Vous devriez voir :

<loc>https://monsite.fr/</loc>
<loc>https://monsite.fr/ma-page/</loc>

Et non plus http://0.0.0.0:8000/... 🎉

Soumettez ensuite le sitemap dans Google Search Console :
https://monsite.fr/sitemap.xml


Récapitulatif

graph TD
    A[mkdocs build] -->|génère| B[/opt/mkdocs/site/]
    B -->|monté en :ro| C[nginx:alpine :80]
    C -->|proxy| D[Nginx Proxy Manager]
    D -->|HTTPS| E[Internet 🌍]
    F[SMB Proxmox\nuid=100000] -->|mp0| G[LXC non-privilégié]
    G -->|volume| A