ERPNext Docker Image as an alternative to Official ERPNext Docker Repo


I just want to share my ERPNext Docker Image as an alternative to Official ERPNext Docker Repo

It’s a self-contained ERPNext Docker Image base on Debian 9.

For newcomers who want to try ERPNext it is super easy after installed Docker you can launch ERPNext using one command. (For better experience you should pull image first docker pull pipech/erpnext-docker-debian:mas-py2-latest)

docker run -d -p 8000:8000 -p 9000:9000 pipech/erpnext-docker-debian:mas-py2-latest

It comes with yml file which make it suitable for development and production purpose.

Currently there’re 3 important branch on frappe.
So now on latest tag we’ll have 4 tags.

  • Master (mas) - v10 [python2]
    • mas-py2-latest
  • Staging (sta) - v11 [python2, python3]
    • sta-py2-latest
    • sta-py3-latest
  • Develop (dev) - v12 [python3]
    • dev-py3-latest

After latest tag is create image will be test and tag version to it. (Testing process is now very very simple, it only run image and get response code if it return 200 it’ll pass.)

ie. 11.0.3-beta.39-py2

  • You’ll always have a working ERPNext image, building from Dockerfile sometimes some updates will break installation process and there’re no easy way to build from older commit.
  • It’s ready for production setup. It comes with yml file which you can run using docker stack deploy, it also comes with backup utilities and Let’s Encrypt using traefik image.
  • You can easily have 2 or 3 version of Frappe (v10, v11, v12) in devlopment or production environment.

Best regards,

Update: 2020-06-14

Official docker repository have matured a lot since I create this repository, It’s now relatively easy to setup, well maintain and will scale nicely in large production setup.

Please also check that out. :grin:


This is some incredible stuff! I had been working on dockerizing ERPNext, but as it’s a monolith setup it constantly fights with that concept itself.

This is where most of it lives, I doubt it works out of the box anymore because I kept experimenting and changing things.

This install script is updated and is where the magic happens. I noticed you’re installing a lot of things you don’t need for Frappe. I’ve been able to reduce the size of the entire image to around 1GB. Basically by removing packages not being used, using a slimmer base image, removing things like the “foundation” and “frappe_io” apps and the .git folders from the apps. And also using docker compression and squashing the layers. (The cleanup stuff isn’t in that script, I was just playing around with that)

You don’t need three different redis containers. One redis instance is enough. I have no idea why the default Frappe setup creates three different redis instances.

Ideally you don’t want nginx either, and just expose the gunicorn port that can be reverse-proxied by a different container. I’m going to stop rambling now. But this is really awesome and has given me some ideas.

1 Like

Hi, vjFaLk

Thank you for your suggestion. I’ve been struggling trying to make image smaller and I’ll definitely try that out.

Wow, just by

  • Deleting foundation(666MB) and frappe_io apps.
  • Deleting .git from erpnext and frappe.
  • Use slimmer base image (from debian:9.6 to debian:9.6-slim)

Image size is reducing to 3.26GB from 4.66GB.

I wonder if there’re any effect from deleting git folder from erpnext and frappe apps.
Are there any bench or frappe command that use git command ?

I’ll update dockerfile and upload new image soon.

Thanks again :smiley:

Docker images in production are supposed to be immutable, which means that we shouldn’t do any operations once the code is in the image. I think by default Frappe does a shallow clone which uses up the least amount of space. But you can get rid of all the .git folders.

Try using this as your base image - Docker

I just noticed you’re using the easy install script. DON’T use it if you’re making a docker image, it installs too much. Check out the file I linked above, and use that as a reference. That is all you need. Feel free to ask any queries.

If you have a seperate MariaDB container, then don’t even install Mariadb.

Try deleting stuff in /tmp and apt cache as well

I’ll try making PRs to your repo if I get the time to work on it. Which I want to!

These apps should be optional installs for those who want in-app help. I will try and get this done by our team sometime in the coming weeks

But there are a lot of stuff that you didn’t install. Are there really not need?

Such as wkhtmltopdf and all these things,

- name: Install prerequisites using apt-get
  become: yes
  become_user: root
  apt: pkg={{ item }} state=present force=yes
	- dnsmasq
	- fontconfig
	- git                     # Version control
	- htop                    # Server stats
	- libcrypto++-dev
	- libfreetype6-dev
	- liblcms2-dev
	- libssl-dev
	- libwebp-dev
	- libxext6
	- libxrender1
	- libxslt1-dev
	- libxslt1.1
	- libffi-dev
	- ntp                     # Clock synchronization
	- postfix                 # Mail Server
	- python-dev              # Installing python developer suite 
	- python3-dev             # For python3 compatibility
	- python-tk
	- screen                  # To aid ssh sessions with connectivity problems 
	- vim                     # Is that supposed to be a question!?
	- xfonts-75dpi
	- xfonts-base
	- zlib1g-dev
	- apt-transport-https
	- libsasl2-dev
	- libldap2-dev
	- libcups2-dev
	- pv                      # Show progress during database restore

