Installer Dolibarr avec Docker Compose

Un docker-compose.yml complet pour Dolibarr 24 et MariaDB, testé de bout en bout. Avec l'exemple officiel, les mots de passe sont stockés en MD5 avec une copie en clair, et les tâches planifiées ne tournent jamais : comment l'éviter.

Versions concernées
Image officielle dolibarr/dolibarr 24.0.1 (dernière image publiée au 13/10/2026), MariaDB 11.4 ; les trois pièges viennent du script de démarrage commun à toutes les versions de l'image
Ce qui a été vérifié
Lecture du script de démarrage de l'image (docker-run.sh, dépôt Dolibarr/dolibarr-docker au 13/10/2026) et du code de Dolibarr 24.0.1 (dol_hash, dol_verifyHash, install/step5.php, cron_run_jobs.php). Trois installations neuves le 13/10/2026 sous Docker 28 : configuration de l'exemple officiel, configuration corrigée, puis les fichiers de cette page copiés tels quels. Contrôles : connexion, empreinte des mots de passe en base, exécution du cron, arrêt et relance, sauvegarde depuis l'interface, envoi d'un fichier de 5 Mo avant et après avoir relevé la limite de Dolibarr. Le 14/10/2026 : lecture de User::setPassword() et admin/security.php, puis deux installations neuves de plus (fichiers de cette page sans, puis avec la ligne DATABASE_PWD_ENCRYPTED) : colonne llx_user.pass après un changement de mot de passe, bouton « Activer » de la page Sécurité, connexion après effacement des copies en clair.

L’image officielle dolibarr/dolibarr installe Dolibarr toute seule au premier démarrage : un fichier docker-compose.yml, une commande, et une minute plus tard l’écran de connexion s’affiche. Cette page donne une configuration complète, testée le 13 octobre 2026 avec Dolibarr 24.0.1 et MariaDB 11.4.

Elle corrige aussi trois défauts de l’installation automatique que l’exemple de la documentation officielle ne signale pas, et que nous avons constatés sur une installation neuve :

  • les mots de passe des utilisateurs sont enregistrés en MD5, sans sel, alors qu’une installation classique les protège avec password_hash ;
  • les tâches planifiées ne s’exécutent jamais : le conteneur cron échoue toutes les cinq minutes avec une erreur de clé que l’on ne voit que dans ses journaux ;
  • une copie en clair des mots de passe reste dans la base : chaque mot de passe changé depuis l’interface y est aussi enregistré lisiblement, à côté de sa version chiffrée.

Ce qu’il vous faut

Docker avec le module Compose : docker compose version doit répondre. Les commandes ci-dessous sont celles de Linux et de macOS. Toute l’installation tient dans un dossier, par exemple ~/dolibarr : la configuration, la base de données, les documents et les modules externes.

mkdir -p ~/dolibarr/docker-init.d && cd ~/dolibarr

1. Le fichier docker-compose.yml

services:
  db:
    image: mariadb:11.4
    restart: unless-stopped
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MARIADB_DATABASE: dolibarr
      MARIADB_USER: dolibarr
      MARIADB_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./data/mariadb:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  web:
    image: dolibarr/dolibarr:24.0.1
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment: &dolibarr-env
      DOLI_DB_HOST: db
      DOLI_DB_NAME: dolibarr
      DOLI_DB_USER: dolibarr
      DOLI_DB_PASSWORD: ${DB_PASSWORD}
      DOLI_URL_ROOT: ${DOLI_URL_ROOT}
      DOLI_ADMIN_LOGIN: ${ADMIN_LOGIN}
      DOLI_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      DOLI_INSTANCE_UNIQUE_ID: ${INSTANCE_UNIQUE_ID}
      DOLI_COMPANY_NAME: ${COMPANY_NAME}
      DOLI_COMPANY_COUNTRYCODE: FR
      DOLI_ENABLE_MODULES: Cron
      DOLI_CRON_KEY: ${CRON_KEY}
      DOLI_CRON_USER: ${ADMIN_LOGIN}
      PHP_INI_DATE_TIMEZONE: Europe/Paris
    ports:
      - "8080:80"
    volumes:
      - ./data/documents:/var/www/documents
      - ./data/custom:/var/www/html/custom
      - ./docker-init.d:/var/www/scripts/docker-init.d

  cron:
    image: dolibarr/dolibarr:24.0.1
    restart: unless-stopped
    depends_on:
      - web
    environment:
      <<: *dolibarr-env
      DOLI_CRON: 1
    volumes:
      - ./data/documents:/var/www/documents
      - ./data/custom:/var/www/html/custom

