LXC Unprivileged autostart in Debian Stretch

I’m running Debian stretch and have some unprivileged containers I’ve created with my non-root account. They do not autostart on boot, and I haven’t been able to find a debian & systemd guide for how to do this. I’ve tried using the systemd service files provided, but I get various errors when I use them and try to modify them.

My current solution is a systemd service that creates a file on boot, and I added a script to my non-root user’s crontab which check for that file every minute, and runs lxc-start for each container if the file exists. This is cludgy and delays container startup on boot.

What is the kosher way to start unprivileged LXC containers in Debian Stretch?

When systemd starts the lxc service, the lxc service calls lxc-autostart. But lxc-autostart is called as root, so even if you have “lxc.start.auto = 1” in your container config, your unprivileged container isn’t started.

If you login as the user that owns the container, and run lxc-autostart as that user, your container will start, assuming you did set its config to autostart.

If you want your unprivileged container to run at boot, you need to call something like

su -c lxc-autostart (USER)

after the lxc service has started. So you could possibly enable the legacy rc-local service and edit its unit file to start after lxc.

Edit:
If your rc-local service unit file is /lib/systemd/system/rc-local.service (you can find out by running systemctl status rc-local)

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.local
After=network-online.target lxc.service

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target

and then enable the service, if it is not already enabled, systemctl enable rc-local

That will run /etc/rc.local on startup after lxc has started. You can put your lxc-autostart call in /etc/rc.local

Your systemd service might be called rc.local, on my ubuntu machine, rc.local is a symlink to rc-local

1 Like

Thanks @cburn11, su -c let me issue commands as root to be executed as my non-root user. I wrote a small systemd service file and a bash script which are run by root at boot. For anybody else who stumbles on this problem, here is what I did:

To make your pre-made unprivileged containers start on boot, log in as the user who owns them, stop the containers, and run nano to add the following to their config files:
nano /home/{username}/.local/share/lxc/{containername}/config

lxc.start.auto = 1

For containers created by a non-root user in my Debian Stretch install, I found the config files in /home/{username}/.local/share/lxc/{containername}/config, substituting in the container’s name and its creator’s username. One of these lines may be redundant, but I had no adverse effects from including both. You can add those lines to the default template I found in /home/{username}/.config/lxc/default.conf , which will affect all new containers made by this user.

As root, do the following:

nano /etc/systemd/system/lxc-autostart.service

[Unit]
Description=Runs “lxc-autostart” on boot
[Service]
ExecStart=/z/s1/lxc/lxc-autostart.sh
Type=oneshot
[Install]
WantedBy=default.target

nano /z/s1/lxc/lxc-autostart.sh

#!/bin/bash
#2018-01-20
#lxc-autostart.sh: Starts lxc containers on boot
su -c “lxc-autostart -a” {username}

With no arguments provided, lxc-autostart will start only containers without a group specified by lxc.group in their config. Providing the -a switch will start all containers with lxc.start.auto = 1 regardless of their group.

chmod 755 /z/s1/lxc/lxc-autostart.sh
chmod 755 /etc/systemd/system/lxc-autostart.service
systemctl daemon-reload #Refreshes list of service files
systemctl enable lxc-autostart.service
systemctl start lxc-autostart.service

The chmod lines allow read access to all, and only permit the creator (root) to edit and execute them. daemon-reload refreshes the list of service files, enable sets lxc-autostart to start at boot, and start starts the service so we can test it without a reboot.

Now as your non-root user, run lxc-ls -f to list that user’s containers and their status. If all the containers you want to autostart read “RUNNING” then the systemd service should autostart them on boot.

Edit: Updated container config options

Your container config puts your container in a group named onboot. The “-a” switch overides the “-g” switch which has a default null value applying to containers not put in a group. You could also run:

lxc-autostart -g onboot