LXC Docs
LXC installation documentation
To write this documentation we followed the Debian wiki, and Stéphane GRABER website, you will find the references at the bottom of this document. LXC pronounced leex~cee provide a free software virtualization system for computers running GNU/Linux. For official upstream documentation [please visit lxc]
Supported versions
| Version | EOL | Release | 
|---|---|---|
| 3.0 LTS | June 1st 2023 | Buster | 
| 4.0 LTS | June 1st 2025 | Bullseye | 
LXC Installation
To install lxc on Debian system typically required lxc.
:~# apt install lxcIf you plan to use unprivileged container you need to install required packages.
:~# apt install lxc libvirt0 libpam-cgfs bridge-utils uidmapNetwork Installation
To use the container over network, we can virtualize the local network by using bridges. The easiest way install the following packages.
:~# apt install libvirt-clients libvirt-daemon-system iptables ebtables dnsmasq-base libxml2-utils iproute2
:~# virsh net-start default
:~# virsh net-autostart defaultSetup Network independent bridge
To set up independent bridge to access from local network, we need to configure different files: /etc/default/lxc-net & /etc/lxc/default.conf
- Create lxc-net file if not exists to /etc/default and add the following line: - USE_LXC_BRIDGE="true"
- 
	Edit default.conf and change the default lxc.network.type = emptyTo this: lxc.net.0.type = veth
 lxc.net.0.link = lxcbr0
 lxc.net.0.flags = up
 lxc.net.0.hwaddr = 00:16:3e:xx:xx:xxAnd live the rest as is. 
- Run the command - :~# service lxc-net restart
Enable Network for unprivileged containers
To set up a network for unprivileged containers checks if user namespaces are enabled. Run the following command:
:~# sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1If it reports 0 instead 1, it's disabled.
To enable it, append kernel.unprivileged_userns_clone=1 to /etc/sysctl.conf, or to file such as /etc/sysctl.d/unpriv-usernd.conf, then run sysctl -p
Copy the default file config into your ~/.config/lxc/
cp /etc/lxc/default.conf ~/.config/lxc/default.confConfiguration
To setup networking and enable it for unprivileged containers, like for containers started by root which by default has a network enabled by default. For non-root containers, we need to allow your non-root user to create a virtual network interface by adding lxc-netuser to /etc/lxc/lxc-usernet with the following line.
:~# echo myusername veth lxcbr0 10 >> /etc/lxc/lxc-usernetThis command creates file lxc-usernet if not exists and append myusername veth lxcbr0 10.
This means "that myusername" is allowed to create up 10 virtual ethernet 'veth' device connected to lxc bridge 'lxcbr0'
Resolve network not starting
Sometimes some containers (unprivileged or not) can not obtaining ip, that can produce if the network has not been started. To resolve the issue, connect to container and restart the network.
:~# lxc-attach xenial
:/# su -
:~# ifconfig eth0 up
:~# ifconfig
eth0	Link encap:Ethernet  HWaddr 00:16:3e:ca:11:09
	inet addr:10.0.3.68  Bcast:10.0.3.255  Mask:255.255.255.0
	inet6 addr: fe80::216:3eff:feca:1109/64 Scope:Link
	UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
	RX packets:32 errors:0 dropped:0 overruns:0 frame:0
	TX packets:17 errors:0 dropped:0 overruns:0 carrier:0
	collisions:0 txqueuelen:1000
	RX bytes:3642 (3.6 KB)  TX bytes:1802 (1.8 KB)
lo	Link encap:Local Loopback
	inet addr:127.0.0.1  Mask:255.0.0.0
	inet6 addr: ::1/128 Scope:Host
	UP LOOPBACK RUNNING  MTU:65536  Metric:1
	RX packets:324 errors:0 dropped:0 overruns:0 frame:0
	TX packets:324 errors:0 dropped:0 overruns:0 carrier:0
	collisions:0 txqueuelen:1000
	RX bytes:25552 (25.5 KB)  TX bytes:25552 (25.5 KB)
If you don't still get an ip, check if your resolvconf folder exists:
:~# cd /run/resolvconf/interfaceIf not exists create the folder, resolve server name & release dhcp:
:~# mkdir /run/resolvconf/interface
:~# resolvconf -u
:~# dhcpclient -r
:~# dhcpclient
:~# ifconfigIf this resolve your issue, but you cannot ping www.debian.org, for example that means you cannot access to internet, in this case resolv.conf file is missing from /run/resolvconf.
:~# echo "nameserver 10.0.3.1" > /run/resolvconf/resolv.conf
:~# echo 'nameserver 127.0.0.53
options edns0' > /run/resolvconf/stub-resolv.conf
:~# /etc/init.d/network restartAfter that you should to connect to internet. Thanks to kianmeng
Configure AppArmor
In your ~/.config/lxc/default.conf change lxc.apparmor.profile = generated to one of this option:
- lxc.apparmor.profile = unconfined
- lxc.apparmor.profile = lxc-container-default-cgnsAllow user to create unprivileged containers.
First of all, you need to make sure your user has an uid and gid map defined in /etc/subuid and /etc/subgid, And defined as following.
:~$ more /etc/subuid
myusername:100000:65536
:~$ more /etc/subgid
myusername:100000:65536The last step is to create an LXC unprivileged you need to add to ~/.config/lxc/default.conf The following lines that represent the preview subuid and subguid:
- lxc.idmap = u 0 100000 65536
- lxc.idmap = g 0 100000 65536To complete, you need allow lxc to use unprivileged containers, to allow lxc to access to your ~/.local and ~/.local/share, with set acl [acl]:
:~$ setfacl -m u:100000:x /home/myusername/.local
:~$ setfacl -m u:100000:x /home/myusername/.local/sharePrivileged Containers (as root)
For all information about all commands for LXC please see: man lxc-'cmd'
To create privileged containers, you need to define the image you want to use. To see all images list, please visit [lxc images list]
An example below:
:~# lxc-create -n mycontainername -t Distribution -- -r Release -a Arch --variant varianteTo start a privileged container an example below:
:~# lxc-start mycontainernameTo stop a privileged container an example below:
:~# lxc-stop mycontainernameTo access to a container you can attach to your terminal, an example below:
:~# lxc-attach mycontainernameTo list the containers use the following command `lxc-ls` you can add options. An example below:
~:# lxc-ls -f
				
					
						
							NAME 
							STATE 
							AUTOSTART 
							GROUPS 
							IPV4 
							IPV6 
							UNPRIVILEGED 
						 
					
					
						
							deb11 
							RUNNING 
							0 
							- 
							10.0.3.22 
							- 
							false 
						 
						
							ubu18 
							RUNNING 
							0 
							- 
							10.0.3.27 
							- 
							false 
						 
						
							alp03 
							STOPPED 
							0 
							- 
							- 
							- 
							false 
						 
					
				
