A Step-by-Step Guide to Running Frappe ERPNext System in Docker Containers
Introduction: In the dynamic landscape of enterprise resource planning, ERPNext stands out as a versatile and powerful solution. To streamline the deployment process and enhance flexibility, utilizing Frappe Docker is a practical approach. This guide will walk you through the step-by-step process of setting up ERPNext using Frappe Docker, including the installation of custom apps for tailored functionality.
Prerequisites: Before diving into the installation process, ensure that you have Docker and Docker Compose installed on your system. Familiarity with ERPNext and Frappe framework basics is also recommended.
Also, install Docker Compose:
A Comprehensive Guide to Installing Docker CE on Various Linux Systems
Start and enable the service:
sudo usermod -aG docker $USER
newgrp docker
sudo systemctl start docker && sudo systemctl enable docker
Step 1: Clone Frappe Docker Repository
Begin by cloning the Frappe Docker repository from GitHub. Open your terminal and execute the following command:
Now clone the frappe_docker repo for the needed YAML files.
cd ~/
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
Once in the directory, create a directory for resources and configs.
mkdir ~/gitops
Ensure OpenSSL is installed:
##On Debian/Ubuntu
sudo apt install openssl
##On CentOS/Rocky/Alma Linux
sudo yum install openssl
#2. Install Traefik Ingress
Traefik ingress acts as an internal load balancer for multiple benches and sites hosted on the server. It will be used to expose port 80 or 443 and also take care of Letsencrypt automation for all sites installed on the server.
In this guide, we will expose port 80 but it is also possible to provide an FQDN for SSL encryption.
First, export the variables for the domain name and Letsencrypt notification email:
echo 'TRAEFIK_DOMAIN=traefik.example.com' > ~/gitops/traefik.env
echo 'EMAIL=admin@example.com' >> ~/gitops/traefik.env
echo 'HASHED_PASSWORD='$(openssl passwd -apr1 Passw0rd | sed 's/\$/\\\$/g') >> ~/gitops/traefik.env
This will create a file at ~/gitops/traefik.env with the above variables. You must ensure that your DNS entry points to the Server IP.
$ sudo vim /etc/hosts
192.168.205.11 traefik.example.com
Once created, you can use the file to run a Traefik container as shown.
docker compose --project-name traefik \
--env-file ~/gitops/traefik.env \
-f overrides/compose.traefik.yaml up -d
If you have an FQDN, and you want to run the container with SSL automation, (expose port 443)you need to include the compose.traefik-ssl.yaml as shown:
docker compose --project-name traefik \
--env-file ~/gitops/traefik.env \
-f overrides/compose.traefik.yaml \
-f overrides/compose.traefik-ssl.yaml up -d
Verify if the container is running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4c7000a029c traefik:v2.6 "/entrypoint.sh --pr…" 24 seconds ago Up 22 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp traefik-traefik-1
#3. Install MariaDB Database
In this setup, we will deploy a single MariaDB database instance that will serve as a database service for all the benches and projects installed on the server.
Create an environment file in ~/gitops
echo "DB_PASSWORD=StrongPassw0rd" > ~/gitops/mariadb.env
Change StrongPassw0rd to a preferred password for the database.
Now start the container using Docker Compose as shown:
docker compose --project-name mariadb --env-file ~/gitops/mariadb.env -f overrides/compose.mariadb-shared.yaml up -d
Once created, check if the container is running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18692eeb5c15 mariadb:10.6 "docker-entrypoint.s…" 7 seconds ago Up 6 seconds (healthy) 3306/tcp mariadb-database
f4c7000a029c traefik:v2.6 "/entrypoint.sh --pr…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp traefik-traefik-1
You will all have the data persist in the directory ${HOME}/data/mariadb
#4. Create Persistent Volumes
For ERPNext to persist its data, we need to create and map the volumes correctly. For this guide, I will create a data directory at /mnt/data
Create the persistent volume:
ADVERTISING
sudo mkdir -p /mnt/data/sites
Set the required permissions:
sudo chmod 775 -R /mnt/data
sudo chown -R $USER:docker /mnt/data
On RHEL-based systems, set SELinux in permissive mode:
sudo setenforce 0
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
Now create the docker volume for sites
docker volume create --driver local \
--opt type=none \
--opt device=/mnt/data/sites \
--opt o=bind sites
Once created, verify with the command:
$ docker volume list
DRIVER VOLUME NAME
local sites
.......
#5. Run ERPNext ERP System on Docker
The ERPNext instance creates its Redis, socketio, Gunicorn, Nginx, workers, and scheduler. It will use the internal MariaDB network to connect to the running instance and expose the service using Traefik.
We will begin by creating a bench with the name erpnext-one with two sites named one.example.com and two.example.com.
cp example.env ~/gitops/erpnext-one.env
sed -i 's/DB_PASSWORD=123/DB_PASSWORD=StrongPassw0rd/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
echo 'ROUTER=erpnext-one' >> ~/gitops/erpnext-one.env
echo "SITES=\`one.example.com\`,\`two.example.com\`" >> ~/gitops/erpnext-one.env
echo "BENCH_NETWORK=erpnext-one" >> ~/gitops/erpnext-one.env
After these commands, you will have an environment file created as ~/gitops/erpnext-one.env.
Also, create a YAML file in the ~/gitops directory.
- For HTTP:
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 config > ~/gitops/erpnext-one.yaml
- For HTTPS
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
Modify your compose YAML file to accommodate the volumes created:
vim compose.yaml
At the end of the file, make the below modifications on the volumes:
# ERPNext requires local assets access (Frappe does not)
volumes:
sites:
external: true
You can now spin the container using the configs:
docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml up -d
Check if the containers created are running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da4cfc1b874f frappe/erpnext:v14.29.1 "nginx-entrypoint.sh" 21 seconds ago Up 4 seconds erpnext-one-frontend-1
1a999b50b096 frappe/erpnext:v14.29.1 "node /home/frappe/f…" 21 seconds ago Up 6 seconds erpnext-one-websocket-1
b0fae8a010ba frappe/erpnext:v14.29.1 "/home/frappe/frappe…" 21 seconds ago Up 6 seconds erpnext-one-backend-1
a566f522bbc2 frappe/erpnext:v14.29.1 "bench schedule" 21 seconds ago Up 5 seconds erpnext-one-scheduler-1
a974b313570b frappe/erpnext:v14.29.1 "bench worker --queu…" 21 seconds ago Up 5 seconds erpnext-one-queue-short-1
4b88d00b8b2b frappe/erpnext:v14.29.1 "bench worker --queu…" 21 seconds ago Up 6 seconds erpnext-one-queue-default-1
380d8ae1399d frappe/erpnext:v14.29.1 "bench worker --queu…" 21 seconds ago Up 6 seconds erpnext-one-queue-long-1
4c14b3e32141 redis:6.2-alpine "docker-entrypoint.s…" 21 seconds ago Up 19 seconds 6379/tcp erpnext-one-redis-socketio-1
3388eba79163 redis:6.2-alpine "docker-entrypoint.s…" 21 seconds ago Up 19 seconds 6379/tcp erpnext-one-redis-cache-1
eb140fd2bcfa redis:6.2-alpine "docker-entrypoint.s…" 21 seconds ago Up 19 seconds 6379/tcp erpnext-one-redis-queue-1
18692eeb5c15 mariadb:10.6 "docker-entrypoint.s…" 7 minutes ago Up 7 minutes (healthy) 3306/tcp mariadb-database
700b6fb1b9ac traefik:v2.6 "/entrypoint.sh --pr…" 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp traefik-traefik-1
Now create the sites.
docker compose --project-name erpnext-one exec backend \
bench new-site one.example.com --mariadb-root-password StrongPassw0rd --install-app erpnext --admin-password StrongPassw0rd
You can only proceed with this option if you need a single bench multi-site setup.
docker compose --project-name erpnext-one exec backend \
bench new-site two.example.com --mariadb-root-password StrongPassw0rd --install-app erpnext --admin-password StrongPassw0rd
#6. Access the ERPNext ERP System WebUI
At this point, you can access any of your sites created on the beach with the URL. For example http://one.example.com or https://one.example.com
I assume that you have and DNS entry pointing to the Server IP. For example:
$ sudo vim /etc/hosts
192.168.205.11 one.example.com
You need to log in using the created admin password for the site as shown:
Conclusion: Setting up ERPNext using Frappe Docker streamlines the deployment process, enhances scalability, and facilitates customization. By incorporating custom apps, organizations can tailor ERP functionality to meet specific business requirements. This guide empowers users to navigate the intricacies of Frappe Docker, unlocking the full potential of ERPNext for their unique needs.
Feel free to adapt and expand upon these steps based on your specific use case, and embark on a seamless ERPNext journey with Frappe Docker.