Linux Web Hosting, DevOps, and Cloud Solutions

Installing ERPNext v15 on Debian 13 Using Docker (Production Ready Guide)





Installing ERPNext v15 on Debian 13 Using Docker (Production Guide)

Installing ERPNext v15 on Debian 13 Using Docker (Production Guide)

This guide explains how to install ERPNext v15 on a single Debian 13 server using Docker and Docker Compose, following Frappe’s recommended production approach.

The setup is suitable for:


Architecture Overview (Important to understand first)

This setup runs all ERPNext services inside Docker containers, fully isolated from the host OS.

Component Purpose
frappe/erpnext ERPNext + Frappe framework
MariaDB 10.6 ERPNext database (containerized)
Redis (cache + queue) Background jobs, caching
Docker volumes Persistent data storage
Reverse proxy SSL & domain handling

Why Docker MariaDB instead of MariaDB installed on the host?

ERPNext Docker Architecture (Interactive)

Internet
HTTPS :443
⬇ Reverse Proxy
Apache / Nginx
SSL Termination
⬇ HTTP :8080 (internal)
ERPNext Frontend
(Nginx)
ERPNext Backend
(Frappe / Bench)
Redis Cache
Redis Queue
MariaDB 10.6

Step 0 – Install Docker & Docker Compose (run as root)

apt update
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
> /etc/apt/sources.list.d/docker.list
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Step 1 – Add user to docker group (run as root)

adduser erp
usermod -aG docker erp

• Adding to docker group means you no longer need sudo to run docker commands
• Permission Alignment: All the files created will be under the user ownership

Step 2 – Install Git (run as root)

apt install -y git

Switch to non-root user

su - erp

Step 3 – Clone Frappe Docker repository (non-root)

git clone https://github.com/frappe/frappe_docker
cd frappe_docker

Step 4 – Create .env file

ERPNEXT_VERSION=v15.95.2
DB_PASSWORD=STRONG_DB_PASSWORD
FRAPPE_SITE_NAME_HEADER=example.com
HTTP_PUBLISH_PORT=8080
UPSTREAM_REAL_IP_ADDRESS=127.0.0.1
UPSTREAM_REAL_IP_HEADER=X-Forwarded-For

Note: Use a strong password for MySQL root user.

Step 5 – Fix MariaDB version (important)

By default, Frappe Docker pulls mariadb:11.8.
ERPNext v15 is tested with MariaDB ≤ 10.8.

You may see this warning:

Warning: MariaDB version ['11.8', '5'] is more than 10.8 which is not yet tested with Frappe Framework.

Edit:

overrides/compose.mariadb.yaml

Change:

image: mariadb:11.8

To:

image: mariadb:10.6

Step 6 – Start ERPNext stack

docker compose \
-f compose.yaml \
-f overrides/compose.mariadb.yaml \
-f overrides/compose.redis.yaml \
-f overrides/compose.noproxy.yaml \
up -d

Step 7 – Verify containers

docker compose ls

You should see:

Step 8 – Create ERPNext site

docker compose exec backend bench new-site example.com \
--mariadb-root-password DB_PASSWORD \
--admin-password ADMIN_PASSWORD \
--install-app erpnext

Important:
--mariadb-root-password must match DB_PASSWORD in .env
--admin-password is used to log in — note it down

Step 9 – Enable scheduler

docker compose exec backend bench --site example.com enable-scheduler
docker compose exec backend bench --site example.com scheduler enable
docker compose exec backend bench doctor
 bench doctor is your "General Health Check" tool 

Expected output:

-----Checking scheduler status-----
Workers online: 2
-----internal.shenzhen24h.com Jobs-----

Step 10 – Access ERPNext

Open in browser:

http://SERVER-IP:8080/app

Login:

Step 11 – Reverse proxy & SSL Examples

Apache

<VirtualHost *:443>
ServerName example.com
ProxyPreserveHost On
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader set X-Forwarded-Proto "https"
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
a2enmod proxy proxy_http headers rewrite
systemctl restart apache2

Nginx

server {
  listen 443 ssl;
  server_name example.com;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
  }
}

Step 12 – If no web server exists

Option A – Traefik

Option B – Caddy

Step 13 – Data persistence & backups

ERPNext data is stored in Docker volumes, not inside containers.
Containers can be safely recreated or upgraded without data loss.

Persistent Docker volumes

Important: Containers are disposable; volumes are persistent.


Recommended backup method (ERPNext-aware)

The preferred way to back up ERPNext is using bench backup inside the backend container.

docker compose exec backend bench \
  --site internal.shenzhen24h.com backup --with-files

This creates a complete backup including:

Example output:

Backup Summary for internal.shenzhen24h.com

Config  : site_config_backup.json
Database: database.sql.gz
Public  : files.tar
Private : private-files.tar

Backup completed successfully

Backups are stored inside the sites volume:

sites/internal.shenzhen24h.com/private/backups/

Optional: Volume-level backups (infrastructure safety)

For disaster recovery, you may also back up Docker volumes at the filesystem level:

This is useful for full server restores, but bench backups should still be taken regularly.

Common Issues & Fixes

Issue Fix
MariaDB 11.x warning Downgrade to 10.6
Scheduler disabled Enable manually
Login loop Missing proxy headers
RequestHeader error Enable mod_headers
Port 8080 exposed Use reverse proxy only

Best Practices

Conclusion

This setup follows Frappe’s official Docker recommendations and provides a stable, secure, production-ready ERPNext installation on Debian 13.

Exit mobile version