A historic moment: this episode guides you through creating your first container with lxc-create and the download template, checking its status with lxc-ls and lxc-info, then starting it with lxc-start and getting inside it via lxc-attach, lxc-console, and lxc-execute.

The environment is ready (episodes 0-3), and the concepts are understood (episodes 1-2). Now it's time for action: creating your first container. In episode 4 we create an Ubuntu 24.04 container named c1, inspect its status, start it, and get inside it through several methods. By the end of the episode, you'll have a complete Linux system running inside a container — no VM, no hypervisor.
Run:
lxc-create -n c1 -t download -- -d ubuntu -r 24.04 -a amd64Let's break down the flags:
-n c1 — container name (c1).-t download — uses the download template, which fetches images from the official image server.-d ubuntu — target distro.-r 24.04 — release (Ubuntu 24.04).-a amd64 — host architecture.On first run, the template will ask about the mirror and key — accept the defaults. The process downloads the rootfs, extracts it to /var/lib/lxc/c1/rootfs, and writes the config to /var/lib/lxc/c1/config.
Tip
The download template uses the official image server from linuxcontainers.org. To look for image candidates, you can type lxc-create -n c1 -t download -- --list to see the list of available distros and releases. This is also the best way to validate your -d, -r, and -a values before running.
List the containers:
lxc-ls -fThe output shows columns like NAME, STATE, AUTOSTART, and IPV4. For details on a single container:
lxc-info -n c1At this point the state is still STOPPED. Also check the generated directory structure:
ls -la /var/lib/lxc/c1/
cat /var/lib/lxc/c1/configStart the container:
lxc-start -n c1lxc-start runs the container in the background (daemonized). After a few seconds, check its status:
lxc-info -n c1
lxc-ls -fA container with systemd will need a few seconds to fully boot. The state should change to RUNNING.
lxc-attach runs a command directly inside the container's namespaces, without a login process:
lxc-attach -n c1 -- hostnameFor an interactive shell:
lxc-attach -n c1Once inside, verify that you're really "inside":
hostname
cat /etc/os-release
ps aux | head -10
exitThe hostname and ps must belong to the container, not the host. That's proof that the PID and UTS namespaces are working.
lxc-console connects you to the container's serial console — like plugging a monitor into a virtual machine. Great for watching the boot log or logging in on a tty:
lxc-console -n c1To exit the console, press Ctrl+A then Q (not Ctrl+D).
Caution
lxc-attach doesn't log in — it directly executes commands as the user configured in the container (usually root). This is very practical for administration, but don't misuse it as "user access": for non-root accounts, use lxc-console and log in normally, or ssh to the container's IP.
Unlike lxc-attach, which enters a running container, lxc-execute creates a fresh container environment to run a single command and then stops:
lxc-execute -n c1 -- ls /Since it creates a new environment every time, lxc-execute is better suited for short jobs and testing, not for interacting with a running container.
To shut it down:
lxc-stop -n c1
lxc-info -n c1The state returns to STOPPED. Don't delete the container yet — we'll use it again in episodes 5 and 6.
Warning
Containers don't restart automatically after a host reboot unless lxc.start.auto is enabled (episode 10). Don't be surprised if a container "disappears" after a reboot — check lxc-ls -f before panicking, and bring it back up with lxc-start.
Key takeaways:
lxc-create -n c1 -t download -- -d ubuntu -r 24.04 -a amd64 creates an Ubuntu 24.04 container.lxc-ls -f and lxc-info -n c1 are your eyes into container status.lxc-start starts the container; lxc-stop stops it.lxc-attach enters without login; lxc-console is like a VM monitor; lxc-execute is for one-shot execution.hostname and ps inside the container prove namespace isolation.In the next episode 5 we'll compare privileged vs unprivileged containers — why root inside a privileged container is the same as root on the host, and how unprivileged containers map users via user namespaces + idmapping to become the safe modern default for multi-tenant environments.