ERPNext is a comprehensive open-source ERP solution used by many businesses for managing various aspects of their operations. In this guide, we’ll walk you through how to set up ERPNext version 15 using Docker Compose with Portainer. This setup simplifies the installation process and ensures all services required by ERPNext are properly configured.
By the end of this guide, you will have ERPNext running on your server, accessible via a web browser. Here’s how to get started.
Prerequisites
Before we dive into the installation, ensure the following:
1. Portainer Installed: Portainer is a container management platform that simplifies the use of Docker. If you haven’t installed Portainer, you can find instructions [here]
2. Docker & Docker Compose: Docker should be installed on your system. If not, follow the Docker installation guide for your operating system: [Docker Installation]
3. Basic Knowledge of Docker and Portainer: While this guide simplifies the process, some basic knowledge will be helpful.
Step 1: Log in to Portainer
1. Open your browser and access Portainer at the IP address or domain of your server, followed by Portainer’s default port (usually `9000`), like so:
http://<your-server-ip>:9000
2. Log in with your credentials or set up an admin account if it’s your first time.
Step 2: Create a New Docker Stack
Once you are logged into Portainer, you’ll use the Docker Compose file to deploy ERPNext. Here’s how:
1. Navigate to the “Stacks” menu: On the Portainer dashboard, go to Stacks in the left-hand menu.
2. Click ‘Add stack’: This will open up a form for you to create a new stack.
Step 3: Paste the Docker Compose File
1. Name the Stack: In the Name field, provide a name for your stack (e.g., `erpnext`).
2. Paste the Docker Compose file: Copy the provided `docker-compose.yml` file (below) and paste it into the Web editor section of the form.
version: "3"
services:
backend:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: on-failure
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
configurator:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: none
entrypoint:
- bash
- -c
command:
- >
ls -1 apps > sites/apps.txt;
bench set-config -g db_host $$DB_HOST;
bench set-config -gp db_port $$DB_PORT;
bench set-config -g redis_cache "redis://$$REDIS_CACHE";
bench set-config -g redis_queue "redis://$$REDIS_QUEUE";
bench set-config -g redis_socketio "redis://$$REDIS_QUEUE";
bench set-config -gp socketio_port $$SOCKETIO_PORT;
environment:
DB_HOST: db
DB_PORT: "3306"
REDIS_CACHE: redis-cache:6379
REDIS_QUEUE: redis-queue:6379
SOCKETIO_PORT: "9000"
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
create-site:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: none
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
entrypoint:
- bash
- -c
command:
- >
wait-for-it -t 120 db:3306;
wait-for-it -t 120 redis-cache:6379;
wait-for-it -t 120 redis-queue:6379;
export start=`date +%s`;
until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
[[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
do
echo "Waiting for sites/common_site_config.json to be created";
sleep 5;
if (( `date +%s`-start > 120 )); then
echo "could not find sites/common_site_config.json with required keys";
exit 1
fi
done;
echo "sites/common_site_config.json found";
bench new-site --no-mariadb-socket --admin-password=admin --db-root-password=admin --install-app erpnext --set-default frontend;
db:
image: mariadb:10.6
healthcheck:
test: mysqladmin ping -h localhost --password=admin
interval: 1s
retries: 15
deploy:
restart_policy:
condition: on-failure
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --skip-character-set-client-handshake
- --skip-innodb-read-only-compressed # Temporary fix for MariaDB 10.6
environment:
MYSQL_ROOT_PASSWORD: admin
volumes:
- db-data:/var/lib/mysql
frontend:
image: frappe/erpnext:v15.19.1
depends_on:
- websocket
deploy:
restart_policy:
condition: on-failure
command:
- nginx-entrypoint.sh
environment:
BACKEND: backend:8000
FRAPPE_SITE_NAME_HEADER: frontend
SOCKETIO: websocket:9000
UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
UPSTREAM_REAL_IP_RECURSIVE: "off"
PROXY_READ_TIMEOUT: 120
CLIENT_MAX_BODY_SIZE: 50m
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
ports:
- "8080:8080"
queue-long:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: on-failure
command:
- bench
- worker
- --queue
- long,default,short
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
queue-short:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: on-failure
command:
- bench
- worker
- --queue
- short,default
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
redis-queue:
image: redis:6.2-alpine
deploy:
restart_policy:
condition: on-failure
volumes:
- redis-queue-data:/data
redis-cache:
image: redis:6.2-alpine
deploy:
restart_policy:
condition: on-failure
volumes:
- redis-cache-data:/data
scheduler:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: on-failure
command:
- bench
- schedule
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
websocket:
image: frappe/erpnext:v15.19.1
deploy:
restart_policy:
condition: on-failure
command:
- node
- /home/frappe/frappe-bench/apps/frappe/socketio.js
volumes:
- sites:/home/frappe/frappe-bench/sites
- logs:/home/frappe/frappe-bench/logs
volumes:
db-data:
redis-queue-data:
redis-cache-data:
sites:
logs:
Step 4: Deploy the Stack
1. Click ‘Deploy the Stack’ at the bottom of the page. Portainer will now begin deploying ERPNext using the services defined in the Docker Compose file.
2. Monitor the process: You can monitor the logs and status of each service from the Portainer dashboard to ensure everything runs correctly.
Step 5: Access ERPNext
Once the stack is deployed, you can access ERPNext through your server’s IP address or domain followed by port `8080` (as defined in the `frontend` service).
http://<your-server-ip>:8080
You should now see the ERPNext login page. Use the admin credentials you specified in the `create-site` service (`admin` as both the username and password).
Conclusion
That’s it! You’ve successfully installed ERPNext 15

2 comments
ahmed
Very nice script, worked smoothly.
could you please publish same script for Step-by-Step Guide: Installing Frappe hrms 15 Using Docker Compose with Portainer?
thanks in advance
jon
Failed to deploy a stack: redis-cache Pulling create-site Pulling queue-long Pulling db Pulling queue-short Pulling websocket Pulling scheduler Pulling redis-queue Pulling configurator Pulling backend Pulling frontend Pulling queue-long Error Get “https://registry-1.docker.io/v2/”: context deadline exceeded (Client.Timeout exceeded while awaiting headers) redis-cache Error context canceled configurator Error context canceled redis-queue Error context canceled db Error context canceled websocket Error context canceled queue-short Error context canceled create-site Error context canceled scheduler Error context canceled frontend Error context canceled backend Error context canceled Error response from daemon: Get “https://registry-1.docker.io/v2/”: context deadline exceeded (Client.Timeout exceeded while awaiting headers)