crash-course-to-lxd.md

  1---
  2title: "Crash Course to LXD"
  3subtitle: "Quick instructions for installing LXD and setting up your first application."
  4date: 2023-09-19T14:27:00-04:00
  5categories:
  6  - Technology
  7tags:
  8  - Sysadmin
  9  - Containers
 10  - VMs
 11  - Docker
 12  - LXD
 13draft: false
 14toc: true
 15rss_only: false
 16cover: ./cover.png
 17---
 18
 19If you're wondering _why_ I like system containers, see the previous post, _[LXD: Containers for
 20Human Beings.][lxd]_
 21
 22[lxd]: {{< ref "lxd-containers-for-human-beings" >}}
 23
 24## Installation
 25
 26{{< adm type="note" >}}
 27
 28**Note:** the instructions below say to install LXD using [Snap.][snap] I
 29personally dislike Snap, but LXD is a Canonical product and they're doing their
 30best to promote it as much as possible. [Incus] is a fork of LXD by the primary
 31creators and maintainers and one of the first things they did was [rip out Snap
 32support,][rsnap] so it will eventually be installable as a proper native
 33package.
 34
 35[snap]: https://en.wikipedia.org/wiki/Snap_(software)
 36[Incus]: https://github.com/lxc/incus
 37[rsnap]: https://github.com/lxc/incus/compare/9579f65cd0f215ecd847e8c1cea2ebe96c56be4a...3f64077a80e028bb92b491d42037124e9734d4c7
 38
 39{{< /adm >}}
 40
 411. Install snap following [Canonical's tutorial](https://earl.run/ZvUK)
 42   - LXD is natively packaged for Arch and Alpine, but configuration can be a
 43     massive headache.
 442. `sudo snap install lxd`
 453. `lxd init`
 46   - Defaults are fine for the most part; you may want to increase the size of
 47     the storage pool.
 484. `lxc launch images:debian/12 container-name`
 495. `lxc shell container-name`
 50
 51## Usage
 52
 53As an example of how to use LXD in a real situation, we'll set up [my URL
 54shortener.][earl] You'll need a VPS with LXD installed and a (sub)domain pointed
 55to the VPS.
 56
 57Run `lxc launch images:debian/12 earl` followed by `lxc shell earl` and `apt
 58install curl`. Also `apt install` a text editor, like `vim` or `nano` depending
 59on what you're comfortable with. Head to the **Installation** section of [earl's
 60SourceHut page][earl] and expand the **List of latest binaries**. Copy the link
 61to the binary appropriate for your platform, head back to your terminal, type
 62`curl -LO`, and paste the link you copied. This will download the binary to your
 63system. Run `mv <filename> earl` to rename it, `chmod +x earl` to make it
 64executable, then `./earl` to execute it. It will create a file called
 65`config.yaml` that you need to edit before proceeding. Change the `accessToken`
 66to something else and replace the `listen` value, `127.0.0.1`, with `0.0.0.0`.
 67This exposes the application to the host system so we can reverse proxy it.
 68
 69[earl]: https://earl.run/source
 70
 71The next step is daemonising it so it runs as soon as the system boots. Edit the
 72file located at `/etc/systemd/system/earl.service` and paste the following code
 73snippet into it.
 74
 75```ini
 76[Unit]
 77Description=personal link shortener
 78After=network.target
 79
 80[Service]
 81User=root
 82Group=root
 83WorkingDirectory=/root/
 84ExecStart=/root/earl -c config.yaml
 85
 86[Install]
 87WantedBy=multi-user.target
 88```
 89
 90Save, then run `systemctl daemon-reload` followed by `systemctl enable --now
 91earl`. You should be able to `curl localhost:8275` and see some HTML.
 92
 93Now we need a reverse proxy on the host. Exit the container with `exit` or
 94`Ctrl+D`, and if you have a preferred webserver, install it. If you don't have a
 95preferred webserver yet, I recommend [installing Caddy.][caddy] All that's left
 96is running `lxc list`, making note of the `earl` container's `IPv4` address, and
 97reverse proxying it. If you're using Caddy, edit `/etc/caddy/Caddyfile` and
 98replace everything that's there with the following.
 99
100[caddy]: https://caddyserver.com/docs/install
101
102```text
103<(sub)domain> {
104	encode zstd gzip
105	reverse_proxy <container IP address>:1313
106}
107```
108
109Run `systemctl restart caddy` and head to whatever domain or subdomain you
110entered. You should see the home page with just the text `earl` on it. If you go
111to `/login`, you'll be able to enter whatever access token you set earlier and
112log in.
113
114## Further tips
115
116One of the things you might want to do post-installation is mess around with
117profiles. There's a `default` profile in LXD that you can show with `lxc profile
118show default`.
119
120```text
121$ lxc profile show default
122config: {}
123description: Default LXD profile
124devices:
125  eth0:
126    name: eth0
127    network: lxdbr0
128    type: nic
129  root:
130    path: /
131    pool: default
132    type: disk
133name: default
134used_by: []
135```
136
137Not all config options are listed here though; you'll need to read [the
138documentation] for a full enumeration.
139
140[the documentation]: https://documentation.ubuntu.com/lxd/en/latest/config-options/
141
142I've seen some people say that executing a fork bomb from inside a container is
143equivalent to executing it on the host. The fork bomb will blow up the whole
144system and render every application and container you're running inoperable.
145That's partially true because LXD _by default_ doesn't put a limit on how many
146processes a particular container can spawn. You can limit that number yourself
147by running
148
149```text
150lxc profile set default limits.processes <num-processes>
151```
152
153Any container you create under the `default` profile will have a total process
154limit of `<num-processes>`. I can't tell you what a good process limit is
155though; you'll need to do some testing and experimentation on your own.
156
157As stated in [the containers section][pp] of the previous post, this doesn't
158_save_ you from fork bombs. It just helps prevent a fork bomb from affecting the
159host OS or other containers.
160
161[pp]: {{< ref "lxd-containers-for-human-beings#containers" >}}