How to Set Up and Use LXD on CentOS 8.x / RHEL 8.x

How do I install, configure and set up LXD (lightweight Linux container) on CentOS Linux 8.x or RHEL 8.x (Red Hat Enterprise Linux)?

Linux containers give an environment as close as possible as the one you would get from a VM but without the overhead that comes with running a separate Linux kernel and simulating all the hardware. You can run your favorite Linux distributions such as Debian, Ubuntu, Arch, Gentoo, CentOS, Oracle, OpenSUSE and more. LXD is lxc on steroids with strong security on the mind. LXD is not a rewrite of LXC. Under the hood, LXD uses LXC through liblxc and its Go binding. This tutorial shows you how to set up and use LXD on CentOS 8.x cloud server and RHEL 8.x based machine.

Update RHEL/CentOS 8.x server

Excute the following yum command:
$ sudo yum update
## reboot Linux box if kernel updated ##
$ sudo reboot

See how to update and install packages for security on a CentOS 8 and RHEL 8 for more information.

Enable and configure EPEL repo

Run the following command to enable and install EPEL repo on a CentOS Linux 8.x:
$ sudo yum install
$ sudo yum update

See “How To Install EPEL Repo on an RHEL 8.x” for more info.

Install snapd on a CentOS / RHEL 8

Now that EPEL repo enabled, it is time to install snapd. We are going to install LXD on CentOS / RHEL 8 using the snap command. Hence, we must install a snapd from EPEL repo.

Search for snapd

Use any one of the following yum command/dnf command:
$ sudo yum search snapd
$ sudo yum list snapd

We can detailed information about the snapd package by executing the following command:
sudo yum info snapd

Last metadata expiration check: 0:23:43 ago on Sunday 01 March 2020 11:21:36 AM UTC.
Available Packages
Name         : snapd
Version      : 2.42.2
Release      : 1.el8
Architecture : x86_64
Size         : 18 M
Source       : snapd-2.42.2-1.el8.src.rpm
Repository   : epel
Summary      : A transactional software package manager
URL          :
License      : GPLv3
Description  : Snappy is a modern, cross-distribution, transactional package
             : manager designed for working with self-contained, immutable
             : packages.

Enable and increase user namespaces for Linux containers

We need to use the grubby command to configure bootloader and Linux kernel boot time options such as user namespaces:
$ sudo grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
Make sure you replace 2147483647 in the following example as per your needs. In other words higher number help run more Linux containers:
$ sudo sh -c 'echo "user.max_user_namespaces=2147483647" >> /etc/sysctl.d/99-userns.conf'
Reboot the Linux system, run:
$ sudo shutdown -r now
$ sudo reboot
After reboot verify that namespaces is enabled and active by typing the following cat command:
cat /proc/cmdline
Sample outputs:

BOOT_IMAGE=(hd0)/boot/vmlinuz-4.18.0-147.5.1.el8_1.x86_64 root=/dev/sda namespace.unpriv_enable=1 ro console=ttyS0,19200n8 net.ifnames=0 crashkernel=auto rhgb

Install snapd

Let us install snapd, run:
$ sudo yum install snapd

Make sure you enable classic snap support using the ln command:
$ sudo ln -s /var/lib/snapd/snap /snap
Next, activate and enable the snapd.socket service using the systemctl command:
$ sudo systemctl enable --now snapd.socket
Verify that snapd.socket and services are running:
$ sudo systemctl status snapd.socket
$ sudo systemctl status snapd.service

If snapd.service not running it, type the following commands:
$ sudo systemctl enable snapd.service
$ sudo systemctl start snapd.service

Optionally you can reboot the server and verify that those two services come online before installing LXD:
sudo reboot

Install LXD on CentOS 8.x or RHEL 8.x

Now that everything set up and running correctly, it is time to install LXD using the snap command:
$ sudo snap install lxd

Installing LXD on CentOS / RHEL 8.x server

Configuring LXD server

You can manage and use LXD without a root user account. It is a good security practice to avoid using root all time. All you have to do is add admin user account such as vivek to lxd group. The command to add existing user to Linux group is as follows:
$ sudo usermod -a -G lxd vivek
Verify it using the id command:
$ newgrp lxd
$ id

Make sure ‘vivek’ user can talk to our lxd server:
$ lxc list
Sample outputs indicating that user vivek can talk to our LXD server:

If this is your first time running LXD on this machine, you should also run: lxd init
To start your first instance, try: lxc launch ubuntu:18.04

