undocker, run a Docker image without Docker
I self-host on *.benpro.fr a lot of things with LXD, right now I have 20 LXC containers managed by LXD on a single machine.
When I want to self-host something, there are three possibilities:
- The software is packaged in Debian/Ubuntu or Archlinux: I just launch a new container, and install the software with the package manager. For example, this is the case of Miniflux.
- The software is not packaged but there is a production install guide: I just launch a new container and do all the necessary actions. For example, this is the case of Mastodon.
- The software is only available via Docker: I could try to translate the Dockerfile to manual steps but I prefer to just not use it.
But thanks to a new discovery, this has changed!
I discovered undocker and skopeo. With these two tools you can easily extract a Docker image (a succession of “layers”), and run the app out of Docker.
I tried with Photoview. Here is the basic guideline:
- Deploy with LXD a LXC container with the same Linux distribution as the Dockerfile use.
- Install MariaDB since the app need a database.
- Extract the Docker image.
- Identify required environment variable by reading the Dockerfile and Docker compose.
- Create a systemd unit file.
- Launch the application with systemd.
- Profit! Give the middle finger to Docker!
Here are the steps for Photoview:
$ lxc launch images:debian/11 gallery $ lxc exec gallery bash # apt install mariadb-server skopeo wget # mysql -e "CREATE DATABASE photoview; GRANT ALL PRIVILEGES ON photoview.* TO 'photoview'@localhost IDENTIFIED BY '<PASSOWRD>'" # wget https://git.sr.ht/~motiejus/undocker/refs/download/v1.0.1/undocker-linux-amd64-v1.0.1 -O /tmp/undocker # install -m 755 /tmp/undocker /usr/local/bin/undocker # adduser --disabled-password photoview # sudo -iu photoview $ skopeo copy docker://docker.io/viktorstrate/photoview:latest docker-archive:photoview.tar $ mkdir photoview cache $ cd photoview $ undocker ~/photoview.tar - | tar -xv $ cat << EOT > ~/.env PHOTOVIEW_LISTEN_IP=127.0.1.1 PHOTOVIEW_LISTEN_PORT=1234 PHOTOVIEW_SERVE_UI=1 PHOTOVIEW_UI_PATH=/ui PHOTOVIEW_DATABASE_DRIVER=mysql PHOTOVIEW_MYSQL_URL='photoview:<PASSWORD>@tcp(127.0.0.1)/photoview' PHOTOVIEW_MEDIA_CACHE=/home/photoview/cache MAPBOX_TOKEN=<TOKEN> EOT # cat << EOT > /etc/systemd/system/photoview.service [Unit] Description=Photoview After=network.target Requires=mariadb.service [Service] Type=simple User=photoview EnvironmentFile=/home/photoview/.env BindReadOnlyPaths=/proc WorkingDirectory=/app RootDirectory=/home/photoview/photoview ExecStart=/app/photoview Restart=on-failure [Install] WantedBy=multi-user.target EOT # systemctl daemon-reload # systemctl enable --now photoview # systemctl status photoview ● photoview.service - Photoview Loaded: loaded (/etc/systemd/system/photoview.service; enabled; vendor preset: enabled) Drop-In: /run/systemd/system/service.d └─zzz-lxc-service.conf Active: active (running) since Sun 2021-09-05 12:49:47 UTC; 8s ago Main PID: 4643 (photoview) Tasks: 9 (limit: 7084) Memory: 54.1M CGroup: /system.slice/photoview.service ├─4643 /app/photoview └─4653 /usr/bin/perl -w /usr/bin/exiftool -stay_open True -@ - -common_args -n Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Scan interval runner: Waiting for signal Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Scan interval runner: New ticker detected Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Scan interval runner: Waiting for signal Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Found executable worker: darktable (this is darktable-cli> Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Found executable worker: ffmpeg (ffmpeg version 4.3.2-0+d> Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Found exiftool Sep 05 12:49:47 test photoview: 2021/09/05 12:49:47 Initializing face detector Sep 05 12:49:48 test photoview: 2021/09/05 12:49:48 Photoview API endpoint listening at http://127.0.1.1:1234> Sep 05 12:49:48 test photoview: 2021/09/05 12:49:48 Photoview API public endpoint ready at /api Sep 05 12:49:48 test photoview: 2021/09/05 12:49:48 Photoview UI public endpoint ready at /
And voilà! 🎉
Now, you still have the the same issue as using Docker, the Dockerfile may have used old software and libraries when compiling the application... But, somehow I find it better, and it integrate well with my LXD usage.
Note that it is also possible to not use
RootDirectory in the systemd unit file and install all the required dependencies (ffmpeg, darktable, ...) and it may also work, having more control on these dependencies, instead of relying of what is shipped in the Docker image.