Instalar Dolibarr con Docker Compose
Un docker-compose.yml completo para Dolibarr 24 y MariaDB, probado de principio a fin. Con el ejemplo oficial, las contraseñas se guardan en MD5 con una copia en claro, y las tareas programadas nunca se ejecutan: cómo evitarlo.
¿Prefiere que se lo hagan? Instalación y configuración, precio fijo 690 €.
Qué se ha comprobado (versiones, pruebas, código leído)
Lectura del script de arranque de la imagen (docker-run.sh, repositorio Dolibarr/dolibarr-docker al 13/10/2026; idéntico en la imagen 24.0.2 salvo una línea de PHP sin relación) y del código de Dolibarr 24.0.1 (dol_hash, dol_verifyHash, install/step5.php, cron_run_jobs.php). Tres instalaciones nuevas el 13/10/2026 con Docker 28: configuración del ejemplo oficial, configuración corregida y, por último, los archivos de esta página copiados tal cual. Comprobado: inicio de sesión, huella de las contraseñas en la base de datos, ejecución del cron, parada y reinicio, copia de seguridad desde la interfaz, subida de un archivo de 5 MB antes y después de subir el límite de Dolibarr. El 14/10/2026: lectura de User::setPassword() y admin/security.php, y dos instalaciones nuevas más (sin y con la línea DATABASE_PWD_ENCRYPTED): columna llx_user.pass tras un cambio de contraseña, botón «Activar» de la página Seguridad, inicio de sesión tras borrar las copias en claro. El 03/11/2026: instalación nueva con los archivos de esta página tal cual y la imagen 24.0.2 publicada el 31/10 (PHP 8.5.12): inicio de sesión, contraseña de admin en MD5 tras la instalación y en password_hash tras cambiarla, columna pass vacía, MAIN_SECURITY_HASH_ALGO y DATABASE_PWD_ENCRYPTED guardados, clave del cron guardada y tareas ejecutadas a mano (Europe/Madrid), archivo de 5 MB rechazado con 2 048 KB y aceptado con 20480, línea de docker-run.sh todavía comentada.
La imagen oficial dolibarr/dolibarr instala Dolibarr sola en el primer arranque: un archivo
docker-compose.yml, un comando, y un minuto después aparece la pantalla de inicio de sesión.
Esta página da una configuración completa, probada con Dolibarr 24.0.2 y MariaDB 11.4.
También corrige tres defectos de la instalación automática que el ejemplo de la documentación oficial no menciona, y que hemos visto en una instalación nueva:
- las contraseñas de los usuarios se guardan en MD5, sin sal, mientras que una instalación
clásica las protege con
password_hash; - las tareas programadas nunca se ejecutan: el contenedor cron falla cada cinco minutos con un error de clave que solo se ve en sus registros;
- queda una copia en claro de las contraseñas en la base de datos: cada contraseña cambiada desde la interfaz se guarda también de forma legible, junto a su versión cifrada.
Lo que necesita
Docker con el complemento Compose: docker compose version debe responder. Los comandos de abajo son
los de Linux y macOS. Toda la instalación cabe en una carpeta, por ejemplo ~/dolibarr: la
configuración, la base de datos, los documentos y los módulos externos.
mkdir -p ~/dolibarr/docker-init.d && cd ~/dolibarr
1. El archivo 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.2
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: ES
DOLI_ENABLE_MODULES: Cron
DOLI_CRON_KEY: ${CRON_KEY}
DOLI_CRON_USER: ${ADMIN_LOGIN}
PHP_INI_DATE_TIMEZONE: Europe/Madrid
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.2
restart: unless-stopped
depends_on:
- web
environment:
<<: *dolibarr-env
DOLI_CRON: 1
volumes:
- ./data/documents:/var/www/documents
- ./data/custom:/var/www/html/custom
Ponga en DOLI_COMPANY_COUNTRYCODE el código de dos letras de su país (ES, MX, AR, CO…)
y en PHP_INI_DATE_TIMEZONE su zona horaria (Europe/Madrid, America/Mexico_City,
America/Bogota…). Las decisiones que importan:
- Versiones precisas, nunca
latest. El ejemplo oficial usadolibarr/dolibarr:latestymariadb:latest: un simpledocker compose pullpuede entonces hacerle cambiar de versión mayor sin haberlo decidido. La imagen 24.0.2 funciona con PHP 8.5. - El control de salud de MariaDB hace que Dolibarr espere a que la base de datos esté lista.
DOLI_ENABLE_MODULES: Cronactiva el módulo de tareas programadas durante la instalación, antes de que la imagen guarde la clave del cron. Es la corrección de la segunda trampa, detallada más abajo. Puede añadir otros módulos, separados por comas (Societe,Facture,Cron).- El servicio
cronusa la misma imagen, conDOLI_CRON: 1: lanza las tareas programadas cada cinco minutos. Hereda todas las variables del serviciowebgracias a&dolibarr-env. - Los datos se quedan en la carpeta
data/: la base de datos, los documentos, los módulos externos. Son los únicos archivos que hay que guardar en la copia de seguridad, junto con.env.
2. El archivo .env, con contraseñas de verdad
Si no se cambia nada, el ejemplo oficial deja las contraseñas admin/admin para Dolibarr y
root para la base de datos. Este comando crea el archivo .env con valores aleatorios:
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="Mi empresa"
EOF
chmod 600 .env
DOLI_URL_ROOT es la dirección con la que abrirá Dolibarr. INSTANCE_UNIQUE_ID sirve de clave de
cifrado para algunos ajustes: sin ella, la imagen escribe un valor fijo, el mismo para todo el
mundo. No la cambie una vez hecha la instalación: esos ajustes se volverían ilegibles.
3. El script que protege las contraseñas
Cree el archivo docker-init.d/contrasenas.sql. La imagen ejecuta los scripts de esta carpeta una sola vez, al final de la instalación:
cat > docker-init.d/contrasenas.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
No ponga comentarios en él: la imagen elimina las líneas que empiezan por -- al reescribir el
archivo.
La primera línea corrige la trampa n.º 1 (contraseñas en MD5) y la segunda la trampa n.º 3 (copia en claro), descritas más abajo.
4. Arrancar
docker compose up -d
docker compose logs -f web
Espere el mensaje «You can connect to the running Dolibarr web application» (alrededor de un minuto
en nuestra prueba) y salga de los registros con Ctrl+C. Abra http://localhost:8080 e inicie
sesión con admin y la contraseña que da grep ADMIN_PASSWORD .env.
5. Justo después del primer inicio de sesión: cambie la contraseña de admin
La cuenta admin se crea antes de que se ejecute el script del paso 3: su contraseña sigue por
tanto en MD5. Abra Usuarios y grupos, la ficha admin, Modificar, y escriba una contraseña
nueva. Se guarda entonces con password_hash, y Dolibarr le pide que vuelva a iniciar sesión.
ADMIN_PASSWORD solo sirve en el primerísimo arranque: cambiarlo después en .env no cambia nada,
ni siquiera al recrear los contenedores. Lo hemos comprobado.
Trampa n.º 1: contraseñas en MD5
Al instalar con el asistente web, Dolibarr guarda MAIN_SECURITY_HASH_ALGO = password_hash
(archivo install/step5.php). La instalación automática de la imagen Docker se salta ese paso: la
línea que debía hacerlo está comentada en docker-run.sh. Sin este ajuste, Dolibarr cifra todas
las contraseñas en MD5 sin sal, incluidas las que cambie después desde la interfaz. En nuestra
instalación nueva, la contraseña cambiada desde la ficha de usuario seguía ocupando 32 caracteres en
la base de datos, la firma de un MD5.
La incidencia correspondiente del repositorio de la imagen (#14) se cerró en mayo de 2026, pero la línea sigue comentada en el script de la imagen 24.0.2.
Para saber si su instancia está afectada, abra Herramientas de administración › Sobre seguridad. Si la línea «Algoritmo para Contraseñas» indica «No definido» seguido de «(If unset: ‘md5’)», lo está.
Para corregir una instancia ya instalada:
- con una sesión de administrador, abra Configuración › Otras configuraciones y añada la
constante
MAIN_SECURITY_HASH_ALGOcon el valorpassword_hash; - sin cerrar la sesión, cambie su propia contraseña desde su ficha de usuario;
- haga que cada uno de los demás usuarios cambie su contraseña.
La página de seguridad de Dolibarr avisa de que, tras este cambio, todas las contraseñas antiguas dejan de ser válidas. En la 24.0.1 ya no es así: comprobamos que un usuario que seguía en MD5 puede seguir iniciando sesión. Pero su contraseña solo se convertirá cuando la cambie. De ahí el paso 3.
Trampa n.º 2: un cron que nunca se ejecuta
Con la configuración del ejemplo oficial (DOLI_CRON_KEY sin DOLI_ENABLE_MODULES), el contenedor
cron muestra cada cinco minutos:
Error: securitykey provided xxxxx... does not match securitykey in setup.
En Dolibarr no aparece nada: solo docker compose logs cron lo muestra. La causa: en el primer
arranque, la imagen escribe su clave actualizando la fila CRON_KEY de la base de datos, pero esa
fila solo existe una vez activado el módulo de tareas programadas. La actualización no toca ninguna
fila y la clave nunca se guarda. Activar el módulo después no basta: la clave se queda vacía.
En una instalación nueva, DOLI_ENABLE_MODULES: Cron resuelve el problema: el módulo se activa
antes de que se escriba la clave. Es la configuración de esta página.
En una instancia ya instalada, active el módulo Tareas programadas, abra su configuración y
pegue en «Clave para la URL para ejecutar tareas Cron» el valor de CRON_KEY de su archivo .env. Para comprobarlo sin
esperar:
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 respuesta debe listar las tareas con «Result of run_jobs OK», y ya no el error de clave.
Trampa n.º 3: una copia en claro de las contraseñas
Al instalar con el asistente web, Dolibarr guarda también DATABASE_PWD_ENCRYPTED = 1 (el mismo
archivo install/step5.php): este ajuste le prohíbe conservar una copia en claro de las
contraseñas. La instalación automática de la imagen no lo define, docker-run.sh no lo menciona en
ninguna parte. Sin él, cada contraseña escrita desde la interfaz se guarda dos veces: cifrada en
pass_crypted, y en claro en la columna pass de la tabla llx_user. La trampa n.º 1 no
cambia nada aquí: con password_hash la versión cifrada es buena, pero la copia en claro sigue ahí.
En nuestra instalación nueva hecha solo con la línea MAIN_SECURITY_HASH_ALGO, la contraseña de
admin cambiada en el paso 5 se leía tal cual en la base de datos. También aparecía en el código HTML
de la ficha de usuario abierta en modo edición. Con la segunda línea del script del paso 3, la
columna se queda vacía: lo comprobamos en otra instalación nueva.
Para saber si su instancia está afectada, abra Herramientas de administración › Sobre seguridad. Si la línea «Cifrar las contraseñas almacenadas en la base de datos» indica «No», lo está. Este comando lista las cuentas cuya contraseña está en claro:
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"'
Para corregir una instancia ya instalada:
- con una sesión de administrador, abra Inicio › Configuración › Seguridad, pestaña Contraseñas, y haga clic en Activar frente a «Cifrar las contraseñas almacenadas en la base de datos». Dolibarr guarda el ajuste y borra las copias en claro, pero solo las de menos de 32 caracteres: toma las más largas por antiguas huellas MD5 y las deja;
- borre las que quedan:
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"'
El inicio de sesión solo usa la versión cifrada: en nuestra prueba, una cuenta cuya copia en claro se había borrado seguía iniciando sesión. No hace falta, por tanto, que se cambien las contraseñas. Vuelva a lanzar el comando de control: ya no debe mostrar nada. Una cuenta que siguiera en la lista no tiene versión cifrada, y el comando la respeta para no bloquearla: haga que cambie su contraseña.
Lo que la imagen hace además, y conviene saber
conf.phpse reescribe cada vez que se recrea el contenedor, a partir de las variables de entorno. CambiarDOLI_URL_ROOTen.envy lanzardocker compose up -dbasta por tanto para cambiar de dirección, pero cualquier modificación hecha a mano enconf.phpdesaparece.- Las sesiones se pierden en cada recreación: tras actualizar la imagen, todo el mundo tiene que volver a iniciar sesión.
- La subida de archivos está limitada a 2 MB, aunque PHP acepte 20 MB. La imagen configura bien
PHP en 20 MB (su documentación dice 2 MB, por error), pero Dolibarr aplica su propio límite, fijado
en 2 048 KB en la instalación. En nuestra prueba, un archivo de 5 MB se rechaza con «El tamaño del
archivo es demasiado grande o no se ha proporcionado el archivo». Para subirlo, abra Inicio ›
Configuración › Seguridad, pestaña Archivos, y cambie «Tamaño máximo de los documentos a
subir» (en KB:
20480para 20 MB). Por encima de 20 MB, añada tambiénPHP_INI_UPLOAD_MAX_FILESIZEyPHP_INI_POST_MAX_SIZEa las variables. - El nombre del servicio de la base de datos debe coincidir con
DOLI_DB_HOST. Sin esta variable, la imagen busca un servidor llamadomysql, y el contenedor web espera indefinidamente.
Acceso desde Internet
No publique el puerto 8080 tal cual. Ponga delante de Dolibarr un proxy que gestione el HTTPS
(Caddy, Traefik, Nginx), escriba la dirección con https:// en DOLI_URL_ROOT y relance con
docker compose up -d. Si el proxy funciona en la misma máquina, publique el puerto solo en local
("127.0.0.1:8080:80") para que no se pueda saltar el proxy.
Copia de seguridad
La copia de seguridad desde la interfaz funciona con esta configuración (Herramientas de
administración › Copia de seguridad): el archivo llega a data/documents/admin/backup/. En línea
de comandos, el método más seguro es exportar la base de datos desde el contenedor MariaDB y luego
copiar las carpetas data/documents y data/custom, con el archivo .env:
docker compose exec -T db sh -c 'mariadb-dump -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' > copia.sql
El archivo está completo si termina con «– Dump completed».
Actualizar después
Cambie el número de versión de la imagen de una versión mayor en una, nunca directamente de la 20 a la 24: la imagen se saltaría migraciones sin avisar. El procedimiento completo, probado, está en Upgrading Dolibarr in Docker (en inglés); el método general, en Actualizar Dolibarr sin romper nada. Antes de cambiar de versión, nuestro módulo gratuito Listo para la actualización lee el código de sus módulos externos frente a la versión de destino, y comprueba PHP y la base de datos, sin modificar nada.
Si prefiere que nos encarguemos, el servicio Instalación y configuración (servicio en español, inglés, francés o alemán) parte de esta configuración.
Lea también
Preguntas frecuentes
¿Por qué las contraseñas son vulnerables con la configuración Docker oficial?
La instalación automática de la imagen se salta dos ajustes que sí define el asistente web: sin MAIN_SECURITY_HASH_ALGO = password_hash, las contraseñas se guardan en MD5 sin sal, y sin DATABASE_PWD_ENCRYPTED = 1, queda una copia en claro en la columna pass de llx_user. El script docker-init.d/contrasenas.sql de esta guía define los dos; cambie después la contraseña de admin, creada antes del script y por tanto todavía en MD5.
¿Por qué falla el contenedor cron de Dolibarr en Docker?
Con el ejemplo oficial (DOLI_CRON_KEY sin DOLI_ENABLE_MODULES), la imagen escribe la clave en la fila CRON_KEY de la base de datos antes de que exista el módulo de tareas programadas: la clave nunca se guarda y el contenedor muestra «securitykey provided … does not match securitykey in setup» cada cinco minutos. En una instalación nueva, añada DOLI_ENABLE_MODULES: Cron; en una instancia ya instalada, active el módulo Tareas programadas y pegue el valor de CRON_KEY del .env en «Clave para la URL para ejecutar tareas Cron».
¿Qué volúmenes Docker hay que conservar sí o sí para Dolibarr?
Como mínimo tres volúmenes persistentes: uno para los documentos (/var/www/documents), uno para los módulos externos (/var/www/html/custom) y uno para los datos de la base MariaDB (/var/lib/mysql).