Finally we need to configure LXD on CentOS/RHEL 8, run:
$ lxd init
Please note that Btrfs or ZFS file system packages not installed by default on a CentOS/RHEL 8.x server. So use LVM as backend storage for all your containers:

Firewalld allow incoming contention via lxdbr0

We set up a firewall for your CentOS 8 and manage with the help of firewall-cmd command. Let us list all active zones:
sudo firewall-cmd --get-active-zones
If lxdbr0 not listed, add to the trusted zone so that connection will go through. In other words, allow all incoming traffic via lxdbr0:
sudo firewall-cmd --add-interface=lxdbr0 --zone=trusted
Verify it:
sudo firewall-cmd --get-active-zones

  interfaces: eth0 
  interfaces: lxdbr0

See “How to set up a firewall using FirewallD on RHEL 8” for more info.

Create and launch your first container

You can list all container images with the following command:
$ lxc image list images:

Listing all images

Of course, you can use the grep command/egrep command to filter out images too:
$ lxc image list images: | grep -i centos
$ lxc image list images: | egrep -i 'ubuntu|debian'

How create and set up your first container using LXD

To create and start containers from images use the launch command as follows:
lxc launch images:{distro}/{version}/{arch} {container-name-here}
Let us see some examples to create and start containers from various Linux distro images as per your needs.

CentOS Linux 6/7/8 container

$ lxc launch images:centos/6/amd64 cenots-c6
$ lxc launch images:centos/7/amd64 cenots-c7
$ lxc launch images:centos/8/amd64 cenots-db

Debian Linux 18.4 LTS

$ lxc launch images:ubuntu/18.04/amd64 ubuntu-www1

Fedora Linux 31

$ lxc launch images:fedora/31/amd64 fedora31-c1

Okay, I have set up and use LXD on CentOS/RHEL 8.x, what next?

List your containers:
$ lxc list
Sample outputs:

|    NAME     |  STATE  |         IPV4          | IPV6 |   TYPE    | SNAPSHOTS |
| cenots-c6   | RUNNING | (eth0) |      | CONTAINER | 0         |
| cenots-c7   | RUNNING | (eth0)  |      | CONTAINER | 0         |
| cenots-db   | RUNNING | (eth0) |      | CONTAINER | 0         |
| fedora31-c1 | RUNNING | (eth0) |      | CONTAINER | 0         |
| ubuntu-www1 | RUNNING | (eth0) |      | CONTAINER | 0         |

To start/stop/restart containers use:
$ lxc start container-name
$ lxc stop container-name
$ lxc restart container-name
$ lxc restart ubuntu-www1

Remove or delete container
$ lxc delete container-name
## stop and delete container named fedora31-c1 ##
$ lxc stop fedora31-c1
$ lxc delete fedora31-c1

Getting info about your container:
$ lxc info container
$ lxc info centos-db

Execute commands in instances/containers:
$ lxc exec container command
$ lxc exec ubuntu-www1 ls /
$ lxc exec ubuntu-www1 -- apt -y update
$ lxc exec ubuntu-www1 -- apt-get -y upgrade
$ lxc exec cenots-db -- yum -y update

Pass the --user to run the command as vivek user in centos-c7:
$ lxc exec centos-c7 --user vivek -- command1
$ lxc exec centos-c7 --user www-data -- my-app-server --debug

Gain root shell:
$ lxc exec container sh
$ lxc exec centos-db sh
$ lxc exec ubuntu-www1 bash

How to set up up firewall-cmd rules to redirect traffic

Now LXD based containers and services are running. How do you reach insider containers from the outside world? You have two options:

  1. Use reverse proxy server such as Nginx
  2. Set up firewall rules to redirect port to containers

Examples (type on host)

Find default zone:
$ sudo firewall-cmd --get-default-zone

Open port 443 for public zone
$ sudo firewall-cmd --zone=public --add-service=https --permanent
Forward port 443 to the LXD server
$ sudo firewall-cmd --permanent --zone=public --add-forward-port=port=443:proto=tcp:toport=443:toaddr=
Reload the firewalld:
$ sudo firewall-cmd --reload
Test it. Fire the web browser and type urls as per your set up:


We just learned and deployed LXD on CentOS 8.x machine and LXD on RHEL 8.x server. You can now use your container as an independent jail or app server isolated from the main host. You can redirect traffic using firewalld to containers TCP/UDP ports. For more info see the official project homepages here and here.

🐧 Please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Problem posting comment? Email me @