Install Dolibarr with Nginx
Install Dolibarr 24 with Nginx, PHP-FPM and MariaDB on Ubuntu or Debian, with a tested configuration. And what the sample shipped with Dolibarr gets wrong: REST API in 404, uploads blocked at 1 MB, folders only protected under Apache.
Want someone to look at your instance? Diagnosis, fixed price €90.
What was checked (versions, tests, code read)
Fresh installs on 02/11/2026 in Docker containers: Debian 13 (Nginx 1.26.3, PHP 8.4.27, MariaDB 11.8.6) with the commands on this page run as is (sudo kept, service instead of systemctl), wizard followed through to the login page, API module enabled and called with a key, invoice validated and PDF generated, 5 MB upload before and after Dolibarr's limit, Nginx log read after browsing the screens; Ubuntu 24.04 (Nginx 1.24.0, PHP 8.3.6, MariaDB 10.11.14) for steps 1 to 3 and the checks. Official sample from the 24.0.2 archive tested on Debian 13.
Dolibarr is documented mostly for Apache. It runs just as well with Nginx, as long as you take over three things Apache was quietly doing. This page installs Dolibarr 24 with Nginx, PHP-FPM and MariaDB on Debian 13 or Ubuntu 24.04, with a configuration we tested.
Dolibarr ships a sample Nginx configuration (dev/setup/nginx/dolibarr in the archive). We tried
it on a fresh install: it has three problems.
- Nginx refuses to start. The
fastcgi_passline ends with a//comment, which does not exist in Nginx syntax:nginx -tanswersunexpected "}". The socket path is also the PHP 5 one. - The REST API returns 404. Once the
//is removed,/api/index.php/statusreturns Nginx’s own “404 Not Found” page: the request never reaches Dolibarr. - The
conffolder can be read from the web. Dolibarr protects it with an.htaccessfile, which Nginx ignores. In our test, a backup copyconf.php.bakshowed up as plain text in the browser, database password included. The PHP scripts of the libraries inincludes, which Dolibarr forbids calling directly, also run.
On top of that, Nginx has its own limit: it rejects uploads larger than 1 MB, before PHP or Dolibarr ever see them. In our test, a 5 MB file got “413 Request Entity Too Large”.
The configuration below fixes all four.
1. Install Nginx, PHP-FPM and MariaDB
sudo apt update
sudo apt install -y nginx mariadb-server php-fpm php-mysql php-gd php-curl php-intl php-zip php-xml php-mbstring curl cron
Same list of extensions as with Apache, with php-fpm instead of the Apache module.
2. Download Dolibarr and create the database
Both steps are the same as with Apache: on Debian and Ubuntu, PHP-FPM also runs as the www-data
user.
cd /tmp
curl -fL -o dolibarr-24.0.2.tgz "https://sourceforge.net/projects/dolibarr/files/Dolibarr%20ERP-CRM/24.0.2/dolibarr-24.0.2.tgz/download"
sudo tar --no-same-owner -xzf /tmp/dolibarr-24.0.2.tgz -C /var/www
sudo mv /var/www/dolibarr-24.0.2 /var/www/dolibarr
sudo mkdir -p /var/lib/dolibarr/documents
sudo touch /var/www/dolibarr/htdocs/conf/conf.php
sudo chown www-data:www-data /var/www/dolibarr/htdocs/conf/conf.php
sudo chown -R www-data:www-data /var/lib/dolibarr/documents /var/www/dolibarr/htdocs/custom
DBPASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 24); echo "Database password: $DBPASS"
sudo mariadb -e "CREATE DATABASE dolibarr CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'dolibarr'@'localhost' IDENTIFIED BY '$DBPASS';
GRANT ALL PRIVILEGES ON dolibarr.* TO 'dolibarr'@'localhost';"
Write down the password shown: the wizard will ask for it.
3. The Nginx configuration
PHPV=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
sudo tee /etc/nginx/sites-available/dolibarr > /dev/null <<CONF
server {
listen 80;
listen [::]:80;
server_name dolibarr.example.com;
root /var/www/dolibarr/htdocs;
index index.php;
# By default Nginx rejects any upload above 1 MB
client_max_body_size 20M;
access_log /var/log/nginx/dolibarr_access.log;
error_log /var/log/nginx/dolibarr_error.log;
location / {
try_files \$uri \$uri/ =404;
}
# What Dolibarr's .htaccess files do under Apache
location ^~ /conf/ {
deny all;
}
location ~ ^/includes/.+\.php$ {
deny all;
}
location ~ /\.(?!well-known) {
deny all;
}
location ~ [^/]\.php(/|$) {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php$PHPV-fpm.sock;
fastcgi_read_timeout 600;
}
}
CONF
sudo ln -s /etc/nginx/sites-available/dolibarr /etc/nginx/sites-enabled/dolibarr
sudo rm /etc/nginx/sites-enabled/default
sudo tee /etc/php/$PHPV/fpm/conf.d/99-dolibarr.ini /etc/php/$PHPV/cli/conf.d/99-dolibarr.ini > /dev/null <<'INI'
upload_max_filesize = 20M
post_max_size = 22M
date.timezone = Europe/Paris
INI
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php$PHPV-fpm
Replace dolibarr.example.com with your server name, and Europe/Paris with your time zone.
What changes compared with the official sample:
snippets/fastcgi-php.conf, shipped with the Debian and Ubuntu Nginx package, splits the script name from the rest of the address and passes the rest to PHP (PATH_INFO). That is what the REST API needs. The official sample checks that the full address is a file (try_files $uri =404), which returns 404 for/api/index.php/thirdparties.client_max_body_size 20Mmatches Nginx to the 20 MB PHP accepts.- The three
denyblocks replace the.htaccessfiles: theconffolder can no longer be reached from the web, the PHP scripts of the libraries inincludescan no longer be called directly, and hidden files (.git,.htaccess…) are not served. $PHPVpicks the right socket: PHP 8.4 on Debian 13, PHP 8.3 on Ubuntu 24.04.
sudo nginx -t must answer “syntax is ok” and “test is successful” before the reload.
4. The wizard, install.lock and the 2 MB limit
The rest is the same as with Apache, detailed in Install Dolibarr on Ubuntu or Debian:
- open
http://your-server/install/, and on the configuration page replace the documents folder with/var/lib/dolibarr/documents; - close the installation:
sudo touch /var/lib/dolibarr/documents/install.lock
sudo chmod 400 /var/www/dolibarr/htdocs/conf/conf.php
sudo find /var/www/dolibarr/htdocs -path /var/www/dolibarr/htdocs/custom -prune -o -exec chmod a-w {} +
- raise Dolibarr’s own limit (2,048 KB) in Home › Setup › Security › Files to
20480.
The three limits go together: Nginx (client_max_body_size), PHP (upload_max_filesize) and
Dolibarr. Whichever stays lower is the one that rejects the file.
5. Check that everything is in place
On the server:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/conf/conf.php
curl -s -o /dev/null -w "%{http_code}\n" http://localhost/includes/sabre/autoload.php
curl -s http://localhost/api/index.php/status
The first two lines must answer 403: the conf folder and the includes scripts are closed.
The third shows that the API does reach Dolibarr. The API module is disabled after installation:
the answer then says the Api module must be enabled. Once the module is enabled
(Home › Setup › Modules/Applications), the same address answers 401 without a key, and
returns the Dolibarr version with a key. If you get Nginx’s “404 Not Found” page, the rest of the
address (PATH_INFO) does not reach PHP: check the include snippets/fastcgi-php.conf line.
The deny blocks do not get in the way of the interface: no Dolibarr screen calls a PHP script
from includes (we checked the 24.0.2 code), and browsing the third parties, products, invoices,
agenda, TakePOS and setup screens left no 403 error in the Nginx log.
Before opening it to the Internet
This configuration answers over HTTP. Before opening it to the Internet, add a certificate
(Certbot can edit an Nginx configuration), then change the address to https:// in the
$dolibarr_main_url_root line of conf.php. This step needs a real domain name: we did not test
it here.
Next
If you would rather have us handle it, the Installation and setup package starts from this configuration.