ERPNext is a free and open-source generic ERP(Enterprise Resource Planning) tool, developed by Frappé Technologies Pvt. Ltd. It is built on the MariaDB database with a Python-based server-side framework. ERPNext provides an alternative to QAD and NetSuite. It offers similar functionality to Odoo, (formerly known as OpenERP), Openbravo and Tryton.

ERPNext is used by companies, manufacturers, and distributors around the world. It supports several modules such as accounting, purchasing, manufacturing, warehouse, point of sale, trading, and inventory retailing, as well as domain-specific modules such as agriculture, non-profits, schools, and healthcare.

The amazing features offered by the ERPNext ERP System are:

  • Light on the system resources
  • 24/7/365 technical support
  • Automatic hosting upgrades
  • Error repair guarantee
  • Backup and redundancy
  • Kubernetes cloud platform
  • Transaction email
  • Free SSL Installation for each domain using Let’s Encrypt.
  • One-Click Installation
  • phpMyAdmin GUI tool for database management
  • Free Migration onto the cloud platform of ERPNext hosting.
  • Monitoring Console to access the metrics dashboard to monitor the resource usage on your cloud ERPNext hosting plan
  • Highly modular to allow easy customization

In this guide, we will walk through how to run ERPNext ERP System in Docker Containers.

1. Install Docker and Docker Compose

This guide requires you to have the Docker Engine installed on your system. This can be done using the guide below:

Add your system user to the Docker group,

sudo usermod -aG docker $USER
newgrp docker

Start and enable the service:

sudo systemctl start docker && sudo systemctl enable docker

Also, install Docker Compose:

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 protected]' >> ~/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:

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.

  • For one.example.com
docker compose --project-name erpnext-one exec backend \
  bench new-site one.example.com --mariadb-root-password StrongPassw0rd --install-app erpnext --admin-password StrongPassw0rd
  • For two.example.com

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:

ERPNext ERP System in Docker Containers

Once logged in, start by making basic configurations. Se the preferred language, country, and timezone.

ERPNext ERP System in Docker Containers 1

Next, create your first user.

ERPNext ERP System in Docker Containers 2

Create the company/organization

ERPNext ERP System in Docker Containers 3

Define the organization type.

ERPNext ERP System in Docker Containers 4

Once provided, the system will initialize

ERPNext ERP System in Docker Containers 5

And there you go! This is the ERPNext ERP System dashboard.

ERPNext ERP System in Docker Containers 6

From this dashboard, you can perform the desired activities.

7. Getting Started with ERPNext ERP System

I will demonstrate how to get started with ERPNext ERP System and make transactions. Begin by clicking on company.

ERPNext ERP System in Docker Containers 7

We already have a company created, you can also create other companies if you need to.

Once the desired company with currency has been created, go back to the accounting tab and select Chart of accounts

ERPNext ERP System in Docker Containers 8

This shows the accounting ledgers for each transaction in your company. Once you have an account with the chart of accounts, you can now go back to the Home page and create the desired item.

This can be a product or a service offered by the company.

ERPNext ERP System in Docker Containers 9

Create the desired item by clicking on Create a new Item

ERPNext ERP System in Docker Containers 10

Once saved, refresh to view the items.

ERPNext ERP System in Docker Containers 11

Now create a customer you want to do business with under accounting->Customer

ERPNext ERP System in Docker Containers 12

Provide the customer details

ERPNext ERP System in Docker Containers 13

Once added, the customer will appear as shown.

ERPNext ERP System in Docker Containers 14

Next, create a supplier for the items created under accounting->Supplier

ERPNext ERP System in Docker Containers 15

Once the item, customer, and supplier details have been added, you are set to do transactions using ERPNext.

Let’s create a sales order by searching as shown.

ERPNext ERP System in Docker Containers 16

A sales order has the customer, delivery date, item code, and quantity.

ERPNext ERP System in Docker Containers 17

Clicking save, saves the transaction in draft mode and can be edited. Once submitted, you cannot make any changes to it.

ERPNext ERP System in Docker Containers 18

You can now print the sales order and you can also send the transaction using SMS, email e.t.c.

ERPNext ERP System in Docker Containers 19

8. Manage the ERPNext ERP System Docker Containers

The ERPNext ERP System Docker Containers can be managed with the following commands:

cd ~/frappe_docker
  • For Traefik
##Stop
docker-compose --project-name traefik \
--env-file ~/gitops/traefik.env \
-f overrides/compose.traefik.yaml stop

##Start
docker-compose --project-name traefik \
--env-file ~/gitops/traefik.env \
 -f overrides/compose.traefik.yaml start
  • For MariaDB
##Stop
docker compose --project-name mariadb \
--env-file ~/gitops/mariadb.env \
-f  overrides/compose.mariadb-shared.yaml stop

##Start 
docker compose --project-name mariadb \
--env-file ~/gitops/mariadb.env \
-f  overrides/compose.mariadb-shared.yaml start
  • For ERPNext
##Stop
docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml stop

##Start
docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml start

Verdict

That marks the end of this guide on how to run ERPNext ERP System in Docker Containers. You can now perform transactions with accounting, purchasing, manufacturing, warehouse, point of sale, trading, and inventory retailing options. I hope this was significant to you.

See more:

11 COMMENTS

  1. Step #2 needs updating. The docs directory no longer contains any subdirectories. New steps should look like this:

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

    • I am also looking for “overrides/compose.erpnext.yaml” which has been removed?

      I have found it in some forked repositories but am unsure whether I can use it?

      Thanks for your comment about the docs/compose directory being moved!
      This guide is a real life saver and I would just like to clear the water for less experienced users as myself 😀

  2. First Thanks for you great tutorial, you have saved a lot of my hard works.

    I have a fews questions need your help:
    can I change folder mount `/mnt/data/sites` to something like this `/mnt/data1/sites `

  3. thax for you great tutorial,
    in my case,restart PC,use #8. Manage the ERPNext ERP System Docker Containers.
    but can’t access erpnext web.
    it’s only first time can access.
    how can i fix it?

    • Hello @Yasar,
      To install any apps in the sites, you can use the command with the syntax:
      bench --site site-name install-app app-name

      Using the example provided here, the command will be:
      docker compose --project-name erpnext-one exec backend \
      bench new-site one.example.com --mariadb-root-password StrongPassw0rd --install-app app-name --admin-password StrongPassw0rd

      Replace app-name with the app to be installed.

LEAVE A REPLY

Please enter your comment!
Please enter your name here