[Tutorial][Docker] Installing ERPNext-16 on Docker: A Step-by-Step Guide [Production]

ERPNext v16 Production Deployment using Docker

This guide explains how to deploy ERPNext v16 in production using Docker, based on official Frappe resources and real-world tested steps.

References

  1. Frappe Forum Guide
    https://discuss.frappe.io/t/tutorial-docker-installing-erpnext-15-on-docker-a-step-by-step-guide-production/111731

  2. Official Frappe Docker Docs
    https://github.com/frappe/frappe_docker/blob/main/docs/02-setup/07-single-server-example.md


1. Prerequisites

1.1 Server Requirements

Minimum recommended configuration for production:

  • RAM: 8 GB

  • CPU: 4 Cores

  • Storage: 160 GB SSD

1.2 Operating System

  • OS: Ubuntu 24.04 or higher

1.3 Software Requirements

  • Docker: Latest stable version

  • Python: >= 3.14 and < 3.15

  • Node.js: 24.x


2. Firewall & Port Configuration

Ensure the following ports are open on your server firewall:

Service Port
SSH 22
HTTP 80
HTTPS 443

3. Create a Linux User for Frappe

Create a dedicated Linux user (recommended for security).

sudo adduser frappe
sudo usermod -aG sudo frappe
su - frappe

Verify Access

whoami
sudo ls


4. Install Docker

Install Docker Engine and configure it properly for non-root usage.

Official Docs (Follow Carefully)

Make sure:

  • Docker is installed

  • frappe user is added to the docker group

  • docker ps works without sudo

If you’re unsure, refer to trusted tutorials or videos.


5. Custom Apps (Optional)

If you use custom apps

You must authenticate GitHub using a Personal Access Token (PAT).

Example APPS_JSON with custom app

https://<USERNAME>:<GITHUB_TOKEN>@github.com/<USERNAME>/<CUSTOM_APP>.git

Example

https://antony:ghp_1234567890abcdef1234567890abcdef@github.com/antony/my_custom_app.git


6. Apps Configuration (No Custom App Case)

below command without custom app.

export APPS_JSON='[
  { "url": "https://github.com/frappe/erpnext", "branch": "version-16" },
  { "url": "https://github.com/frappe/hrms", "branch": "version-16" },
  { "url": "https://github.com/frappe/email_delivery_service", "branch": "main" },
  { "url": "https://github.com/resilient-tech/india-compliance", "branch": "version-16" },
  { "url": "https://github.com/frappe/crm", "branch": "main" },
  { "url": "https://github.com/erpnextai/next_ai", "branch": "main" }
]'

Encode it:

export APPS_JSON_BASE64=$(echo ${APPS_JSON} | base64 -w 0)


7. Clone Frappe Docker

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


8. Build Custom Docker Image

Choose Versions

  • Frappe: v16.7.0

  • Python: 3.14.0

  • Node.js: 24.13.0

Check versions here:

Build Command

Takes 10–15 minutes. Be patient.

docker build \
  --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \
  --build-arg=FRAPPE_BRANCH=v16.7.0 \
  --build-arg=PYTHON_VERSION=3.14.0 \
  --build-arg=NODE_VERSION=24.13.0 \
  --build-arg=APPS_JSON_BASE64=$APPS_JSON_BASE64 \
  --tag=customapp:1.0.0 \
  --file=images/custom/Containerfile .


9. DNS Configuration

Add an A record pointing to your server’s IPv4 address.

Example:

myerpnext.online → <SERVER_IPV4>

image


10. Update Docker Compose Image

Edit compose.yaml:

x-customizable-image: &customizable_image
  image: customapp:1.0.0
  pull_policy: never


11. Create GitOps Directory

mkdir ~/gitops


12. Traefik Configuration

Replace domain and email accordingly.

  • Here Im assume im using the domain myerpnext.online . you can change your domain accordingly
  • Important note i used my HASHED_PASSWORD as a mypassword. but in your case you have to chose some strong password
