10 Step Guide to deploy ERPNext using Docker Container with a custom domain in Ubuntu 24.04 LTS with HRMS and India Compliance Apps
Summary: ERPNext and Frappe have emerged as the ERP of choice among small and medium enterprises (SMEs) and nonprofits across many regions worldwide, including manufacturing, distribution, retail, healthcare, education, services, non-profit organizations, and agriculture industries. This article outlines the method for deploying custom apps in a virtual machine with custom apps.
Keywords: ERPNext, Frappe, open-source ERP, SME digitization, nonprofit digitization
Update 1 (Jan 15, 2025): Step 1: Preparing the Virtual Machine (Added ufw for SSH port); Step 5: Create a Custom App Docker Image: Provides docker buildx command
Introduction to ERPNext and Frappe Framework
Frappe is an open-source, modern, and full-stack web framework in Python and JavaScript. It serves as the foundation for ERPNext and provides:
RPNext is a comprehensive, open-source Enterprise Resource Planning (ERP) system built on the Frappe Framework. It offers:
Objective
At the end of this article, you shall have a fully functional and production-ready ERPNext and Frappe framework in your virtual machine (VM).
Step 1: Preparing the Virtual Machine
For this article, we have taken the example of Ubuntu 24.04 LTS. However, any Linux distro shall be able to meet this requirement, because we are using Docker to deploy the ERP framework. For the VM (I have used x86/64), we recommend a minimum of 2 vCPUs, 8 GB RAM, and 20 GB hard disk.
Once you have SSHed into your VM, install Docker. Docker installation commands are available on the Docker website here. However, the convenient script is easier to use. Remember the script also installs Docker Compose by default. You don't need to run an additional Docker Compose script (as suggested in ERPNext documentation) on top of it here.
curl -fsSL https://get.docker.com | bash
Once you have run the Docker script, test it with docker version and docker compose version to get both Docker and Docker Compose are installed in the VM.
Next, we will allow common ports (80 and 443) to UFW using these commands.
# Allow HTTP
sudo ufw allow 80/tcp
# Allow HTTPS
sudo ufw allow 443/tcp
#Allow SSH (this is important, because without it you will lose access to VM)
sudo ufw allow 22/tcp
# Check UFW status
sudo ufw enable
sudo ufw status
In your favorite folder (for example at ~/home) you can then clone frappe_docker. Frappe docker repository is available here: https://github.com/frappe/frappe_docker and create a ~/gitops directory under the same root directory (e.g., ~/home).
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
# Create gitops directory from frappe_docker directory itself
mkdir ~/gitops
Step 2: Installing Traefik Router
Traefik is a modern, cloud-native reverse proxy and load balancer that simplifies the management of microservices and APIs. It supports dynamic service discovery, automatic SSL/TLS certificates, traffic routing, and integration with container orchestration platforms like Docker, Kubernetes, and more. You can use Nginx, instead of traefik as well. This article uses traefik as the router and load balancer.
Before you begin installing traefik, add the domain to your DNS provider such as Godaddy. Add an A record with 'traefik' as the name and IP address of the VM as value and TTL 600 seconds, so that traefik.yourdomain.com resolves to the traefik service in your VM.
Then, run the following command. Before running the command make changes in domain name, email, and password chageit.
echo 'TRAEFIK_DOMAIN=traefik.yourdomain.com' > ~/gitops/traefik.env
echo '[email protected]' >> ~/gitops/traefik.env
echo 'HASHED_PASSWORD='$(openssl passwd -apr1 changeit | sed -e s/\\$/\\$\\$/g) >> ~/gitops/traefik.env
Then start the traefik container using docker-compose:
docker compose --project-name traefik \
--env-file ~/gitops/traefik.env \
-f overrides/compose.traefik.yaml \
-f overrides/compose.traefik-ssl.yaml up -d
Check if the traefik container is running using docker ps and you will see the traefik container running locally. You can open your browser at https://traefik.yourdomain.com to go to the traefik page and log in using the password you mentioned above.
领英推荐
Step 3: Installing Maria DB
MariaDB is an open-source, high-performance relational database management system, designed as a drop-in replacement for MySQL. In this step, we will create and run Maria DB as an independent service in the VM. First, create a secure password using the command and keep the password handy for use in the subsequent steps.
echo "DB_PASSWORD= changeit" > ~/gitops/mariadb.env
Then, spin off a Maria DB service using docker compose:
docker compose --project-name mariadb --env-file ~/gitops/mariadb.env -f overrides/compose.mariadb-shared.yaml up -d
Check if the Maria DB is running with docker ps.
Step 4: Create Custom App Format
Frappe_Docker's documentation provides an example apps.json to create custom app. For this article, I have taken the following example that includes ERPNext (required), payments, HRMS, and india-compliance (app name: india_compliance). You can get the GitHub URL of the apps by visiting the app's GitHub repository. To create the apps.json, use sudo nano apps.json and then provide these values. Save the apps.json file.
[
{
"url": "https://github.com/frappe/erpnext",
"branch": "version-15"
},
{
"url": "https://github.com/frappe/payments",
"branch": "version-15"
},
{
"url": "https://github.com/frappe/hrms",
"branch": "version-15"
},
{
"url": "https://github.com/resilient-tech/india-compliance",
"branch": "version-15"
}
]
You can export the file in BASE64 format: echo -n ${APPS_JSON_BASE64} | base64 -d > apps-test-output.json. Check if you are getting the BASE64 using echo $APPS_JSON_BASE64.
Step 5: Create a Custom App Docker Image
Once the apps definition is available for us, we need to create the Docker image of the custom app using docker compose:
docker buildx build \
--build-arg "FRAPPE_PATH=https://github.com/frappe/frappe" \
--build-arg "FRAPPE_BRANCH=version-15" \
--build-arg "PYTHON_VERSION=3.11.9" \
--build-arg "NODE_VERSION=18.20.2" \
--build-arg "APPS_JSON_BASE64=$APPS_JSON_BASE64" \
--tag frappe_custom:latest \
--file images/custom/Containerfile .
Note that the tag for the app is using frappe_custom:latest. Check the docker image built using docker images.
Step 6: Create a Custom Env
At this step, we will create a custom env that allows us to use the custom image that is created above and pass CUSTOM_IMAGE, CUSTOM_TAG, and PULL_POLICY variables to the env file. These tags are essentially telling the env and docker compose to use the locally available frappe_custom image, instead of trying to look for an external image container.
Before running this command, change the DB_PASSWORD to the one you opted above and bind the erp domain in your DNS provider with VM's IP address.
cp example.env ~/gitops/erpnext-one.env
sed -i 's/DB_PASSWORD=123/DB_PASSWORD= changeit/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=`erp.example.com`/SITES=`erp.yourdomain.com`/g' ~/gitops/erpnext-one.env
echo 'ROUTER=erpnext-one' >> ~/gitops/erpnext-one.env
echo "BENCH_NETWORK=erpnext-one" >> ~/gitops/erpnext-one.env
echo "CUSTOM_IMAGE=frappe_custom" >> ~/gitops/erpnext-one.env
echo "CUSTOM_TAG=latest" >> ~/gitops/erpnext-one.env
echo "PULL_POLICY=never" >> ~/gitops/erpnext-one.env
Step 7: Generate a Custom Docker Compose File
Before you can run a docker compose command, we need to create a custom docker compose file that uses the variables from the custom env. Use this command:
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
Step 8: Spin-off ERPNext and Frappe Docker Containers
Now run the docker compose to spin off the docker containers. This will install the core ERPNext and other custom apps.
docker compose --project-name erpnext-one -f ~/gitops/erpnext-one.yaml up -d
Step 9: Run ERPNext Site
To create the first ERPNext site, run the command. Update the passwords you have used to set for MariaDB and provide a new admin password.
docker compose --project-name erpnext-one exec backend \
bench new-site --mariadb-user-host-login-scope=% --db-root-password changeit --install-app erpnext --install-app payments --install-app hrms --install-app india_compliance --admin-password changeit erp.yourdomain.com
Step 10: Log in ERPNext
Now go to your site at erp.yourdomain.com to get the user interface. Default username is 'administrator' and the password you have set in step 9 above.