How to install ERPNext in a Linux Container (using LXD)?

… and how to setup an easy update routine?

1 Like

This is Work in Progress and therefore not complete yet

Setting up the host machine

  • OS: ubuntu server 16.04
  • LXD version (the recommended way to get to most recent, yet production ready version is to install LXD from the xenial-backports like
    apt-get install -t xenial-backports lxd lxd-client

###preparing your base container

  • on your host OS

    1. lxc launch ubnutu:16.04 erpnext-base
      creates a container named erpnext-base from an ubuntu 16.04 image
    2. lxc exec erpnext-base bash
      gets you inside of your container’s console
  • inside the erpnext-base Container

    1. apt update
    2. apt upgrade -y
    3. apt install -y python-minimal (which you’ll need to execute the easy install script)
    4. su - ubuntu become user ubuntu (which exists inside of that container by default)
    5. wget download the easy install script
    6. sudo chmod 774 (makes the script executable)
    7. sudo python --production (instaling ERPNext in production mode)
      you’ll be prompted to enter a password for the ERPNext administrator & the MariaDB administrator
    8. exit (exiting user ‘ubuntu’)
    9. exit (leaving the container)
  • back on your host

    1. lxc snapshot erpnext-base post-install (takes a snapshot of the erpnext-base container called ‘post-install’ (which we may remove at a later point in time)
    2. lxc exec erpnext-base bash get back inside the container
  • back inside the Container we update the just installed ERPNext & frappe

    1. su - frappe (become user ‘frappe’ [which has been created by the install script)
    2. cd /home/frappe-bench
    3. update bench (updating bench, frappe & erpnext)
    4. exit (exiting user ‘frappe’)
    5. exit (leaving the container)
  • back on your host

    1. lxc snapshot erpnext-base post-update (take another snapshot of the container after the bench update procedure)

no we have a basic installation of ERPNExt inside a Linux Container

from here you can either

  • publish an image of that container with lxc publish erpnext-base/post-update erpnext (which you can use to run new containers from), or
  • copy the base container with lcx copy erpnext-base/post-update erpn1 which spins up a new container [erpn1]

… to be continued

P.S. the problem I have to solve yet is how to make the containerize ERPNext accessible via the local Network. Once solved I’ll update this topic


Thanks for sharing this … I am new to ERPNext, and found your guide very useful …

  • As to networking, generally, lxc/lxd networking is confusing … especially with the rapidly moving development … going from lxc v1 to lxc v2

  • For my needs, I tend to avoid the default bridge mode within containers. If you use bridge mode, then there are ways to perhaps use a proxy on the host to access services running in the containers or do port forwarding and such.

  • Practically all the guides on the net assume everyone is happy to run only bridge mode. So, there is plenty of info to refer to, but beware the versions used may be different from the version you are using. I prefer to use lxc v2 because it’s here and will only get better.

  • For container networking, I personally prefer macvlan, but it’s hard to get good information about this …

  • The following is what has worked for me:

Create a macvlan bridge mode on the host … and put the host’s ip address on that macvlan bridge

#file: /etc/network/interfaces on the host
auto eth0
iface eth0 inet manual
auto mac0

iface mac0 inet static
        pre-up ip link set eth0 up
        pre-up ip link add $IFACE link eth0 type macvlan mode bridge
        post-down ip link delete $IFACE type macvlan
  • Generally, macvlan would not allow host to talk to ct … but by directly using the same macvlan bridge for the host, we ensure ip level communications

  • Next, we define a profile that will work for this macvlan … or edit the default profile

bash# lxc profile copy default ourprofile
bash# lxc profile edit ourprofile
  • an editor session opens … and we should end up with the following … or something like it … the config section is saying to get dhcp from the same dhcp server the host sees
config: dhcp
  user.networking_mode: dhcp
description: Default LXD profile
    nictype: macvlan
    parent: mac0
    type: nic
    path: /
    pool: lxd
    type: disk
name: ourprofile
used_by: []
  • you can also go static, but you will need to run the tedious single commands for setting container params in lxd-2 (ie, no provision for the config files in /var/lib/lxc as was the case with LXC v1) … or use something like ansible.
  • Now we are ready to create our container
bash# lxc launch ubuntu:16.04 -p ourprofile erpnext-base
  • wait a few seconds for the container to start and obtain dhcp address … then confirm with ping … ssh should also work, but I think by default the ubuntu image disables ssh access by password
bash# lxc ls
bash# ping <ip-address> 

The ip address obtained via dhcp by the container is now visible to the host and other hosts on the same network as the host …


great guide. Will check out McClane networking (which I heard of, but haven’t used yet).

bash# lxc ls

Shouldn’t this be lxc list ?

btw, LXD can be installed from a snap package by snap install lxd.

This makes new LXD versions easily available without utilizing backports, ppa’s or such. For example I am running LXD 2.16 on a 14.04 server (which would not be easily possible through a Deb package)

the snap is not yet recommended for production yet though, but about to be considered “production ready” shortly

1 Like

@fblauer, @kirthi you are LXD users … would be interested to hear what your take on bridged vs macvlan networking for LXD containers is?

@vrms I didnt try macvlan at all. I was happy with bridge - it served my purpose. once bridged - there is no need ofd proxying or port forwarding. container behaves like a stand-alone machine in the network.

Nice to know about snap for lxd. weill hv to try it sometime…

thanks @kirthi

for anybody who’s interested in this here is a pretty neat how-to for putting macvlan into play with LXD containers LXC Containers - Exposing Ports & Port Forwarding - YouTube

it takes a more simple approach then @laymonk, attaching the macvlan directly to the default network interface of you host machine. @laymonk do you have any opinion about why your approach would be preferable over this one?

1 Like

btw: a "good-to-know: fact about lxd from snap can be found here: Lxc from snap - where is /var/lib/lxd? - LXD - Linux Containers Forum

1 Like

@vrms, the only difference between what was shown in that video, and my suggested setup is that the host’s ip address is attached to the underlying ethernet device in the video, while my example config attaches the host’s ip to the macvlan bridge interface on the host.

The consequence of that is that as setup in the video, the container would not be able to talk to the host and vice versa, I reckon.

Having said that, it is possible the host and container may be able to talk on L3, but will first traverse the network (ie, their awareness of each other will be determined by the external network switch, as against a local commuination within the host alone) … I guess I need to test that out to be sure.

I don’t think ‘preference’ is relevant here … just roll with what works for your needs. I have gotten used to putting the ip on the macvlan interface, and it makes logical sense to me …

1 Like

it looks like…

  1. … the snap package is almost there in terms of “production readiness”
  2. … the strategy of the LXD developers is movin away from deb packages for LXD slowly starting with the ppa’s and backport channels being deprecated

this furthermore says … “The transition from deb to snap will be done through a script which will let you move your existing environment to the snap without loosing anything. We’ll initially just prompt users on package upgrade, suggesting that they switch to the snap.”

@vrms - given your experience in working with lxd and mine - we can probably create a document or a presentation at the conference to explain the advantages of using lxd. I have immensely benefitted from using lxd and I think a lot of users who installed erpnext in ubuntu will also benefit from that. I can help with content creation in any format that you may suggest. Plz let me know.

1 Like

yes, that’s a great idea. I think the best format would be this topic here, or alternatively and md file on github.
I won’t be able to make it to the conference though I am afraid (even if I’d very much like to be there).

But we still could work this out together. Would you be able to give the presentation?

Ideally we would be able to convince Frappe or the Foundation to issue and maintain an official LXD image, so one could just say lxc launch erpnext:8.x

EDIT: Actually my experience is rather small. I just have publish everything I just have discovered

1 Like

how about that? the date of the Conference is getting closer and there was just released a call for presentations . Would you be able to deliver a talk about ERPNext/LXD?

For your information, I’ve test to install ERPNext under LXC. But this error happened after running sudo python --production using ubuntu user.

Traceback (most recent call last):
File “”, line 388, in
File “”, line 114, in install_bench
run_playbook(‘production/install.yml’, sudo=True, extra_vars=extra_vars)
File “”, line 326, in run_playbook
success = subprocess.check_call(args, cwd=os.path.join(cwd, ‘playbooks’))
File “/usr/lib/python2.7/”, line 541, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘[‘ansible-playbook’, ‘-c’, ‘local’, ‘production/install.yml’, ‘-e’, ‘@/tmp/extra_vars.json’, ‘–become’, ‘–become-user=frappe’]’ returned non-zero exit status 2

I also tried to install on host OS and it went smoothly without error.

Trying to install frappe bench in lxc container (ubuntu 16.04) under Proxmox 5.1, and I am geting What a PITA to install frappe bench (including frappe_docker):

TASK [locale : Check current locale] ********************************************************************************

fatal: [localhost]: FAILED! => {“changed”: true, “cmd”: “localectl”, “delta”: “0:00:25.026238”, “end”: “2017-12-30 11:41:38.663161”, “failed”: true, “rc”: 1, “start”: “2017-12-30 11:41:13.636923”, “stderr”: “Could not get properties: Connection timed out”, “stderr_lines”: [“Could not get properties: Connection timed out”], “stdout”: “”, “stdout_lines”: []}
to retry, use: --limit @/tmp/.bench/playbooks/develop/install.retry

PLAY RECAP **********************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=1

Traceback (most recent call last):
File “”, line 388, in
File “”, line 111, in install_bench
run_playbook(‘develop/install.yml’, sudo=True, extra_vars=extra_vars)
File “”, line 326, in run_playbook
success = subprocess.check_call(args, cwd=os.path.join(cwd, ‘playbooks’))
File “/usr/lib/python2.7/”, line 541, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘[‘ansible-playbook’, ‘-c’, ‘local’, ‘develop/install.yml’, ‘-e’, ‘@/tmp/extra_vars.json’, ‘–become’, ‘–become-user=frappe’]’ returned non-zero exit status 2
root@frappe:~# localectl
Could not get properties: Connection timed out

I’ve just successfully installed ERPNext in a LXC debian 9/jessie container. It was indeed a PITA, the common install notes are not really useful for setting this up in LXC containers or similar. Among the many things I encountered issues with, I can tell you about two issues:

  • /proc/sys without writing permissions to change swappiness (which the isntall script does). To solve this you have to run the command mount /proc/sys -o remount,rw as root (or with sudo).

  • localectl failing to connect (timing out). This was solved following instructions here: [lxc-users] Failed at step NAMESPACE spawning: Invalid argument

Another tip is when studying errors it’s useful to go several lines up, not just the python traceback but many others up, or pasting the complete install log if possible.

Last but not least, I had to install several packages by hand in the LXC container for the install script to work, the following link is a list of packages installed in the debian container if that helps, check if you don’t have something you may need: ERPNext in Debian LXC - packages · GitHub

I hope this helps.

When I wrote this guide a while ago I have not seen any of those issues. Main problem, if I recall it correctly, was to get container networking right.

  1. can you say whether the issues you have encountered are due to using debian or due to using an LXC container? I’d guess debian being the source of your troubles.
  2. What version (ERPNext, LXC/LXD are you using)?
  3. are u using LXD or pure LXC? If LXD is it the snap or conventional .deb package?

I’m using pure LXC and the problems are basically issues or common things you expect from containers (the swappiness and localectl issues I talked about earlier, specifically), the problem is that the easy install script from ERPNext doesn’t expect these to be this way, but it’s the expected way for LXC containers as said in the links of the issues I posted, at least for some/most of the host OS.

This was using the latest ERPNext version (10.1.31) and latest LXC version (3.0.0) on an archlinux host.

did this by any chance happen on a proxmox server? I see something very similar right now on a proxmox system (ubuntu 16.04 container).

And, as I am not 100% sure whether the Container templates on proxmox are identical with the ‘original’ LXC templates, was wondering whether this zould be a proxmox thing.