How to Use Ubuntu Server lxc for Lightweight Containers

While Docker has become synonymous with “containers,” Docker is actually designed for application containers—running a single process, like a web server or a database, in isolation. But what if you want an entire operating system (with an init system, cron, syslog, and multiple users) running in isolation, without the massive CPU and RAM overhead of a traditional Virtual Machine (like VMware or VirtualBox)? For this, Ubuntu Server provides native support for LXC (Linux Containers) and its modern manager, LXD.

What is LXC/LXD?

LXC provides “system containers.” To the user inside the container, it looks and feels exactly like a full Virtual Machine. You can SSH into it, install packages with apt, and run multiple services. However, because it shares the host’s Linux kernel rather than emulating hardware, you can run hundreds of LXC containers on a single physical server that might only be able to handle ten traditional VMs.

Step 1: Initialize LXD

On modern Ubuntu Server installations, LXD (the daemon that manages LXC containers) is pre-installed via Snap. Before creating your first container, you must run the initialization script to configure the storage backend and virtual network switch.

sudo lxd init

You will be asked a series of questions. For a basic setup, you can safely press Enter to accept the default values for every question. This will create a default storage pool (using ZFS or Btrfs) and an internal bridge network (lxdbr0) with NAT, allowing your containers to reach the internet.

Step 2: Launch Your First Container

Creating a container is remarkably fast. You simply tell LXC which operating system image to download and what to name the container.

lxc launch ubuntu:22.04 webserver1

LXD will download the official Ubuntu 22.04 LTS image (caching it locally for future use) and instantly spin up a container named webserver1. The entire process usually takes less than 10 seconds.

Step 3: Manage Your Containers

To see a list of all your running containers, along with their assigned IP addresses on the internal bridge network:

lxc list

To stop a container:

lxc stop webserver1

To completely delete a container (this destroys all data inside it):

lxc delete webserver1

Step 4: Execute Commands Inside the Container

You don’t need to configure SSH to access the container; LXC provides a direct, highly privileged backdoor via the exec command.

To run a single command (like installing Apache) inside the container from the host machine:

lxc exec webserver1 -- apt install apache2 -y

To drop yourself into an interactive bash shell as the root user inside the container:

lxc exec webserver1 -- /bin/bash

Your prompt will change. You are now inside the isolated OS. Any files you delete or services you break here will have absolutely zero impact on the host Ubuntu Server.

Step 5: Resource Limits

By default, an LXC container can consume all the CPU and RAM available on the host machine. You can easily constrain it using lxc config.

To limit the webserver1 container to exactly 512MB of RAM:

lxc config set webserver1 limits.memory 512MB

To restrict it to using only two CPU cores:

lxc config set webserver1 limits.cpu 2

With LXC, you gain the complete administrative freedom of a Virtual Machine, combined with the bare-metal performance and near-instant boot times of a container.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.