sodcalculator

10 Tech How-To

Run Multiple Linux Distros with LXC Containers

Guide 10-13372 · Updated · Step by step

This guide shows you how to run several Linux distributions side by side on a single host using Linux Containers (LXC). Instead of spinning up full virtual machines, LXC gives you lightweight, isolated environments that share your host’s kernel but keep their own userspace, packages, and configuration. You’ll learn how to install LXC, create containers from official distro templates, manage them from the command line, and avoid the common pitfalls that trip up first-time users.

What You’ll Need

  • A Linux host (Ubuntu 20.04+, Debian 11+, or any distro with LXC packages). You’ll need root or sudo access.
  • An internet connection to download templates and packages.
  • Basic comfort with the terminal and command-line tools.
  • At least 1 GB of free RAM and a few GB of disk space, depending on how many distros you plan to run.

Step-by-Step

  1. Install LXC. On Debian/Ubuntu, run sudo apt update && sudo apt install lxc lxc-templates. On Fedora, use sudo dnf install lxc lxc-templates. For Arch, sudo pacman -S lxc. Verify the install with lxc-checkconfig – it should show all items as “enabled” or at least not “missing”.
  2. Set up the LXC network bridge (optional but recommended). During install, LXC may create a default bridge called lxcbr0. Check with ip addr show lxcbr0. If it’s missing, edit /etc/default/lxc-net and set USE_LXC_BRIDGE="true", then restart with sudo systemctl restart lxc-net (or sudo service lxc-net restart).
  3. Create your first container. Use the lxc-create command with a template. For example, to create an Ubuntu 22.04 container named “ubuntu1”: sudo lxc-create -n ubuntu1 -t download -- -d ubuntu -r jammy -a amd64. The -t download template fetches a pre-built rootfs from the LXC image server. You’ll be prompted to choose a distribution, release, and architecture.
  4. Start the container. sudo lxc-start -n ubuntu1. Check its status with sudo lxc-ls -f – you should see the container with a state of RUNNING and an IP address.
  5. Enter the container. Use sudo lxc-attach -n ubuntu1 to get a root shell inside. You can also use sudo lxc-console -n ubuntu1 for a console login (default user is root, no password unless you set one). To exit the attach shell, type exit.
  6. Create more distros. Repeat step 3 with different parameters. For Debian 12: sudo lxc-create -n debian12 -t download -- -d debian -r bookworm -a amd64. For Alpine: sudo lxc-create -n alpine -t download -- -d alpine -r 3.18 -a amd64. For CentOS Stream: sudo lxc-create -n centos -t download -- -d centos -r stream9 -a amd64. You can also use older templates like ubuntu or debian directly, but the download template is more reliable.
  7. Manage containers. List all with sudo lxc-ls -f. Stop a container with sudo lxc-stop -n ubuntu1. Remove it with sudo lxc-destroy -n ubuntu1. To auto-start a container on boot, set lxc.start.auto = 1 in its config file (/var/lib/lxc/ubuntu1/config).
  8. Install software inside a container. Attach to the container and use its native package manager. For Ubuntu/Debian: apt update && apt install vim. For Alpine: apk add vim. For CentOS: dnf install vim. The container shares your host’s kernel, so you can run most software that works on your host’s architecture.
  9. Copy files in and out. From the host, use sudo lxc-file push /host/file ubuntu1/root/ to copy a file into the container, and sudo lxc-file pull ubuntu1/etc/os-release . to copy a file out.
  10. Snapshot and clone. To snapshot a running container: sudo lxc-snapshot -n ubuntu1. To clone a container: sudo lxc-copy -n ubuntu1 -N ubuntu2 (this creates a new container named ubuntu2 based on ubuntu1).

