[Linux] Run Jeedom in a LXC container
Jeedom is open-source software for home-automation; if you plan on installing it on your server, you should read this first.
Indeed, if you follow the official installation instructions, you’ll create a a big mess on your machine that you’ll have a hard time to rollback.
Most of the time Jeedom assumes it’s root and you’re even required to give sudo
rights to the user www-data
! Can you image that?
Still not convinced? Listen to this: the setup script for Jeedom changes the MOTD to “Welcome to Jeedom”! WTF, guys! Just because I’m installing your software doesn’t mean you own my machine!
To work around this, we’ll use LXC containers that are available on recent Linux kernel. To make it short, an LXC container is like a lightweight virtual machine, without the cost of a virtualization technology like VirtualBox.
This article is a step by step guide to install Jeedom in an container. It assumes that the linux kernel supports this technology; as it was the case with the Ubuntu 14.04 that I used.
Install the LXC command line
Even though the support for containers is already bundle in the Linux kernel. You need to install the command line tools:
sudo apt-get install lxc
Update lxc templates
LXC containers are created from templates like “Ubuntu Precise”, “CentOS”, etc. By default very few templates are available, if you want more of them, run:
sudo apt-add-repository ppa:ubuntu-lxc/lxc-stable
sudo apt-get update
sudo apt-get dist-upgrade
Create container
Now let’s create a container named jeedom1
:
sudo lxc-create -t download -n jeedom1
This command is interactive, choose the followings:
- Distribution =
ubuntu
- Release =
vivid
- Architecture =
amd64
(most likely)
Basic container commands
Now that the container is created, you can:
- Start the container with:
sudo lxc-start -n jeedom1
- Open terminal with:
sudo lxc-attach -n jeedom1
- Close terminal with:
ctrl-a
+ctrl-d
orexit
- Shut the container down with:
sudo lxc-stop -n jeedom1
- Destroy the container with:
sudo lxc-destroy -n jeedom1
(but don’t do it now)
Allow container to access the Z-wave USB device
Edit /var/lib/lxc/jeedom1/config
and add:
# Z-wave USB
lxc.cgroup.devices.allow = c 166:* rwm
lxc.mount.entry = /dev/ttyACM0 dev/ttyACM0 none bind,create=file 0 0
This configuration works for a Zwave.me ZME UZB1; you’ll have to adapt it if you’re using another transceiver. In particular, 166
is the major device id, you can do a ls -al /dev/ttyACM0
to find the one for your device.
Start the container and install Jeedom
Time to install Jeedom, we’ll follow the official installation instructions:
# Start the container
sudo lxc-start -n jeedom1
# Connect to the container
sudo lxc-attach -n jeedom1
# The following commands are executed in the container
# Do as told in Jeedom installation instructions
cd /root
apt-get update
apt-get install -y curl wget
wget https://raw.githubusercontent.com/jeedom/core/stable/install/install.sh
chmod +x install.sh
./install.sh
echo "www-data ALL=(ALL) NOPASSWD: ALL" | (EDITOR="tee -a" visudo)
# Exit from container and go back to host
exit
Forward HTTP port to the container
Right now Jeedom is running in the container and the web interface is accessible only from the host. You probably want to had a firewall rule to map the Jeedom port to a port of the host.
Use the following command to get the names and the IP addresses of the existing containers:
sudo lxc-ls --fancy
Now that you have the IP, add a routing rule with:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 7080 -j DNAT --to <YOUR_CONTAINER_IP>:80
This command routes all traffic going to the port 7080 of the host to the port 80 of the container.
Additional tips
To start the container when the host boots, add the following lines to /var/lib/lxc/jeedom1/config
:
# Auto start
lxc.start.auto = 1
lxc.start.delay = 5
To workaround a bug in current Jeedom version I had to type the following command in the container:
mkdir -p /usr/share/nginx/www/jeedom/plugins/openzwave/data
To diagnose problem with the openzwave plugin, use the following command
python /usr/share/nginx/www/jeedom/plugins/openzwave/ressources/zwaveserver/openZWave.py \
--pidfile=/tmp/openzwave.pid \
--device=/dev/ttyACM0 \
--log=Debug \
--port=8083 \
--config_folder=/usr/share/nginx/www/jeedom/plugins/openzwave/ressources/openzwave/config \
--data_folder=/usr/share/nginx/www/jeedom/plugins/openzwave/data \
--callback=http://127.0.0.1:80/jeedom/plugins/openzwave/core/php/jeeZwave.php
--apikey=<YOUR_API_KEY> \
--serverId=0
Conclusion
It’s much better like this. The mess is still here but in a container, so that your host machine is pristine.
However, there is still an issue. As you saw we’re starting the container with sudo lxc-start
; this is because we’re running a “privileged” container.
It’s possible to run the container as a non root user, it’s called “unprivilged” container and it’ll hopefully be the topic of a future blog post.