- name: install pillow prerequisites for Debian >= 8
  apt: pkg={{ item }} state=present
	- libjpeg62-turbo-dev
	- libtiff5-dev
	- tcl8.5-dev
	- tk8.5-dev
  when: ansible_distribution_version | version_compare('8', 'ge')

I see easy install script as requirements.txt for bench.

If they update bench and need more prerequisites for bench, they should add those prerequisites to easy install script.

By using easy install script both prerequisites and apps will always be in sync.

What do you think?


  • Remove some package
  • Remove cleanup apt-get and remove tmp folder after easy install
  • Not install Mariadb
  • Init new site

Image is now 1.68GB !!

Most impact change is not install Mariadb since /var/lib/mysql folder is 1.2GB. (Not sure if it’s a normal size)

You’re right about wkhtmltopdf, it’s missing in my script. But the rest are either not needed or ended up getting installed as a dependency for a different package.

I understand what you mean about thinking of it as a requirements.txt though, but it’s very unlikely that these packages will change. Also, the easy install, installs a lot of things that make sense on a server but not a docker image. Also, notice there’s also python3. If you’re not running Frappe on python3 then why install it?

Your Dockerfile is difficult to read, because of the hacks you’re doing to modify the Frappe installer. Highly recommend replacing it with simple installs.

Awesome! When building the image, you can also use docker compression by adding the flag --compress and squash all the Docker layers (you need to enable experimental features for this) by adding the flag --squash

I believe so, yes.
bench update i.e. initiates some git pull operations

In bench update command I believe we can skip git pull using these tag pull or patch or build or bench or requirements, so it should be ok for that command.

Thanks you :relaxed:

disclaimer: not much sysadmin might here …

… but I guess the entire update procedure is done via git in one way or another. So I guess there should not be a way to avoiding git … unless you find a way to create new containers with new version that would talk to the pre-existing db container (not even sure your environment is setup like this) and likewise come to a new running version. I guess this would need to be done pretty finegrained, so u won’t miss any bugfixes

speaking of which … you need git to do the inital installaing anyway, or do you remove git after installing bench/frappe/erpnext and before creating the image?

Or am I on a wrong pathtrain of though altogether?

This is exactly correct.

It is normal in docker environment to create new image with newer version then replace the old one.

In this setup if you want to update to new version, you have to build new image then update image to new one then run bench migrate, bench build or bench update --patch

So there should be no need to use git.

I remove git folder after installing bench/frappe/erpnext since git folder is use a lot of space and the way docker environment is setup there are no need to use git command.


I’ve tried not using easy install.

I take all installation that happen in easy install and remove some package that I guess it is not necessary.

Image size is now 1.62GB from 1.68GB.

I’m not sure if it worth the effort, using easy install for me it seems more systematic and should install all necessary package, which result in more stable images, even there’re some package that are not need but space saving from not install those package is just 0.06GB I don’t think it worth it.

Ah wow, great work man. I see your point about using easy install. But how do you plan to clean up your dockerfile? Also, you can move all the run commands into a single script and run that.

This is the cleanest Dockerfile I can come up with for now. (just cleanup comments)

I’ve tried combining all run command into one command, doesn’t help much interm of image size in this particular case.

This will be base image and I’ve add new Dockerfile to use this base image add mariadb and init new site for trial and testing purpose.

Final base image size is at 1.68GB (Still haven’t tried --squash and --compress yet, I forgot, maybe tomorrow :blush:)


I just set up CI/CD on gitlab, which will automatically create new Image Every Monday at Mid-night UTC.

Currently there’re 3 important branch on frappe.
So now on latest tag we’ll have 8 tags. (All image will come with 2 variance with or without MySql)

Master (mas) - v10 [python2]

  • mas-py2-latest
  • mas-py2-w.sql-latest

Staging (sta) - v11 [python2, python3]

  • sta-py2-latest
  • sta-py3-latest
  • sta-py2-w.sql-latest
  • sta-py3-w.sql-latest

Develop (dev) - v12 [python3]

  • dev-py3-latest
  • dev-py3-w.sql-latest

After latest tag is create image will be test and tag version to it. (Testing process is now very very simple, it only run image and get response code if it return 200 it’ll pass.)

ie. 11.0.3-beta.39-py2 or 11.0.3-beta.39-py2-w.sql

Gitlab repository is at pipech - ERPNext Docker
Edited: 22/01/62, Using Github + Travis CI Instead.

Image tag is host and list at Docker hub

And Image size without sql is around 2.14GB


Just an FYI, image without mysql won’t work because it’s a requirement for PyMySQL which is essential to Frappe apps.

So I’ll remove image without mysql option soon.

@pipech: very nice work!
I will probably provide a sample kubernetes/helm solution based on your images next week. I’ll provide the link to the charts here.


Is there any update to this?