echo 'TRAEFIK_DOMAIN=myerpnext.online' > ~/gitops/traefik.env
echo 'EMAIL=admin@myerpnext.online' >> ~/gitops/traefik.env
echo 'HASHED_PASSWORD='$(openssl passwd -apr1 mypassword | sed 's/\$/\\\$/g') >> ~/gitops/traefik.env

:warning: Use a strong password in production.


13. Start Traefik

docker compose --project-name traefik \
  --env-file ~/gitops/traefik.env \
  -f overrides/compose.traefik.yaml \
  -f overrides/compose.traefik-ssl.yaml up -d


14. MariaDB Setup

Note: Replace DB_PASSWORD with a strong, secure password; this command creates a mariadb.env file inside the gitops folder—if it is not created automatically, create it manually and add DB_PASSWORD=<your_secure_password>.

Start MariaDB:

docker compose --project-name mariadb \
  --env-file ~/gitops/mariadb.env \
  -f overrides/compose.mariadb-shared.yaml up -d


15. ERPNext Environment Configuration

  1. Carefully update only the required values — change your domain (replace only myerpnext.online, do not modify erp.example.com) and update the DB Password.

  2. Do not change any other configuration values apart from the specified domain and password.

  3. Verify all changes properly before running the command.

:warning: Change only the domain and DB password. Do NOT touch erp.example.com elsewhere.

cp example.env ~/gitops/erpnext-one.env
sed -i 's/DB_PASSWORD=123/DB_PASSWORD=mypassword/g' ~/gitops/erpnext-one.env
sed -i 's/DB_HOST=/DB_HOST=mariadb-database/g' ~/gitops/erpnext-one.env
sed -i 's/DB_PORT=/DB_PORT=3306/g' ~/gitops/erpnext-one.env
sed -i 's/SITES_RULE=Host(`erp.example.com`)/SITES_RULE=Host(`myerpnext.online`)/g' ~/gitops/erpnext-one.env
sed -i 's/NGINX_PROXY_HOSTS=erp.example.com/NGINX_PROXY_HOSTS=myerpnext.online/g' ~/gitops/erpnext-one.env
echo 'ROUTER=erpnext-one' >> ~/gitops/erpnext-one.env
echo 'BENCH_NETWORK=erpnext-one' >> ~/gitops/erpnext-one.env


16. Generate Final Compose File

Create erpnext-one.yaml file in the gitops folder

docker compose --project-name erpnext-one \
  --env-file ~/gitops/erpnext-one.env \
  -f compose.yaml \
  -f overrides/compose.redis.yaml \
  -f overrides/compose.multi-bench.yaml \
  -f overrides/compose.multi-bench-ssl.yaml \
  config > ~/gitops/erpnext-one.yaml


17. Deploy ERPNext Containers

docker compose --project-name erpnext-one \
  -f ~/gitops/erpnext-one.yaml up -d


18. Create ERPNext Site

  1. Create the site using myerpnext.online, but make sure to replace myerpnext.online with your actual domain name before running the command.

  2. In the command, both the site password and DB password are set as mypassword; replace every occurrence of mypassword with strong, secure passwords.

  3. Important: Do not use the same password for both the site and the database — use two different strong passwords.

:warning: Do NOT use the same password for Admin and DB.

docker compose --project-name erpnext-one exec backend \
bench new-site --db-root-password mypassword --admin-password mypassword --mariadb-user-host-login-scope=% myerpnext.online


19. Enter Backend Container

docker exec -it erpnext-one-backend-1 bash


20. Enable Scheduler

bench --site myerpnext.online enable-scheduler
bench use myerpnext.online


21. Install Apps

bench install-app erpnext
bench install-app hrms
bench install-app email_delivery_service
bench install-app india_compliance
bench install-app next_ai

More info about NextAI

Migrate:

bench migrate


22. Troubleshooting

Site Not Working?

  1. Wait 5–10 minutes

  2. Restart containers

docker compose --project-name erpnext-one \
  -f ~/gitops/erpnext-one.yaml down

docker compose --project-name erpnext-one \
  -f ~/gitops/erpnext-one.yaml up -d

Try 2–3 times if needed.


5 Likes

Thanks @Antony_Praveenkumar it really helps. Good work!

1 Like