Common Mistakes

  • Forgetting to start the LXC network bridge. If your container has no IP address or can’t reach the internet, the bridge is often the culprit. Check ip addr show lxcbr0 and restart lxc-net.
  • Using the wrong template name. The download template is the most reliable for getting a working distro. Older templates like ubuntu or debian may fail on newer hosts due to outdated scripts.
  • Running out of disk space. Each container can take several hundred MB to a few GB. Check your host’s free space with df -h before creating many containers.
  • Assuming containers are VMs. LXC containers share the host kernel, so you cannot run a different kernel version inside a container. For example, you can’t run a container with a 5.4 kernel on a host with 6.2 – it will use the host’s kernel.
  • Not setting a root password. When you use lxc-console, you may be prompted for a login. By default, the root account has no password, so you can’t log in via console. Use lxc-attach instead, or set a password inside the container with passwd.

Tips

  • Use lxc-attach for quick admin tasks – it’s faster than console and doesn’t require a password.
  • Name your containers descriptively (e.g., web-dev-ubuntu, db-centos) to avoid confusion.
  • Keep containers updated regularly. Just like any Linux system, they need security patches.
  • Back up important containers with lxc-snapshot before making big changes.
  • If you need GUI apps, consider using lxc-attach with X11 forwarding (set DISPLAY and mount your X11 socket) – but it’s often simpler to run GUI apps on the host and only use containers for services.
  • Use the lxc-copy command to quickly spin up test environments from a base container.

Troubleshooting

  • Container won’t start. Check the logs with sudo lxc-start -n ubuntu1 -l trace -o /tmp/lxc.log and look at the end of the file. Common causes: missing template, kernel module not loaded (try sudo modprobe veth), or insufficient permissions.
  • No network inside container. First, verify the bridge exists: ip addr show lxcbr0. If it’s down, run sudo systemctl restart lxc-net. If the container still has no IP, attach and check ip addr – you may need to run dhclient eth0 inside the container (or use systemctl restart networking on Debian/Ubuntu).
  • DNS not working. Inside the container, check /etc/resolv.conf. If it’s empty, add nameserver 8.8.8.8 or your host’s DNS. The bridge usually forwards DNS automatically, but sometimes you need to set it manually.
  • Permission denied when using lxc commands. Make sure you’re using sudo. LXC commands need root privileges to manage containers.
  • Template download fails. This often happens due to network restrictions or the image server being down. Try again later, or manually download a rootfs tarball and use lxc-create -n name -t local -- --tarball /path/to/rootfs.tar.xz.
  • Container shows as STOPPED after reboot. Containers don’t auto-start by default. To enable auto-start, add lxc.start.auto = 1 to the container’s config file, then restart the host or run sudo lxc-start -n ubuntu1 manually.

Frequently Asked Questions

Can I run a different kernel inside an LXC container?

No. LXC containers share the host’s kernel. You can only run userspace from different distributions. If you need a different kernel, use a full virtual machine (KVM, VirtualBox) instead.

How do I access a container from another machine on my network?

By default, containers are on a private bridge (lxcbr0) and are not accessible from outside. To expose a service, use port forwarding with iptables or run the container in bridged mode (set lxc.net.0.type = veth and lxc.net.0.link = your_bridge where your_bridge is a bridge that has an interface on your LAN).

Can I run GUI applications inside a container?

Yes, but it requires extra setup. You can use X11 forwarding: on the host, run xhost +local: and then inside the container set DISPLAY=:0 and mount the X11 socket. However, this is finicky; for GUI apps, consider using a full VM or a container with VNC.

What is the difference between LXC and Docker?

LXC creates full system containers that behave like a lightweight VM – you can run init systems, multiple processes, and manage them like a real machine. Docker is designed for running single-purpose applications with a minimal footprint, and it uses a different isolation model (often with more restrictions). LXC is closer to a traditional OS environment.

How do I update containers?

Attach to the container and use its native package manager. For Ubuntu/Debian: apt update && apt upgrade. For Alpine: apk update && apk upgrade. For CentOS: dnf update.

Can I run 32-bit containers on a 64-bit host?

Yes, if your host kernel has 32-bit compatibility enabled (most do). Use -a i386 when creating the container. However, you may need to install 32-bit libraries on the host.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →