Créer et administrer une ferme dokuwiki.

Éric Maeker, 20 Septembre 2016, MAJ 27 Août 2017.

La simplicité est la sophistication suprême.
Léonard de Vinci
Dokuwiki est un moteur wiki simple d'utilisation et de mise en place. Il utilise des fichiers textuels au lieu d'un moteur de base de données complexe pour gérer le contenu et le paramétrage des sites. Il est possible de créer avec un seul moteur Dokuwiki (le farmer ou fermier) plusieurs sites internets (ou animaux). Ces multiples sites peuvent être paramétrés en :
  • domaines (https://www.mondomaine.fr),
  • sous-domaines (https://wiki.mondomaine.fr),
  • ou chemins (https://www.mondomaine.fr/mon/wiki).

L'ensemble farmer et animaux constitue une ferme.

Comment créer une ferme Dokuwiki et comment l'administrer ?

  • Plusieurs de mes sites sont propulsés par le même moteur Dokuwiki installé sur un même serveur VPS.

Les répertoires de travail

L'organisation des répertoires a un impact très important dans la configuration des serveurs, de la ferme et des animaux. Voici l'arborescence utilisée :

  • farm
    • dokuwiki (répertoire qui contient le “farmer”)
    • animal1
    • animal2

Le farmer est une installation complète et fonctionnelle de Dokuwiki. Il sera nécessaire de modifier un à deux fichiers php dans cette installation pour activer le farming.

Installer Dokuwiki

Le plus simple consiste à télécharger Dokuwiki depuis le site officiel et de décompresser l'archive dans le répertoire dokuwiki (selon l'arborescence ci-dessus).

Suivez le guide officiel de préparation du farmer, dont voici le résumé :

  • copier le fichier
    ./inc/preload.php.dist

    en

    ./inc/preload.php
  • éditer le fichier selon le modèle présenté ci-dessous
  • vérifier l'existance du fichier
    ./inc/farm.php

Modèle de contenu du fichier <code>./inc/preload.php</code>

// Set this to your farm directory using the full path to the dokuwiki farmer
// Change ‘/var/www/farm’ to your full path
// On MacOs X, apache server points to /Library/WebServer/Documents
if(!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', '/var/www/farm');
 
// or use this code if you are using the exact directory structure describe above
// if(!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', fullpath(dirname(__FILE__).'/../..'));
 
// include this after DOKU_FARMDIR if you want to use farms
include(fullpath(dirname(__FILE__)).'/farm.php');

Récupérer les structures "animaux" vierges

Le modèle d'animal vierge est disponible sur le site officiel. Il ne reste qu'à copier ce fichier dans la racine de la ferme et de le décompresser.

Pour assurer une bonne lisibilité de l'arborescence, le nom de l'animal sera choisi selon sa destination. Par exemple :

  • wiki_truc
  • domaine.com

Dans le répertoire de l'animal, il est nécessaire de configurer le fichier conf/local.protected.php. Le protected permet de verrouiller les variables pour limiter les modifications malheureuses.

Souvent les sites sont modifiés en local (test) pour être ensuite propulsés sur le net (production). Il sera donc judicieux d'automatiser le changement de structure (test et production) dans le code PHP. Voici une modification qui permet d'avoir deux configurations : l'une locale l'autre sur serveur.

<?php
/**
 * These settings are "protected" and cannot be overwritten
 * by the configuration manager, but need to be edited manually.
 */
 
$conf['savedir'] = DOKU_CONF.'../data';
$conf['updatecheck'] = 0;
$conf['useslash'] = 1;
 
if ($_SERVER['SERVER_NAME'] == 'localhost') {
  // Local configuration: URL= localhost{basedir}{request}
  $conf['basedir'] = '/eric/farm/eric/';
  $conf['userewrite'] = 0;
} else {
  // VPS server configuration
  // URL= https://server.svr{basedir}{request}
  $conf['basedir'] = '/eric/wiki/';
  $conf['userewrite'] = 1;
  $conf['baseurl'] = ''; // autodetect
}

La configuration du serveur Apache (utilisé en local pour les tests) passe par l'utilisation des fichiers .htaccess. Le fichier sera placé à la racine de l'arborescence farm dans celle décrite au début de l'article.

RewriteEngine On
RewriteCond %{REQUEST_URI}   !^/eric/farm/dokuwiki(/|$)
RewriteRule ^/?([^/]+)/(.*)  /eric/farm/dokuwiki/$2?animal=$1 [QSA]
RewriteRule ^/?([^/]+)$      /eric/farm/dokuwiki/doku.php?animal=$1 [QSA]

Options +FollowSymLinks

Le paramétrage du serveur nginx est plus délicat. Voici le code du fichier de configuration du serveur nginx.

Exemple du code du site FreeMedForms, un animal accessible en domaine.

# This should be defined once in all configurations if you want to debug the rewritings
#rewrite_log on;

## SERVERS --> HTTP to HTTPS
server {
    listen 80;
    server_name freemedforms.com www.freemedforms.com;
    rewrite ^(.*) https://freemedforms.com/$1 permanent;
}

server {
  listen 443 ssl;
  server_name freemedforms.com www.freemedforms.com;

  # SSL configuration: https://letsecure.me/secure-web-deployment-with-lets-encrypt-and-nginx/
  ssl on;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
     ssl_prefer_server_ciphers On;
     ssl_certificate /PATH/TO/fullchain.pem;
     ssl_certificate_key /PATH/TO/privkey.pem;
     ssl_trusted_certificate /PATH/TO/chain.pem;
     ssl_session_cache shared:SSL:128m;
     add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
     add_header X-Frame-Options "SAMEORIGIN";
     add_header X-Content-Type-Options "nosniff";
     add_header X-Xss-Protection "1";
#     add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' *.google-analytics.com; img-src 'self' data:";
     add_header Referrer-Policy origin-when-cross-origin;
     ssl_stapling on;
     ssl_stapling_verify on;

  # Log files
  access_log /var/log/nginx/access_fmf.log;
  error_log  /var/log/nginx/error_fmf.log;
#  error_log  /var/log/nginx/error_fmf.log debug;
#  error_log  /var/log/nginx/error_fmf.log notice;

  client_max_body_size 15M;
  client_body_buffer_size 128k;

  # Dokuwiki farming one for one:
  #   One server_name for one animal (eg www.domain.tld -> farm[animal])

  # Farm dir:
  #   /var/www/farm
  #             |--- /dokuwiki/  -> FARMER (all dokuwiki files & templates & plugins)
  #             |--- /fmf/       -> ANIMAL (current one)
  #             `--- /other/     -> Another ANIMAL (not accessible from here)

  # Edit Dokuwiki files according to documentation
  #   inc/preload.php
  #     if(!defined('DOKU_FARMDIR'))
  #       define('DOKU_FARMDIR', fullpath(dirname(__FILE__).'/../..')); // to /var/www/farm
  #     include(fullpath(dirname(__FILE__)).'/farm.php');

  # Check this file exists
  #   /var/www/farm/dokuwiki/inc/farm.php

  # There are no sub-path domains (like domain.dom/subpath/) so we defined the
  #   /var/www/farm/fmf/conf/local.protected.php
  #     $conf['basedir']="/";                         # no sub-path
  #     $conf['baseurl']="";                          # auto-detect
  #     $conf['savedir'] = DOKU_CONF.'../data';       # data path inside the animal path
  #     $conf['userewrite'] = 1;                      # server url rewriting
  #     $conf['useslash'] = 1;                        # url uses slash instead of semicolon

  # Set root to FARMER
  root /var/www/farm/dokuwiki/;

  # Manage FARMING in index (only dokuwiki)
  # Here you should manage dokuwiki url rewriting & page sperator in the conf/local.php
  # Eg:
  #    no rewriting       -> index: /doku.php?id=start&animal=fmf
  #    dokuwiki rewriting -> index: /doku.php/start
  #    server rewriting   -> index: /start  # recommanded
  index /fr/start;

  # Define expiration date to image/css/js/pdf/xml resources 
  location ~ ^/lib/.+\.(jpg|jpeg|gif|png|svg|ico|css|js|xml|pdf)$ {
    expires 7d;
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
  }

  # TODO: move these files to the **animal** path (cause root path is the farmer)
  location = /robots.txt  { access_log off; log_not_found off; }
  location = /favicon.ico { access_log off; log_not_found off; }
  location ~ /\.          { access_log off; log_not_found off; deny all; }
  location ~ ~$           { access_log off; log_not_found off; deny all; }

  # Secure Dokuwiki installation
  location ~ ^/(data/|conf/|bin/|inc/|install.php)/ { deny all; }

  # Default location: tries URL, URL as a dir, or serve FreeMedForms's Dokuwiki Animal
  location / {
    try_files $uri $uri/ @dokuwiki;
  }

  location @dokuwiki {
    # Use URL Rewriting with the FARMING options:
    #   - add "animal=ANIMAL_NAME" param at the **end** of the params
    rewrite ^/_media/(.*)          /lib/exe/fetch.php?media=$1&animal=fmf last;
    rewrite ^/_detail/(.*)         /lib/exe/detail.php?media=$1&animal=fmf last;
    rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2&animal=fmf last;
    # Workaround sitemap problematic
    rewrite ^/sitemap              /doku.php?do=sitemap&animal=fmf last;
    # Tag everything with the animal arg
    rewrite ^/(.*)                 /doku.php?id=$1&$args&animal=fmf last;
  }

  location ~ \.php$ {
    try_files $uri =404;
    include fastcgi.conf ;
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index doku.php;
    # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    # include snippets/fastcgi-php.conf ;
  }
}

Exemple du code du site https://www.maeker.fr, plusieurs animaux accessibles grâce à l'utilisation de chemins dans l'URL : https://www.maeker.fr/{animal}/wiki.

# This should be defined once in all configurations if you want to debug the rewritings
#rewrite_log on;

# Redirect http -> https
server {
    listen 80;
    server_name maeker.fr www.maeker.fr;
    rewrite ^(.*) https://www.maeker.fr/$1 permanent;
}

# SSL server
server {
  listen 443 ssl;
  server_name maeker.fr www.maeker.fr;

  # SSL configuration: https://letsecure.me/secure-web-deployment-with-lets-encrypt-and-nginx/
  ssl on;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
     ssl_prefer_server_ciphers On;
     ssl_certificate /PATH/TO/fullchain.pem;
     ssl_certificate_key /PATH/TO/privkey.pem;
     ssl_trusted_certificate /PATH/TO/chain.pem;
     ssl_session_cache shared:SSL:128m;
     add_header Strict-Transport-Security "max-age=31557600; includeSubDomains";
     add_header X-Frame-Options "SAMEORIGIN";
     add_header X-Content-Type-Options "nosniff";
     add_header X-Xss-Protection "1";
#     add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' *.google-analytics.com; img-src 'self' data:";
     add_header Referrer-Policy origin-when-cross-origin;
     ssl_stapling on;
     ssl_stapling_verify on;

  # Log files
  access_log /var/log/nginx/access_mk.log;
  error_log /var/log/nginx/error_mk.log; # notice; # debug;

  client_max_body_size 15M;
  client_body_buffer_size 128k;

  # Set root to FARMER
  root /var/www/farm/dokuwiki/;

  # We use the URL rewriting using 'htaccess' in dokuwiki configuration
  index /eric/wiki/fr/start;

  # Define expiration date to image/css/js/pdf/xml resources 
  location ~ ^/([^/]+)/wiki/lib/.+\.(jpg|jpeg|gif|png|svg|ico|css|js|xml|pdf)$ {
    expires 7d;
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    rewrite ^/([^/]+)/wiki/lib/(.*)      /lib/$2?$args last;
  }

  # TODO: move these files to the **animal** path (cause root path is the farmer)
  location = /robots.txt  { access_log off; log_not_found off; }
  location = /favicon.ico { access_log off; log_not_found off; }
  location ~ /\.          { access_log off; log_not_found off; deny all; }
  location ~ ~$           { access_log off; log_not_found off; deny all; }

  # Secure Dokuwiki installation
  location ~ ^/(data/|conf/|bin/|inc/|install.php)/ { deny all; }

  # FARMING: Rewrite URL putting the animal name at the end of the params or URL
  location ~ ^/([^/]+)/wiki/ {
    try_files $uri $uri/ @dokufarm;
  }

  location @dokufarm {
    # FARMING: Rewrite URL putting the animal name at the end of the params or URL
    # The animal is the first subpath  {animal}/wiki/{request}
    rewrite ^/([^/]+)/wiki/_media/(.*)   /lib/exe/fetch.php?media=$2&animal=$1 last;
    rewrite ^/([^/]+)/wiki/_detail/(.*)  /lib/exe/detail.php?media=$2&animal=$1 last;
    rewrite ^/([^/]+)/wiki/_export/([^/]+)/(.*) /doku.php?do=export_$2&id=$3&animal=$1 last;
    rewrite ^/([^/]+)/wiki/lib/exe/(.*)  /lib/exe/$2?$args&animal=$1 last;
    rewrite ^/([^/]+)/wiki/lib/(.*)      /lib/$2?$args last;
    rewrite ^/([^/]+)/wiki/(.*)          /doku.php?id=$2&$args&animal=$1 last;
    rewrite ^/([^/]+)/wiki               /doku.php?animal=$1 last;
  }

  location ~ \.php$ {
    try_files $uri =404;
    include fastcgi.conf ;
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index doku.php;
    # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    # include snippets/fastcgi-php.conf ;
  }
}

Ce script s'utilise en ligne de commande directement sur le serveur. Il convient de modifier les chemins d'accès à votre farmer et vos animaux. Les sitemap seront à jour à la fin de ce processus. Ce script est nécessaire pour palier à un défaut de configuration de l'exporter de Dokuwiki.

#!/bin/bash
 
# Aller à la racine de la ferme : "farm" dans notre exemple
cd farm/root/path
 
# Définir tous les animaux pour les wikis fonctionnant en URL-chemin
# Par exemple: https://domaine.fr/wiki/ANIMAL/...
animaux="eric fmf ged"
 
for a in $animaux; do
  echo "***********  UPDATING ANIMAL: $a";
  sudo animal=$a ./dokuwiki/bin/indexer.php;
  # Remettre les droits aux fichiers nouvellement créés
  sudo chown www-data:www-data ./$a/data/index/*;
  sudo chown -R www-data:www-data ./$a/data/meta/*;
  # Effacer les anciens sitemaps pour forcer leur (re)création
  sudo rm ./$a/data/cache/sitemap*;
done
 
exit 0;
  • Pour accéder aux sitemap des différents animaux il suffit de préciser l'animal dans l'URL.
  • Pour l'exemple de configuration en URL-chemin :
    • https://domaine.fr/ANIMAL/wiki/?do=sitemap
  • Cette URL est indispensable pour envoyer les sitemap aux moteurs de recherche.

Les fermes dokuwiki sont faciles à mettre en place et à paramétrer. L'utilisation d'un serveur Apache est peut-être plus confortable que l'utilisation d'un serveur nginx. Chacun appréciera selon ses habitudes et ses opinions.

Il est fortement recommandé de lire les documentations sur le site officiel de Dokuwiki.

Sites internet