Setting-up LXC on Slackware Linux

this is draft because we should setup unprivileged instances by tuning cgroups and namespaces


no need to run the init script unless you have instances configured already

slackpkg install lxc gnutls p11-kit nettle bridge-utils
ls -lF /etc/rc.d/rc.lxc*
chmod +x /etc/rc.d/rc.lxc

ldd /usr/bin/lxc-info
lxc-info --version

slackpkg install libcgroup sysvinit-functions
ls -lF /etc/rc.d/*
chmod +x /etc/rc.d/rc.cgconfig /etc/rc.d/rc.cgred
/etc/rc.d/rc.cgconfig start
/etc/rc.d/rc.cgred start


you will also need debootstrap in case you plan to deploy Debian or Ubuntu. But then you will be stuck with SystemD issues anyhow. We’re proceeding with the deployment of a slackware instance in this guide.

Setup LXC

ls -lF /var/lib/lxc/
mv /var/lib/lxc/ /data/instances/
ln -s /data/instances /var/lib/lxc

define the defaults when creating instances

mv /etc/lxc/default.conf /etc/lxc/default.conf.dist
vi /etc/lxc/default.conf

this is v4 = veth = up = dummybr0 = eth0

# internal bridge and self-defined MAC prefix, xx will expand = dummybr0 = 00:00:00:xx:xx:xx

vi /etc/lxc/lxc.conf # new file

lxcpath = /data/instances

lxc-config -l

Create an instance

review available distributions

#lxc-create -t download -n dummy
#rm -rf /data/instances/dummy/

ehm… just review available template scripts instead

ls -lF /usr/share/lxc/templates/

fix the template scripts to be ready for current (got PAM and need moar pkgs)

cp -pi /usr/share/lxc/templates/lxc-slackware /usr/share/lxc/templates/lxc-slackware.dist
chmod -x /usr/share/lxc/templates/lxc-slackware.dist
vi /usr/share/lxc/templates/lxc-slackware

#echo "root:root" | chroot $rootfs chpasswd
#echo "Root default password is 'root', please change it!"
chroot $rootfs passwd --delete --unlock root

# REMOVE openssh as we do not necessarily want a full-blown system there

diff -u /usr/share/lxc/templates/lxc-slackware.dist /usr/share/lxc/templates/lxc-slackware

now deploy your system of choice on the file-system

cd /data/instances/

export arch=x86_64
export release=current
export MIRROR=
cat /var/cache/lxc/slackware/slackpkg-conf/mirrors
echo $MIRROR > /var/cache/lxc/slackware/slackpkg-conf/mirrors

lxc-ls -f


rm -rf $instance/
# need to answer y about using current
time echo y | lxc-create -n $instance -t slackware 2>&1 > $instance.log && echo CREATED
# -f /etc/lxc/$instance.conf

# 1m53.229s on xc

cat /data/instances/$instance/config

eventually clean-up things and make the instance lighter

du -sh /data/instances/$instance/rootfs/
# vbatts + additions above = 258M
# the new script for v4 = 316M

ls -lhF /data/instances/$instance/rootfs/var/cache/lxc/slackware/cache-current-x86_64/slackware64/*/*.txz*
rm -rf /data/instances/$instance/rootfs/var/cache/lxc/slackware/cache-current-x86_64/

du -sh /data/instances/$instance/rootfs/
# now 214M
# now 261M

Network setup

full bridge

setup network on a full bridge on the Slackware host (yeah sorry for the bridge name, it does not matter, really)

    echo -n default bridge...
    brctl addbr xenbr0
    brctl addif xenbr0 eth0
    ifconfig eth0 up
    ifconfig xenbr0 HOST-IP-ADDRESS/24 up && echo done || echo FAIL

and configure the instance brutally, here some kind of failover IP

    echo $instance
    vi /data/instances/$instance/rootfs/etc/rc.d/rc.inet1


    echo rc.inet1 PATH is $PATH

    if [[ $1 = stop || $1 = down ]]; then
            route delete default
            ifconfig eth0 down
            ifconfig lo down
            echo -n lo...
            ifconfig lo up && echo done || echo FAIL

    echo -n eth0...
    ifconfig eth0 $failover/32 up && echo done || echo FAIL
    #ifconfig eth0 $failover/32 pointopoint up && echo done || echo FAIL
    unset failover

    echo -n custom route for non-subnet gateway...
    route add -host dev eth0 && echo done || echo FAIL

    echo -n default route...
    route add default gw && echo done || echo FAIL

    vi /data/instances/$instance/rootfs/etc/rc.d/rc.local # why the freak is it restarting rc.inet1?

–and/or– dummy bridge

setup network on a dummy bridge and SNAT on the Slackware host

vi /etc/rc.d/rc.inet1

