Overview #
LXC:
-
Allows running multiple isolated Linux environments (containers) on a single host using a shared kernel
-
Only supports Linux containers
LXD:
-
Written in Go and is built on top of LXC, it aims to provide a simplified user experience
-
Can run both containers and full VMs
LXD Setup #
Installation #
# Install LXD package: Debian
sudo apt -y install lxd
# Verify the installation / check version
lxd --version
# Shell output:
5.0.2
Add User to LXD Group #
# Add the current user to the LXD group
sudo usermod -aG lxd $USER
Initialize LXD Service #
Start the LXD configuration:
# Initialize LXD
lxd init
# Shell output:
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: pool1
Name of the storage backend to use (dir, lvm) [default=dir]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
I use the default settings for every option:
-
“dir” storage backend: LXD will use a local directory on the server as the storage pool
-
MAAS server (Metal as a Service): Automated bare-metal provisioning system
-
Local network bridge “lxdbr0”: LXD will create a bridge interface for the containers connect to. Containers have outbound internet access via NAT.
-
LXD server not available over the network: Prevents external access to the LXD API
-
Automatically update stale cached images: LXD will periodically check and refresh outdated cached images of containers
Verify the Installation #
List Default Profile #
# List the default profile details
lxc profile show default
# Shell output:
config: {}
description: Default LXD profile
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
used_by: []
Verify Network #
# List available network interfaces
sudo lxc network list
# Shell output:
+--------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
| NAME | TYPE | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY | STATE |
+--------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
| ens33 | physical | NO | | | | 0 | |
+--------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
| lxdbr0 | bridge | YES | 10.163.195.1/24 | fd42:ea24:d55e:5620::1/64 | | 2 | CREATED |
+--------+----------+---------+-----------------+---------------------------+-------------+---------+---------+
# List details of specific interface "lxdbr0"
lxc network show lxdbr0
# Shell output:
config:
ipv4.address: 10.163.195.1/24
ipv4.nat: "true"
ipv6.address: fd42:ea24:d55e:5620::1/64
ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
used_by:
- /1.0/profiles/default
managed: true
status: Created
locations:
- none
Verify Storage Pool #
# List the storage pools
lxc storage list
# Shell output:
+---------+--------+------------------------------------+-------------+---------+---------+
| NAME | DRIVER | SOURCE | DESCRIPTION | USED BY | STATE |
+---------+--------+------------------------------------+-------------+---------+---------+
| default | dir | /var/lib/lxd/storage-pools/default | | 1 | CREATED |
+---------+--------+------------------------------------+-------------+---------+---------+
Container Images #
Remove Old Image Server #
# Remove the old image server
lxc remote remove images
Add LXD Image Server #
Add the new LXD image server: https://images.lxd.canonical.com/
# Add image server
lxc remote add images https://images.lxd.canonical.com --protocol=simplestreams
List Image Servers #
# List the current image servers
lxc remote list
# Shell output:
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| NAME | URL | PROTOCOL | AUTH TYPE | PUBLIC | STATIC | GLOBAL |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| images | https://images.lxd.canonical.com | simplestreams | none | YES | NO | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| local (current) | unix:// | lxd | file access | NO | YES | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | none | YES | YES | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | none | YES | YES | NO |
+-----------------+------------------------------------------+---------------+-------------+--------+--------+--------+
List Available Images #
List available prebuilt container images:
# List images: Ubuntu
lxc image list ubuntu:
# List images: LXD default server
lxc image list images:
Filter for specific Images:
# List images: LXD default server, filter for "Alma"
lxc image list images: almalinux
# Shell output:
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8 (3 more) | 554961f01a67 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | VIRTUAL-MACHINE | 906.14MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8 (3 more) | c1aa5f943701 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | CONTAINER | 129.01MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/arm64 (1 more) | 457dc8ca19b1 | yes | AlmaLinux 8 arm64 (20250224_0033) | aarch64 | CONTAINER | 125.25MB | Feb 24, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/cloud (1 more) | 338b18526be0 | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | CONTAINER | 148.67MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/cloud (1 more) | c66262652dbd | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 925.27MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/cloud/arm64 | f1e3be751f21 | yes | AlmaLinux 8 arm64 (20250224_0033) | aarch64 | CONTAINER | 144.40MB | Feb 24, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9 (3 more) | 91a8ff758f3a | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | VIRTUAL-MACHINE | 780.70MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9 (3 more) | bb511c6896a8 | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | CONTAINER | 118.43MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/arm64 (1 more) | 975d3afc6ee5 | yes | AlmaLinux 9 arm64 (20250224_0033) | aarch64 | CONTAINER | 114.26MB | Feb 24, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/cloud (1 more) | 8d1e851396f8 | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | CONTAINER | 134.49MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/cloud (1 more) | 0274d83c7ceb | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 801.48MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/cloud/arm64 | 06d4d9a67523 | yes | AlmaLinux 9 arm64 (20250224_0033) | aarch64 | CONTAINER | 130.09MB | Feb 24, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
# List images: LXD default server, filter for "Alma", list only "x86_64" (amd64)
lxc image list images: almalinux arch=amd64
# Shell output:
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8 (3 more) | 554961f01a67 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | VIRTUAL-MACHINE | 906.14MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8 (3 more) | c1aa5f943701 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | CONTAINER | 129.01MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/cloud (1 more) | 338b18526be0 | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | CONTAINER | 148.67MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/8/cloud (1 more) | c66262652dbd | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 925.27MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9 (3 more) | 91a8ff758f3a | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | VIRTUAL-MACHINE | 780.70MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9 (3 more) | bb511c6896a8 | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | CONTAINER | 118.43MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/cloud (1 more) | 8d1e851396f8 | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | CONTAINER | 134.49MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
| almalinux/9/cloud (1 more) | 0274d83c7ceb | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 801.48MB | Feb 27, 2025 at 12:00am (UTC) |
+----------------------------+--------------+--------+-----------------------------------+--------------+-----------------+----------+-------------------------------+
# List images: LXD default server, filter for "Alma" (alternative command)
lxc image list images: | grep -i almalinux
# Shell output:
| almalinux/8 (3 more) | 554961f01a67 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | VIRTUAL-MACHINE | 906.14MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/8 (3 more) | c1aa5f943701 | yes | AlmaLinux 8 amd64 (20250227_0014) | x86_64 | CONTAINER | 129.01MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/8/arm64 (1 more) | 457dc8ca19b1 | yes | AlmaLinux 8 arm64 (20250224_0033) | aarch64 | CONTAINER | 125.25MB | Feb 24, 2025 at 12:00am (UTC) |
| almalinux/8/cloud (1 more) | 338b18526be0 | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | CONTAINER | 148.67MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/8/cloud (1 more) | c66262652dbd | yes | AlmaLinux 8 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 925.27MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/8/cloud/arm64 | f1e3be751f21 | yes | AlmaLinux 8 arm64 (20250224_0033) | aarch64 | CONTAINER | 144.40MB | Feb 24, 2025 at 12:00am (UTC) |
| almalinux/9 (3 more) | 91a8ff758f3a | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | VIRTUAL-MACHINE | 780.70MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/9 (3 more) | bb511c6896a8 | yes | AlmaLinux 9 amd64 (20250227_0015) | x86_64 | CONTAINER | 118.43MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/9/arm64 (1 more) | 975d3afc6ee5 | yes | AlmaLinux 9 arm64 (20250224_0033) | aarch64 | CONTAINER | 114.26MB | Feb 24, 2025 at 12:00am (UTC) |
| almalinux/9/cloud (1 more) | 8d1e851396f8 | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | CONTAINER | 134.49MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/9/cloud (1 more) | 0274d83c7ceb | yes | AlmaLinux 9 amd64 (20250227_0013) | x86_64 | VIRTUAL-MACHINE | 801.48MB | Feb 27, 2025 at 12:00am (UTC) |
| almalinux/9/cloud/arm64 | 06d4d9a67523 | yes | AlmaLinux 9 arm64 (20250224_0033) | aarch64 | CONTAINER | 130.09MB | Feb 24, 2025 at 12:00am (UTC) |
| | 5f00ce0dd58d | yes | AlmaLinux 9 arm64 (20250217_0033) | aarch64 | CONTAINER | 130.09MB | Feb 17, 2025 at 12:00am (UTC) |
| | 9e275c5cce43 | yes | AlmaLinux 9 arm64 (20250217_0033) | aarch64 | CONTAINER | 114.27MB | Feb 17, 2025 at 12:00am (UTC) |
| | 13afc0276ddc | yes | AlmaLinux 9 amd64 (20250226_0013) | x86_64 | CONTAINER | 118.43MB | Feb 26, 2025 at 12:00am (UTC) |
| | 39abc7c1940e | yes | AlmaLinux 9 amd64 (20250226_0013) | x86_64 | VIRTUAL-MACHINE | 780.84MB | Feb 26, 2025 at 12:00am (UTC) |
| | a0b88c058ff7 | yes | AlmaLinux 8 amd64 (20250226_0013) | x86_64 | VIRTUAL-MACHINE | 925.09MB | Feb 26, 2025 at 12:00am (UTC) |
| | ad8d926ec74b | yes | AlmaLinux 8 amd64 (20250226_0013) | x86_64 | VIRTUAL-MACHINE | 906.14MB | Feb 26, 2025 at 12:00am (UTC) |
| | b9a3507dacf5 | yes | AlmaLinux 8 arm64 (20250217_0033) | aarch64 | CONTAINER | 144.38MB | Feb 17, 2025 at 12:00am (UTC) |
| | b58464968cf0 | yes | AlmaLinux 8 amd64 (20250226_0013) | x86_64 | CONTAINER | 148.67MB | Feb 26, 2025 at 12:00am (UTC) |
| | beb8e7c80ecf | yes | AlmaLinux 9 amd64 (20250226_0014) | x86_64 | VIRTUAL-MACHINE | 801.64MB | Feb 26, 2025 at 12:00am (UTC) |
| | cd10cc797ed0 | yes | AlmaLinux 8 arm64 (20250217_0033) | aarch64 | CONTAINER | 125.26MB | Feb 17, 2025 at 12:00am (UTC) |
| | d910e1915571 | yes | AlmaLinux 9 amd64 (20250226_0014) | x86_64 | CONTAINER | 134.49MB | Feb 26, 2025 at 12:00am (UTC) |
| | d850461e9924 | yes | AlmaLinux 8 amd64 (20250226_0013) | x86_64 | CONTAINER | 129.01MB | Feb 26, 2025 at 12:00am (UTC) |
List Image Details #
# List details of specific image
lxc image info images:almalinux/9
# Alternative
lxc image info images:bb511c6896a8
# Shell output:
Fingerprint: bb511c6896a826059af48eb6db0c2818de7515d171be13f045054e702d91d096
Size: 118.43MB
Architecture: x86_64
Type: container
Public: yes
Timestamps:
Created: 2025/02/27 00:00 UTC
Uploaded: 2025/02/27 00:00 UTC
Expires: never
Last used: never
Properties:
os: AlmaLinux
release: 9
architecture: amd64
type: squashfs
serial: 20250227_0015
description: AlmaLinux 9 amd64 (20250227_0015)
variant: default
Aliases:
- almalinux/9/default
- almalinux/9/default/amd64
- almalinux/9
- almalinux/9/amd64
Cached: no
Auto update: disabled
Profiles: []
Launch Prebuilt Container #
Create Container #
Note: For a unknown reason I had problems running containers from the “images” list, so I just used an image from the “ubuntu” list instead.
# Create an example Ubuntu based container
sudo lxc launch ubuntu:7a0b671dbca3 example-ubuntu-container
# Shell output:
Creating example-ubuntu-container
Starting example-ubuntu-container
List Containers #
# List containers
sudo lxc list
# Shell output:
+--------------------------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------------------------+---------+------+------+-----------+-----------+
| example-ubuntu-container | RUNNING | | | CONTAINER | 0 |
+--------------------------+---------+------+------+-----------+-----------+
List Container Details #
# List container details
sudo lxc info example-ubuntu-container
# Shell output:
Name: example-ubuntu-container
Status: RUNNING
Type: container
Architecture: x86_64
PID: 45910
Created: 2025/02/27 18:03 CET
Last Used: 2025/02/27 18:03 CET
Resources:
Processes: 27
CPU usage:
CPU usage (in seconds): 3
Memory usage:
Memory (current): 67.54MiB
Network usage:
eth0:
Type: broadcast
State: UP
Host interface: vethbe32030d
MAC address: 00:16:3e:7f:0d:db
MTU: 1500
Bytes received: 310.13kB
Bytes sent: 9.83kB
Packets received: 160
Packets sent: 114
IP addresses:
inet: 10.163.195.54/24 (global)
inet6: fd42:ea24:d55e:5620:216:3eff:fe7f:ddb/64 (global)
inet6: fe80::216:3eff:fe7f:ddb/64 (link)
lo:
Type: loopback
State: UP
MTU: 65536
Bytes received: 1.29kB
Bytes sent: 1.29kB
Packets received: 12
Packets sent: 12
IP addresses:
inet: 127.0.0.1/8 (local)
inet6: ::1/128 (local)
Nginx Test #
Install Nginx #
# Install Nginx inside the container
lxc exec example-ubuntu-container -- apt update
lxc exec example-ubuntu-container -- apt install -y nginx
Add HTML File #
- index.html
<!DOCTYPE html>
<html>
<head>
<title>jklug.work</title>
</head>
<body>
<h1>Some text</h1>
</body>
</html>
# Copy the index.html file into the container
lxc file push index.html example-ubuntu-container/var/www/html/index.html
Access the Container Terminal #
# Access the container terminal
lxc exec example-ubuntu-container -- bash
# Test Nginx
curl localhost
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>jklug.work</title>
</head>
...
# Exit the container terminal
exit
Add Port Forwarding #
# Add a port forwarding rule
lxc config device add example-ubuntu-container example-webserver proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80
# Shell output:
Device example-webserver added to example-ubuntu-container
Access Nginx Webserver #
Access the Nginx webserver inside the container from an external host:
# Curl the LXD server IP
curl 192.168.30.20:8080
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>jklug.work</title>
</head>
...
Remove Port Forwarding #
# Remove the port forwarding rule
lxc config device remove example-ubuntu-container example-webserver
# Shell output:
Device example-webserver removed from example-ubuntu-container
Start, Stop & Delete Container #
# Stop the container
lxc stop example-ubuntu-container
# Start the container
lxc start example-ubuntu-container
# Restart the container
lxc restart example-ubuntu-container
# Delete the container (stop it first)
lxc delete example-ubuntu-container
Create Custom Container Image #
Create Container #
# Create an example Ubuntu based container
sudo lxc launch ubuntu:7a0b671dbca3 ubuntu-nginx-container
Customize the Container #
Install Nginx #
# Install Nginx inside the container
lxc exec ubuntu-nginx-container -- apt update
lxc exec ubuntu-nginx-container -- apt install -y nginx
Add HTML File #
- index.html
<!DOCTYPE html>
<html>
<head>
<title>jklug.work</title>
</head>
<body>
<h1>Some text</h1>
</body>
</html>
# Copy the index.html file into the container
lxc file push index.html ubuntu-nginx-container/var/www/html/index.html
Stop the Container #
# Stop the container
lxc stop ubuntu-nginx-container
# Verify the container is stopped / list containers
sudo lxc list
# Shell output:
+------------------------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------------------------+---------+------+------+-----------+-----------+
| ubuntu-nginx-container | STOPPED | | | CONTAINER | 0 |
+------------------------+---------+------+------+-----------+-----------+
Convert Container to Image #
# Create LXD image and save it locally as "ubuntu-nginx"
lxc publish ubuntu-nginx-container --alias ubuntu-nginx
# Shell output:
Instance published with fingerprint: d509022631812336e4c311de8440bfdc9847340c30df8b2cab0020b5587dd946
Verify the container image:
# List container image
lxc image list
# Shell output:
+--------------+--------------+--------+---------------------------------------------+--------------+-----------+----------+------------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE |
+--------------+--------------+--------+---------------------------------------------+--------------+-----------+----------+------------------------------+
| ubuntu-nginx | d50902263181 | no | Ubuntu 24.04 LTS server (20250226) | x86_64 | CONTAINER | 385.33MB | Feb 27, 2025 at 4:45pm (UTC) |
+--------------+--------------+--------+---------------------------------------------+--------------+-----------+----------+------------------------------+
Launch Container from Custom Image #
Launch Container #
# Launch a new container from the custom image
lxc launch ubuntu-nginx custom-nginx-container
# Verify the container is stopped / list containers
sudo lxc list
# Shell output:
+------------------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------------------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
| custom-nginx-container | RUNNING | 10.163.195.42 (eth0) | fd42:ea24:d55e:5620:216:3eff:fe48:8f2b (eth0) | CONTAINER | 0 |
+------------------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
| ubuntu-nginx-container | STOPPED | | | CONTAINER | 0 |
+------------------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
Add Port Forwarding #
# Add a port forwarding rule
lxc config device add custom-nginx-container custom-image-webserver proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80
# Shell output:
Device custom-image-webserver added to custom-nginx-container
Access Nginx Webserver #
Access the Nginx webserver inside the container from an external host:
# Curl the LXD server IP
curl 192.168.30.20:8080
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>jklug.work</title>
</head>
...
Remove Port Forwarding #
# Remove the port forwarding rule
lxc config device remove custom-nginx-container custom-image-webserver
# Shell output:
Device custom-image-webserver removed from custom-nginx-container
Stop & Delete the Container #
# Stop the container
lxc stop ubuntu-nginx-container
# Delete the container
lxc delete ubuntu-nginx-container
Delete the Image #
# Delete the custom image
lxc image delete ubuntu-nginx
Links #
# LXC Official Documentation
https://linuxcontainers.org/lxc/documentation/