Domoticz for Alpine!!

Tue Jan 5 2021

I moved all apps on my RPI2 to LXD (Linux Containers) a simple lightweight solution for OS virtualization. In another note I will share more details. Since it is a RPI2 - armv7l - and limited I really wanted to push all containers to the smallest possible container, being alpine musl images. To get domoticz running on LXD was pretty easy using a debian image, simply launch a standard debian image and install domoticz. This might still be the best/easiest/quickest way to run domoticz, but I still wanted to move to an alpine image .. so ..

It took me some puzzling and trial and error, but in the end I succeeded. This not is here for future reference (probably will have to do this again for an upgrade) and to share with potential others. Not that it is not the fastest solution for compiling since I ended up compiling via qemu. If I find a way I might add another note on cross compiling domoticz on alpine ;-)

Goal: Compile domoticz from for the latest alpine stable using a void linux desktop ;-)

Create aplpine armv7l chroot on x86_64

Step 1: chroot into alpine musl!!

add binfmt-support and qemu-user-static and make sure binfmt-support is started

# note: binfmt-support must be installed first, not sure if it has to be started first
xbps-install binfmt-support
cd /var/services
ln -s /etc/sv/binfmt-support .
xbps-install qemu-user-static

Step 2: build root with alpine-minirootfs

curl -O https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/armhf/alpine-minirootfs-3.13.0-armhf.tar.gz
mkdir chroot
cd chroot
tar xvf ../alpine-minirootfs-3.13.0-armhf.tar.gz 

Step 3: Add qemu emulation in the chroot

cp /sbin/qemu-arm-static chroot/usr/bin

Step 4: chroot into the alpine musl armv7l chroot

uname -m
# your current architecture: eg x86_64

# note the /bin/sh is required since alpine does not have bash installed by default
chroot chroot /bin/sh
uname -m
# should give armv7l

NICE FINALLY!!

Build domoticz on the alpine qemu chroot

Next steps is loosely based on a Dockerfile for building domoticz on alpine linux, and a lot of trial and error

Step 1: Install required packages

# get into the chroot
chroot chroot /bin/sh
# add required packages for compiling on alpine
apk add git python3-dev build-base cmae boost-dev boost-thread boost-system boost-date_time sqlite sqlite-dev curl libcurl curl-dev libressl-dev libusb libusb-dev libusb-compat libusb-compat-dev lua5.3-dev minizip-dev mosquitto-dev coreutils tzdata zlib zlib-dev udev eudev-dev linux-headers libssl1.1

Step 2: add cereal includes

On top of this cereal is required. cereal is a header-only C++11 serialization library:

# download cereal from the website (download topright) or
curl -OL https://github.com/USCiLab/cereal/archive/v1.3.0.tar.gz
tar xvf v1.3.0.tar.gz
# link the resulting cerual-1.3.0 dir to /usr/include
cd /usr/include
ln -s <path-to-cereal-1.3.0> .

Step 3: Get domoticz

git clone https://github.com/domoticz/domoticz.git dev-domoticz
cd dev-domoticz

Step 4: Build!!


cmake -DBUILD_SHARED_LIBS=True  -DCMAKE_BUILD_TYPE=Release -DUSE_BUILTIN_LUA=OFF -DUSE_BUILTIN_MINIZIP=OFF -DUSE_BUILTIN_MQTT=OFF -DUSE_BUILTIN_SQLITE=OFF -DLUA_LIBRARIES=/usr/lua5.3/lib/liblua-5.3.so.0 -DUSE_STATIC_BOOST=OFF CMakeLists.txt
# should return without errors

# build with parallel cores
make -j13

# note that building is slower than normal compile since everything is run via qemu-arm-static!

The resulting binary should give sort of the following in ldd

~/dev-domoticz # ldd domoticz
/lib/ld-musl-armhf.so.1 (0x40000000)
libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x3ed8c000)
libminizip.so.1 => /usr/lib/libminizip.so.1 (0x3ed73000)
libssl.so.1.1 => /lib/libssl.so.1.1 (0x3ecf9000)
libcrypto.so.1.1 => /lib/libcrypto.so.1.1 (0x3eb12000)
libboost_thread.so.1.72.0 => /usr/lib/libboost_thread.so.1.72.0 (0x3eadf000)
libusb-0.1.so.4 => /usr/lib/libusb-0.1.so.4 (0x3eacb000)
libz.so.1 => /lib/libz.so.1 (0x3eaa6000)
libcurl.so.4 => /usr/lib/libcurl.so.4 (0x3ea33000)
libmosquitto.so.1 => /usr/lib/libmosquitto.so.1 (0x3ea0f000)
liblua-5.3.so.0 => /usr/lua5.3/lib/liblua-5.3.so.0 (0x3e9d5000)
libc.musl-armhf.so.1 => /lib/ld-musl-armhf.so.1 (0x40000000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x3e9bb000)
libusb-1.0.so.0 => /usr/lib/libusb-1.0.so.0 (0x3e995000)
libnghttp2.so.14 => /usr/lib/libnghttp2.so.14 (0x3e967000)
libcares.so.2 => /usr/lib/libcares.so.2 (0x3e945000)

Install Domoticz in container

Step 1: Create lxc container for domoticz

Add lxc container and copy domoticz into the container

# add base container
lxc launch images:alpine/3.13 a1

# enter a1 container
lxc exec a1 sh
apk add sqlite-libs libcurl minizip boost-thread libusb-compat mosquitto-libs 
exit

# copy domoticz into the container
tar cvf domoticz.tar Config domoticz* plugins History.txt scripts License.txt dzVents www
lxc file push domoticz.tar a1/root/domoticz.tar

# setup container
lxc exec a1 sh
adduser domoticz
cd /home/domoticz
mkdir app
cd app
tar xvf /root/domoticz.tar
cd ..
chown -R domoticz.domoticz app
chmod -R u+rwX,go-rwx .
# etc, you probably know the drill

Step 2: Add startup scripts

Alpine containers use /etc/local.d/.[start|stop] to start and stop local apps

#!/bin/sh
# /etc/local.d/domoticz.start

su -l domoticz -c 'cd app; ./domoticz -www 8008 -sslwww 0 -noupdates -syslog local6 -loglevel status,normal,error -pidfile domoticz.pid -daemon'

#!/bin/sh
# /etc/local.d/domoticz.stop
killall domoticz

# and add local to the startup sequence
rc-update add local

that’s it! Alpine running in an lxd/lxc alpine musl container!