Les choix qui comptent :

  • Des versions précises, jamais latest. L’exemple officiel utilise dolibarr/dolibarr:latest et mariadb:latest : un simple docker compose pull peut alors vous faire changer de version majeure sans l’avoir décidé. Au 13 octobre 2026, la dernière image publiée est la 24.0.1 ; la 24.0.2 est sortie, mais son image n’est pas encore sur Docker Hub.
  • Le contrôle de santé de MariaDB fait attendre Dolibarr que la base soit prête.
  • DOLI_ENABLE_MODULES: Cron active le module des tâches planifiées pendant l’installation, avant que l’image enregistre la clé du cron. C’est la correction du second piège, détaillée plus bas. Vous pouvez ajouter d’autres modules, séparés par des virgules (Societe,Facture,Cron).
  • Le service cron utilise la même image, avec DOLI_CRON: 1 : il lance les tâches planifiées toutes les cinq minutes. Il reprend toutes les variables du service web grâce à &dolibarr-env.
  • Les données restent dans le dossier data/ : la base, les documents, les modules externes. Ce sont les seuls fichiers à sauvegarder avec .env.

2. Le fichier .env, avec de vrais mots de passe

L’exemple officiel garde, si l’on ne change rien, les mots de passe admin/admin pour Dolibarr et root pour la base. Cette commande crée le fichier .env avec des valeurs aléatoires :

cat > .env <<EOF
DOLI_URL_ROOT=http://localhost:8080
ADMIN_LOGIN=admin
ADMIN_PASSWORD=$(openssl rand -hex 12)
DB_PASSWORD=$(openssl rand -hex 16)
DB_ROOT_PASSWORD=$(openssl rand -hex 16)
INSTANCE_UNIQUE_ID=$(openssl rand -hex 32)
CRON_KEY=$(openssl rand -hex 16)
COMPANY_NAME="Ma société"
EOF
chmod 600 .env

DOLI_URL_ROOT est l’adresse à laquelle vous ouvrirez Dolibarr. INSTANCE_UNIQUE_ID sert de clé de chiffrement pour certains réglages : sans elle, l’image écrit une valeur fixe, la même pour tout le monde. Ne la changez plus une fois l’installation faite, ces réglages deviendraient illisibles.

3. Le script qui protège les mots de passe

Créez le fichier docker-init.d/mots-de-passe.sql. L’image exécute les scripts de ce dossier une seule fois, à la fin de l’installation :

cat > docker-init.d/mots-de-passe.sql <<'EOF'
INSERT INTO llx_const (name, value, type, visible, note, entity) VALUES ('MAIN_SECURITY_HASH_ALGO', 'password_hash', 'chaine', 0, '', 0);
INSERT INTO llx_const (name, value, type, visible, note, entity) VALUES ('DATABASE_PWD_ENCRYPTED', '1', 'chaine', 0, '', 0);
EOF

N’y mettez pas de commentaire : l’image retire les lignes qui commencent par -- en réécrivant le fichier.

La première ligne corrige le piège n° 1 (mots de passe en MD5), la seconde le piège n° 3 (copie en clair), tous deux décrits plus bas.

4. Démarrer

docker compose up -d
docker compose logs -f web

Attendez le message « You can connect to the running Dolibarr web application » (une minute environ dans notre test), puis quittez les journaux avec Ctrl+C. Ouvrez http://localhost:8080 et connectez-vous avec admin et le mot de passe que donne grep ADMIN_PASSWORD .env.

5. Juste après la première connexion : changez le mot de passe admin

Le compte admin est créé avant que le script de l’étape 3 ne s’exécute : son mot de passe est donc encore en MD5. Ouvrez Utilisateurs & Groupes, la fiche admin, Modifier, et saisissez un nouveau mot de passe. Il est alors enregistré avec password_hash, et Dolibarr vous demande de vous reconnecter.

