This document describes the step-by-step procedure for the initial setup of nc-env in an Ubuntu Destkop system.
Check the project homepage to know more about nc-env.
Component | Version |
---|---|
Operating System | Ubuntu 20.04.4 LTS (Focal Fossa) |
LXD | 5.0.0 |
vagrant | 2.2.19 |
vagrant-lxd | 0.5.6 |
Component | Version |
---|---|
Operating System | Ubuntu 22.04.3 LTS (Jammy Jellyfish) |
LXD | 5.19 |
vagrant | 2.4.0 |
vagrant-lxd | 0.7.0 |
Install all the software needed for the project, starting by updating the package repositories:
$ sudo apt update
The following packages are not strictly needed, but may make the following operations more agile, depending on the user tooling preferences.
$ sudo apt install vim tree
However, rysnc is needed, so install it:
$ sudo apt install rsync
Install LXD using snap:
$ sudo snap install lxd lxd 5.12-c63881f from Canonical\u2713 installed
Verify that LXD has been correctly installed:
$ snap list lxd Name Version Rev Tracking Publisher Notes lxd 5.12-c63881f 24643 latest/stable canonical\u2713 -
LXD supports several storage backends, you can get more information in the documentation.
These are the recommended options, in descending order:
In any case, it is recommended to assign nc-env at least 20 GB.
Go through this section only if you choose option 1 above.
If you plan to use ZFS as backend for the LXD storage pools, you should have a disk or unformatted partition, of 20GB or more, for that.
Install the ZFS package:
$ sudo apt install zfsutils-linux
Verify that it has been correctly installed:
$ sudo zpool --version zfs-2.1.5-1ubuntu6~22.04.1 zfs-kmod-2.1.5-1ubuntu6~22.04.1
From the official installation documentation page:
$ wget -O /tmp/hashicorp-gpg https://apt.releases.hashicorp.com/gpg $ sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg /tmp/hashicorp-gpg $ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list $ sudo apt update
Install the vagrant package:
$ sudo apt install vagrant
Verify that it has been correctly installed:
$ vagrant --version Vagrant 2.3.4
Vagrant plugins are installed by using the plugin
switch, so let's install the vagrant-lxd
plugin by issuing the following command:
$ vagrant plugin install vagrant-lxd
Verify that it has been correctly installed:
$ vagrant plugin list vagrant-lxd (0.6.0, global)
Install mkcert, an utility that makes it easy to create locally trusted TLS certificates, from APT repositories
$ sudo apt install mkcert
Run the install command
$ mkcert -install Created a new local CA π₯ The local CA is now installed in the system trust store! β‘οΈ
Check the local CAROOT folder by issuing the following command. We will need to make the files in that folder available to the containers as well:
$ mkcert -CAROOT
It should be under ${HOME}/.local/share/mkcert
mkcert has browser detection logic, so if one is detected (Chrome, Firefox) the install command will let you know. If the browser is not detected for some reason (ex. Firefox installed via snap), you will need to manually import the certificate in the browser.
Pick the latest release of the project from here, in this example v20230420
:
$ wget https://codeberg.org/pmarini/nc-env/archive/v20230420.tar.gz $ tar -xzf v20230420.tar.gz $ cd nc-env/
Go through the LXD initialization process:
The process below assumes you have a free local block device that we can use as a storage pool. If you donβt have one, you can use a ZFS-formatted loop device or nolxthe
dir
backend
Make sure the user is in group
lxd
$ lxd init Would you like to use LXD clustering? (yes/no) [default=no]: no Do you want to configure a new storage pool? (yes/no) [default=yes]: yes Name of the new storage pool [default=default]: lxdpool01 Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]: zfs Create a new ZFS pool? (yes/no) [default=yes]: yes Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: yes Path to the existing block device: /dev/vdb Would you like to connect to a MAAS server? (yes/no) [default=no]: no Would you like to create a new local network bridge? (yes/no) [default=yes]: 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]: none Would you like the LXD server to be available over the network? (yes/no) [default=no]: yes Address to bind LXD to (not including port) [default=all]: Port to bind LXD to [default=8443]: Trust password for new clients: <your password> Again: <your password> Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: yes Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Create a LXD profile for the containers created in nc-env:
$ lxc profile create nc-env-prf $ lxc profile device add nc-env-prf root disk path=/ pool=lxdpool01 size=5GB $ lxc profile device add nc-env-prf eth0 nic nictype=bridged name=eth0 parent=lxdbr0 $ lxc profile set nc-env-prf boot.autostart false $ lxc profile set nc-env-prf limits.memory 1GB $ lxc profile set nc-env-prf limits.cpu 1 $ lxc profile list +----------------+---------------------+---------+ | NAME | DESCRIPTION | USED BY | +----------------+---------------------+---------+ | default | Default LXD profile | 1 | +----------------+---------------------+---------+ | nc-env-profile | | 0 | +----------------+---------------------+---------+
Configure the internal LXD DNS server to automatically resolve hostnames of containers in nc-env:
$ lxc network set lxdbr0 dns.domain '<your domain>' $ lxc network set lxdbr0 dns.mode managed $ sudo vim /etc/systemd/system/lxd-dns-lxdbr0.service [Unit] Description=LXD per-link DNS configuration for lxdbr0 BindsTo=sys-subsystem-net-devices-lxdbr0.device After=sys-subsystem-net-devices-lxdbr0.device [Service] Type=oneshot ExecStart=/usr/bin/resolvectl dns lxdbr0 <IP address of interface> ExecStart=/usr/bin/resolvectl domain lxdbr0 '<your domain>' [Install] WantedBy=sys-subsystem-net-devices-lxdbr0.device
Now you can reload the systemd daemons and enable and start the service:
In Debian environments, you should enable at this point the
systemd-resolved
service (sudo systemctl enable systemd-resolved.service
), then reboot.
$ sudo systemctl daemon-reload $ sudo systemctl enable lxd-dns-lxdbr0.service $ sudo systemctl start lxd-dns-lxdbr0.service $ sudo resolvectl status lxdbr0 Link 3 (lxdbr0) Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6 Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported Current DNS Server: <IP address of interface> DNS Servers: <IP address of interface> DNS Domain: <your domain>
At this point you should be able to start using LXD to run your conatiners.
Let's first display the storage pools:
$ lxc storage list To start your first container, try: lxc launch ubuntu:20.04 Or for a virtual machine: lxc launch ubuntu:20.04 --vm +--------+--------+--------+-------------+---------+---------+ | NAME | DRIVER | SOURCE | DESCRIPTION | USED BY | STATE | +--------+--------+--------+-------------+---------+---------+ | pool01 | zfs | pool01 | | 1 | CREATED | +--------+--------+--------+-------------+---------+---------+
Then, let's display the networks:
$ lxc network list +--------+----------+---------+---------------+------+-------------+---------+---------+ | NAME | TYPE | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY | STATE | +--------+----------+---------+---------------+------+-------------+---------+---------+ | enp1s0 | physical | NO | | | | 0 | | +--------+----------+---------+---------------+------+-------------+---------+---------+ | lxdbr0 | bridge | YES | 10.20.73.1/24 | none | | 1 | CREATED | +--------+----------+---------+---------------+------+-------------+---------+---------+
Let's start a sample container:
$ lxc launch ubuntu:22.04 c1 Creating c1 Starting c1
Verify its status:
$ lxc ls +------+---------+---------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+---------+---------------------+------+-----------+-----------+ | c1 | RUNNING | 10.20.73.194 (eth0) | | CONTAINER | 0 | +------+---------+---------------------+------+-----------+-----------+
Log into the container and get information about the system:
$ lxc exec c1 bash root@c1:~# hostnamectl Static hostname: c1 Icon name: computer-container Chassis: container Machine ID: 615754225c3e48b2945deebfdeff4b4a Boot ID: b71e857de62a4c239cd3d9a274a433e6 Virtualization: lxc Operating System: Ubuntu 20.04.4 LTS Kernel: Linux 5.13.0-40-generic Architecture: x86-64
Leave the container and check the ZFS storage pool, using the zpool
utility:
$ sudo zpool list NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT pool01 19,5G 586M 18,9G - - 0% 2% 1.00x ONLINE -
Delete the sample container:
$ lxc delete -f c1
Now the environment is ready to be used and you can create the first container with nc-env.
For example, letβs pick the Nextcloud Standalone container, that is template01-nextcloud-standalone
:
$ pwd /home/ubuntu/nc-env $ mkdir my-local-env $ cd my-local-env $ cp -r ../templates/template01-nextcloud-standalone nc01 $ cd nc01
Follow the instructions that you find in the Readme.md
file.
At the end of the configuration the local folder layout should be similar to the following:
βββ artifacts β βββ nc-fulltext-live-indexer.service β βββ nc-redirect.conf β βββ nextcloud-26.0.0.tar.bz2 β βββ nextcloud-26.0.0.tar.bz2.md5 β βββ nextcloud.conf β βββ occ β βββ redis.conf β βββ rootCA-key.pem β βββ rootCA.pem βββ log βββ provision.sh βββ Readme.md βββ Vagrantfile
If this is your first container created with vagrant-lxd you'll need to add a certificate in LXD trust store allowing vagrant to interact with it. To do that, just issue the following command:
$ vagrant up The LXD provider could not authenticate to the daemon at https://127.0.0.1:8443. You may need configure LXD to allow requests from this machine. The easiest way to do this is to add your LXC client certificate to LXD's list of trusted certificates. This can typically be done with the following command: $ lxc config trust add /home/ubuntu/.vagrant.d/data/lxd/client.crt You can find more information about configuring LXD at: https://linuxcontainers.org/lxd/getting-started-cli/#initial-configuration
As suggested in the helper, issue the following command (change the name of the user according to your setup):
$ lxc config trust add /home/ubuntu/.vagrant.d/data/lxd/client.crt
Then, issue the following command:
$ vagrant up > log/provision.log
If it shows up, you can safely ignore the warning:
==> default: The host machine does not support LXD synced folders.
You may to want to follow the provisioning progress with the following command:
$ tail -f log/provision.log
Once the provisioning ended, you can see that the container has been created:
$ lxc ls +------+---------+---------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+---------+---------------------+------+-----------+-----------+ | nc01 | RUNNING | 10.20.73.116 (eth0) | | CONTAINER | 0 | +------+---------+---------------------+------+-----------+-----------+
Assign nc01
the profile nc-env-profile
:
This result could have been achieved also by setting the parameter
lxd.profiles
in Vagrantfile
.
$ lxc profile add nc01 nc-env-profile
You can now start using your brand-new Nextcloud instance by opening the instance url in your browser. The instance url and the admin user login credentials are displayed at the end of the log. For example if you set MACHINE_HOSTNAME=nc01.localenv.com
in provision.sh
, you will be able to access the instance with the following url: https://nc01.localenv.com
.
To build up more complex environments please check the list of templates available and pick the ones that fit your needs!