Debian support IPV6 in stretch, in Debian > 9 IPV6 should be configured manually only enabled by systemd-networkd for more please see [debian IPV6]
Unprivileged Containers (as non-root)
To create unprivileged containers as non-root you must download the image with the command lxc-create an example below:
:~$ lxc-create -n mycontainername -t download -- -d debian -r bullseye -a amd64 --variant defaultIf the message *ERROR: Unable to fetch GPG key from keyserver* you must append to the command --keyserver with the ubuntu hkp as the url to deliver GPG. An example below :
:~$ lxc-create -n mycontainername -t download -- -d debian -r bullseye -a amd64 --variant default --keyserver hkp://keyserver.ubuntu.comTo start containers you need to use lxc-unprivileged-start, an example bellow:
:~$ lxc-unprivileged-start mycontainernameTo list the containers use lxc-ls with options, an example below:
~:$ lxc-ls -f
			
				
					
						NAME 
						STATE 
						AUTOSTART 
						GROUPS 
						IPV4 
						IPV6 
						UNPRIVILEGED 
					 
				
				
					
						deb10 
						RUNNING 
						0 
						- 
						10.0.3.22 
						- 
						true 
					 
					
						ubu16 
						RUNNING 
						0 
						- 
						10.0.3.27 
						- 
						true 
					 
					
						alp043 
						STOPPED 
						0 
						- 
						- 
						- 
						true 
					 
				
			
External mounts inside the containers
To mount another filesystem in the container, add to /var/lib/lxc/mycontainer/config:
lxc.mount.entry=/path/in/host/mount_point mount_point_in_container none bind 0 0Another bind mounts example:
# Exposes /dev/sde in the container
lxc.mount.entry = /dev/sde dev/sde none bind,optional,create=fileMount FS in a non-privileged container
When a container is unprivileged, the UID or GID of a mounted device has to be root in the container. To make sure we need to map the current user id to lxc.
	In ./local/share/lxc/container_name/config
	Add Mount file :
lxc.mount.entry = /path/to/host/folder /home/username/.local/share/lxc/foldername/rootfs/path/in/container none bind,rw 0 0And in .config/lxc/default.conf set mapping
# Container's UID/GID 0-65535 are mapped to host's 100000-165535,
# but UID/GID 1000 on the container is mapped to host's UID/GID 1000.
# replace the previous lxc.idmap set with the following idmap assuming that your uid = 1000 and gid =1000
lxc.idmap = u 0 100000 1000
lxc.idmap = g 0 100000 1000
lxc.idmap = u 1000 1000 1
lxc.idmap = g 1000 1000 1
lxc.idmap = u 1001 101001 64535
lxc.idmap = g 1001 101001 64535To make sure 1000 correspond to your uid and gid to know your user id
:~$ more /etc/passwd | grep your_user_name
username:x:1000:1000:Username,,,:/home/username:/bin/bashFirst 1000 user id, second 1000 group id
Check configuration
Check lxc-configuration to see if everything is enabled. Some time cgroup is not enabled by default it could be simply missing folders /sys/fs/cgroup/systemd & /sys/fs/cgroup/freezer
To enable it
# Create the folders
:~# mkdir /sys/fs/cgroup/systemd
:~# mkdir /sys/fs/cgroup/freezer
:~# mkdir /sys/fs/cgroup/freezer/0Mount cgroups into them
mount -t cgroup -o name,name=systemd systemd /sys/fs/cgroup/systemd
mount -t cgroup -ofreezer freezer /sys/fs/cgroup/freezerCheck the config again and see if it look like as the following
~:$ lxc-checkconfig
-- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
--- Control groups ---
Cgroups: enabled
Cgroup v1 mount points:
/sys/fs/cgroup/systemd
/sys/fs/cgroup/freezer
Cgroup v2 mount points:
/sys/fs/cgroup
Cgroup v1 clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled, loaded
Macvlan: enabled, not loaded
Vlan: enabled, not loaded
Bridges: enabled, loaded
Advanced netfilter: enabled, loaded
CONFIG_NF_NAT_IPV4: missing
CONFIG_NF_NAT_IPV6: missing
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, loaded
--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities:
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig Documentation
 Documentation
						 Lxccontainer
 Lxccontainer
						 Stéphane GRABER
 Stéphane GRABER
						 .
	However, our study statistical studies, in order to know the traffic on our site. If you do not want, use a Blocker, such as Adblock Plus, or Ghostery. 
	Much more effective than blocking by the site itself.
.
	However, our study statistical studies, in order to know the traffic on our site. If you do not want, use a Blocker, such as Adblock Plus, or Ghostery. 
	Much more effective than blocking by the site itself.