ADMIN_PASSWORD ne sert qu’au tout premier démarrage : le modifier ensuite dans .env ne change rien, même après une recréation des conteneurs. Nous l’avons vérifié.

Piège n° 1 : des mots de passe en MD5

À l’installation par l’assistant web, Dolibarr enregistre MAIN_SECURITY_HASH_ALGO = password_hash (fichier install/step5.php). L’installation automatique de l’image Docker saute cette étape : la ligne qui devait le faire est en commentaire dans docker-run.sh. Sans ce réglage, Dolibarr chiffre tous les mots de passe en MD5 sans sel, y compris ceux que vous changez ensuite depuis l’interface. Sur notre installation neuve, le mot de passe changé depuis la fiche utilisateur faisait toujours 32 caractères en base, la signature d’un MD5.

Le ticket correspondant du dépôt de l’image (#14) a été fermé en mai 2026, mais l’image 24.0.1, installée de zéro le 13 octobre 2026, a toujours ce défaut.

Pour savoir si votre instance est touchée, ouvrez Outils d’administration › Infos sécurité. Si la ligne « Algorithme pour : Mots de passe » indique « Non défini (If unset: ‘md5’) », elle l’est.

Pour corriger une instance déjà installée :

  1. connecté en administrateur, ouvrez Configuration › Divers et ajoutez la constante MAIN_SECURITY_HASH_ALGO avec la valeur password_hash ;
  2. sans vous déconnecter, changez votre propre mot de passe depuis votre fiche utilisateur ;
  3. faites changer le mot de passe de chaque autre utilisateur.

La page de sécurité de Dolibarr prévient qu’après ce changement, tous les anciens mots de passe deviennent invalides. En 24.0.1, ce n’est plus le cas : nous avons vérifié qu’un utilisateur resté en MD5 se connecte toujours. Mais son mot de passe ne sera converti que lorsqu’il le changera. D’où l’étape 3.

Piège n° 2 : un cron qui ne tourne jamais

Avec la configuration de l’exemple officiel (DOLI_CRON_KEY sans DOLI_ENABLE_MODULES), le conteneur cron affiche toutes les cinq minutes :

Error: securitykey provided xxxxx... does not match securitykey in setup.

Rien n’apparaît dans Dolibarr : seul docker compose logs cron le montre. La cause : au premier démarrage, l’image écrit votre clé par une mise à jour de la ligne CRON_KEY de la base, mais cette ligne n’existe qu’une fois le module des tâches planifiées activé. La mise à jour ne touche aucune ligne, et la clé n’est jamais enregistrée. Activer le module ensuite ne suffit pas : la clé reste vide.

Sur une nouvelle installation, DOLI_ENABLE_MODULES: Cron règle le problème : le module est activé avant que la clé soit écrite. C’est la configuration de cette page.

Sur une instance déjà installée, activez le module Travaux planifiés, ouvrez sa configuration et collez dans « Clé de sécurité » la valeur de CRON_KEY de votre fichier .env. Pour vérifier sans attendre :

docker compose exec cron /bin/su www-data -s /bin/sh -c "/var/www/scripts/cron/cron_run_jobs.php $(grep '^CRON_KEY=' .env | cut -d= -f2) admin"

La réponse doit lister les tâches avec « Result of run_jobs OK », et non plus l’erreur de clé.

Piège n° 3 : une copie en clair des mots de passe

À l’installation par l’assistant web, Dolibarr enregistre aussi DATABASE_PWD_ENCRYPTED = 1 (même fichier install/step5.php) : ce réglage lui interdit de garder une copie en clair des mots de passe. L’installation automatique de l’image ne le pose pas, docker-run.sh n’en parle nulle part. Sans lui, chaque mot de passe saisi depuis l’interface est enregistré deux fois : chiffré dans pass_crypted, et en clair dans la colonne pass de la table llx_user. Le piège n° 1 n’y change rien : avec password_hash, la version chiffrée est bonne, mais la copie en clair est toujours là.

Sur notre installation neuve faite avec la seule ligne MAIN_SECURITY_HASH_ALGO, le mot de passe admin changé à l’étape 5 se lisait tel quel dans la base. Il apparaissait aussi dans le code HTML de la fiche utilisateur ouverte en modification. Avec la seconde ligne du script de l’étape 3, la colonne reste vide : nous l’avons vérifié sur une autre installation neuve.

Pour savoir si votre instance est touchée, ouvrez Outils d’administration › Infos sécurité. Si la ligne « Chiffrer les mots de passe stockés dans la base de données » indique « Non », elle l’est. Cette commande liste les comptes dont le mot de passe est en clair :

docker compose exec -T db sh -c 'mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE" -e "SELECT login FROM llx_user WHERE LENGTH(pass) > 0"'

Pour corriger une instance déjà installée :

  1. connecté en administrateur, ouvrez Accueil › Configuration › Sécurité, onglet Mots de passe, et cliquez sur Activer en face de « Chiffrer les mots de passe stockés dans la base de données ». Dolibarr enregistre le réglage et efface les copies en clair, mais seulement celles de moins de 32 caractères : il prend les plus longues pour d’anciennes empreintes MD5 et les laisse ;
  2. effacez celles qui restent :
docker compose exec -T db sh -c 'mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE" -e "UPDATE llx_user SET pass = NULL WHERE LENGTH(pass) > 0 AND LENGTH(pass_crypted) > 0"'

La connexion n’utilise que la version chiffrée : dans notre test, un compte dont la copie en clair a été effacée se connecte toujours. Inutile donc de faire changer les mots de passe. Relancez la commande de contrôle : elle ne doit plus rien afficher. Un compte qui resterait listé n’a pas de version chiffrée, la commande l’épargne pour ne pas le bloquer : faites-lui changer son mot de passe.

Ce que l’image fait d’autre, à savoir

  • conf.php est réécrit à chaque recréation du conteneur, à partir des variables d’environnement. Changer DOLI_URL_ROOT dans .env puis lancer docker compose up -d suffit donc pour changer d’adresse, mais toute modification faite à la main dans conf.php disparaît.
  • Les sessions sont perdues à chaque recréation : après une mise à jour de l’image, tout le monde doit se reconnecter.
  • Les envois de fichiers sont limités à 2 Mo, même si PHP accepte 20 Mo. L’image règle bien PHP sur 20 Mo (sa documentation indique 2 Mo, à tort), mais Dolibarr applique sa propre limite, fixée à 2 048 Ko à l’installation. Dans notre test, un fichier de 5 Mo est refusé avec « La taille du fichier est trop grande ou le fichier n’est pas fourni ». Pour la relever, ouvrez Accueil › Configuration › Sécurité, onglet Fichiers, et changez « Taille maximum des fichiers envoyés » (en Ko : 20480 pour 20 Mo). Au-delà de 20 Mo, ajoutez aussi PHP_INI_UPLOAD_MAX_FILESIZE et PHP_INI_POST_MAX_SIZE aux variables.
  • Le nom du service de la base doit correspondre à DOLI_DB_HOST. Sans cette variable, l’image cherche un serveur nommé mysql, et le conteneur web attend indéfiniment.

Accès depuis Internet

Ne publiez pas le port 8080 tel quel. Placez devant Dolibarr un proxy qui gère le HTTPS (Caddy, Traefik, Nginx), mettez l’adresse en https:// dans DOLI_URL_ROOT, puis relancez avec docker compose up -d. Si le proxy tourne sur la même machine, publiez le port uniquement en local ("127.0.0.1:8080:80") pour qu’on ne puisse pas contourner le proxy.

Sauvegarder

La sauvegarde depuis l’interface fonctionne avec cette configuration (Outils d’administration › Sauvegarde) : le fichier arrive dans data/documents/admin/backup/. En ligne de commande, la méthode la plus sûre consiste à exporter la base depuis le conteneur MariaDB, puis à copier les dossiers data/documents et data/custom, avec le fichier .env :

docker compose exec -T db sh -c 'mariadb-dump -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' > sauvegarde.sql

Le fichier est complet s’il se termine par « – Dump completed ».

Mettre à jour ensuite

Changez le numéro de version de l’image une version majeure à la fois, jamais directement de la 20 à la 24 : l’image sauterait des migrations sans le signaler. La procédure complète, testée, est dans Mettre à jour Dolibarr sous Docker.

Si vous préférez qu’on s’en occupe, le forfait Installation et paramétrage part de cette configuration.

À lire aussi

DolibarrDockerdocker composeinstallationMariaDBcronmot de passe