echo -n dummy bridge...
brctl addbr dummybr0
ifconfig dummybr0 up && echo done

echo -n SNAT for
    echo 1 > /proc/sys/net/ipv4/ip_forward
/usr/sbin/nft -f /etc/nftables.conf && echo done || echo FAIL

    vi /etc/nftables.conf

    flush ruleset

    table ip nat {
            chain postrouting {
                    type nat hook postrouting priority 100;
                    ip saddr oif xenbr0 snat FACING-IP;

vi /etc/hosts

# LXC slacklxc xc

vi /etc/postfix/

mynetworks =,

postfix reload

and setup network within the instance brutally

echo $instance
mv /data/instances/$instance/rootfs/etc/rc.d/rc.inet1 /data/instances/$instance/rootfs/etc/rc.d/rc.inet1.dist
chmod -x /data/instances/$instance/rootfs/etc/rc.d/rc.inet1.dist
vi /data/instances/$instance/rootfs/etc/rc.d/rc.inet1


    echo rc.inet1 PATH is $PATH

    if [[ $1 = stop || $1 = down ]]; then
            route delete default
            ifconfig eth0 down
            ifconfig lo down
            echo -n lo...
            ifconfig lo up && echo done || echo FAIL

            echo -n eth0...
            ifconfig eth0 up && echo done || echo FAIL

            echo -n default route...
            route add default gw && echo done || echo FAIL

    vi /data/instances/$instance/rootfs/etc/rc.d/rc.local

# why the freak was it restarting networking?
#/etc/rc.d/rc.inet1 restart

further instance setup

not sure why a debianish file appeared on a slackware system

ls -lF /data/instances/$instance/rootfs/etc/hostname
rm -f /data/instances/$instance/rootfs/etc/hostname

short name is enough

cat /data/instances/$instance/rootfs/etc/HOSTNAME
echo $instance > /data/instances/$instance/rootfs/etc/HOSTNAME

eventually define FQDNs here instead

mv /data/instances/$instance/rootfs/etc/hosts /data/instances/$instance/rootfs/etc/hosts.dist
vi /data/instances/$instance/rootfs/etc/hosts       localhost slacklxc xc

–or–       localhost
INSTANCE-IP meet  gw

    vi /data/instances/$instance/rootfs/etc/resolv.conf


further post-install in a CHROOT

vi /data/instances/$instance/rootfs/root/.bashrc

alias ll='ls -alhF --color=auto'

we did not add NVI hence Elvis is the only editor around

chroot /data/instances/$instance/rootfs/

which vi # no exist
ls -lF /usr/bin/vi
which elvis
ln -s elvis /usr/bin/vi

slackpkg’s mirror was defined at install time

grep -v ^# /etc/slackpkg/mirrors
slackpkg update gpg
slackpkg update

first shot of indexing


exit the CHROOT


and in case you need to change the MAC or something

vi /data/instances/$instance/config

# dedibox failover-ip with a manually defined MAC suffix = xenbr0 = 00:16:3e:SUFFIX = 1

The systemd situation

oh, you wanna run a systemd-capable instance on slackware?!

ls -ldF /sys/fs/cgroup/systemd # -> elogind/
rm /sys/fs/cgroup/systemd
mkdir -p /sys/fs/cgroup/systemd/

# mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd
vi /etc/fstab

systemd /sys/fs/cgroup/systemd cgroup rw,none,name=systemd 0 0

mount /sys/fs/cgroup/systemd/

here we go with buster to build a Jitsi Meet instance

export MIRROR=
lxc-create -n $instance -t debian -- template-options -r buster
#-t ubuntu -- template-options -r bionic

get rid of that unknown password the script defined

chroot /data/instances/$instance/rootfs/ passwd -d root

setup a few things brutally (this is recommended esp. as there’s no editor within the instance so far)

cat >> /data/instances/$instance/rootfs/etc/bash.bashrc <<-EOF
alias ll='ls -alhF --color=auto'

rmdir /data/instances/$instance/rootfs/etc/network/interfaces.d/
cat > /data/instances/$instance/rootfs/etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    post-up ip route add dev eth0
    post-up ip route add default via
    #dns-search example.local

and once the instance is up you may want to

apt update
apt full-upgrade
apt install inetutils-ping vim-tiny less
# iputils-ping

also there’s no need for ssh in the instance

apt purge openssh-server openssh-sftp-server openssh-client

Ready to go

start the instance on the foreground to see its console at startup. beware if you’re remote, when started in foreground, the instance crashes if you loose your ssh session. this is why it’s better run it inside gnu/screen or tmux

screen -S lxc


echo $instance
lxc-ls $instance --fancy
lxc-start $instance --foreground

and in another window, get to the login prompt

lxc-ls --fancy
lxc-attach $instance -- /bin/bash # TODO workdir

ps auxfww
ifconfig -a




boot-time scripts take care of instances' startup and shutdown. enable an instance at boot-time

vi /data/instances/$instance/config = 1


/etc/rc.d/rc.lxc stop


ps auxfww | grep lxc | grep -vE 'grep|tail'
ls -lF /data/instances/
    lxc-ls --fancy


/etc/rc.d/rc.lxc stop


start an instance

lxc-start $instance
# -f /etc/lxc/$instance.conf
# CONFIG=/etc/lxc/$instance.conf lxc-checkconfig
lxc-attach $instance

status an instance

lxc-ls --fancy -n $instance
lxc-info $instance

stop an instance

lxc-stop $instance
lxc-stop -n $instance -k

Upgrade to v4

lxc-update-config -c /etc/lxc/lxc.conf
lxc-update-config -c /etc/lxc/default.conf
lxc-update-config -c /data/instances/INSTANCE/INSTANCE.conf


Setup cgroups and namespaces

vi /etc/cgconfig.conf
vi /etc/cgred.conf

About lxc-start -F – are there other means of seeing the instance starting up?

How come the default route is already set in the instance?

default route...SIOCADDRT: File exists

How come we see agetty tty1 tty2 running but no prompt anywhere?


on instance’s foreground

lxc-start: conf.c: remount_all_slave: 3126 Invalid argument - Failed to copy "/proc/self/mountinfo"
Failed to mount cgroup at /sys/fs/cgroup/systemd: Operation not permitted
[!!!!!!] Failed to mount API filesystems, freezing.
Freezing execution.

==> that only matters if you need to run a systemd-capable instance.

when trying lxc-stop from the host against an instance you get

lxc-stop: commands_utils.c: lxc_cmd_sock_rcv_state: 75 Failed to receive message: Resource temporarily unavailable

when trying poweroff or halt -p in the instance you get

System has not been booted with systemd as init system (PID 1). Can't operate.

==> did you notice there’s something missing when checking the state of the art on the host?


Cgroup v1 systemd controller: missing

this is probably sure why systemd does not work within the instance – TODO – I didnt found how to fix this yet - proceeding w/o it and be happy with -k

on instance’s foreground

lxc-start: conf.c: remount_all_slave: 3126 Invalid argument - Failed to copy "/proc/self/mountinfo"

==> TODO


not sure where to use those (default.conf vs lxc.conf), it only worked as shell exports

# Ubuntu mirror for FRANCE/SCW
#lxc.environment = MIRROR=
#lxc.environment = DOWNLOAD_KEYSERVER=""

# Debian mirror for FRANCE
#lxc.environment = MIRROR=
#lxc.environment = DOWNLOAD_KEYSERVER=""

# Devuan
#lxc.environment = MIRROR=
#lxc.environment = DOWNLOAD_KEYSERVER=...?

# Slackware mirror for FRANCE
#lxc.environment = MIRROR=






LXC 1.0: Blog post series [0/10]

LXC 1.0: Unprivileged containers [7/10]

Configuring Unprivileged LXC containers in Debian Jessie

Unprivileged containers in Slackware©



Bug 1802090 - Systemd: Couldn’t move remaining userspace processes, ignoring: Input/output error

Warning “Couldn’t move remaining userspace processes, ignoring: Input/output error” #14788

“Couldn’t move remaining userspace processes, ignoring: Input/output error” message on dmesg/journalctl on boot since Linux 5.5 upgrade #14682

LXC ubuntu container fails to start

Fails to work with cgroupv2 / unified hierarchy #3183


Alpine Linux and Systemd Containers (Round 2)

upgrade to v4 — config syntax

LXC version 2 migration to version 3 issue : Failed to load config

Parse.c errors after full system update of archlinux- failed to parse config

Many syslog entries for some, but not all containers: Failed to load config for xxxx #4624

LXC config error after update

Upgrade from lxc2 to lxc3

cannot start

Container won’t start - lxc_rootfs_init - Bad file descriptor

Containers do not launch on Linux 5.12

lxc info –show-log local:wekan

Newuidmap failed to write mapping “newuidmap: uid range [1000-1001) -> [1000-1001) not allowed”

Unprivileged container failed to mount rootfs and start when cloning

FS#70736 - LXD breaks on kernel 5.12

conf: handle kernels with CAP_SETFCAP #3827

Arch lxc start failed #7469

“File exists” error while starting container

Failed To Initialize Cpuset Cpus Issue 9114 Lxc Lxd Github

cannot start a container if has a device disk added from another blockdevice mount point

Cannot start LXD container within LXD container


more issues

Can’t get LCX bridge to work

Unprvileged container: lxc-start not working if cpu-related cgroups are set #1205

Copyright © 2024 Pierre-Philipp Braun