Tools to build a minimal webserver, as a self-contained archive that contains Nginx and Lego, with configuration to run it under systemd on Flatcar Container Linux (formerly CoreOS). A secure and simple way to host a static site.
Features:
- A recent Nginx, with Brotli support.
- Lego to refresh your Letsencrypt certificates.
- Bit by bit reproducible.
- Packaged as Erofs file system, runs using systemd's isolation features.
Building of the image is automated using Nix, a purely functional package manager:
nix build --out-link result
systemd-nspawn --image result/miniserver.img --ephemeral -- /usr/bin/nginx -V
The build involves the following:
- Take the package definitions for
nginxandlegofrom a pinned version of Nixpkgs. - Override
nginxpackage to disable unused features (to reduce the number of dependencies, and thereby attack surface and image size). Add thengx_brotlimodule forbrotli_staticsupport. - Build a self-contained Erofs image.
This repository includes a simple deployment tool, miniserver.py for updating
an existing installation. It will:
- Create a
/var/lib/miniserveron a target machine to hold deployed images. - Copy the current image to the server over
sshfsinto a directory named after the current version's Nix hash. - Put systemd units
nginx.serviceandlego.servicenext to the image. - Symlink
/var/lib/miniserver/currentto the latest version. - Daemon-reload
systemdand restartnginx.service.
Before the first deployment, perform the following initial setup. It is recommended to encode these steps in your Ignition config.
- Create a
wwwsystem group. - Create
nginxandlegosystem users with their own group, and also part of thewwwgroup. - Create
/var/log/nginxandchownit tonginx:nginx. This directory will be mounted read-write inside the unit's chroot. - Create
/var/www, chown it to$USER:www, and put your static site in there. This directory will be mounted read-only inside the unit's chroot. - Create
/etc/nginx/sites-enabled/and put at least one Nginx configuration file in there./etc/nginxwill be mounted read-only inside the unit's chroot. Files insites-enabledwill be loaded by the master config. - Create
/var/lib/lego/certificatesand chown it and its parent tolego:www. Set the file mode on/var/lib/lego/certificatesto 0750, to enable thewwwgroup to enter the directory. - Put your Lego flags environment file at
/etc/lego.conf.
Then to install or update:
./miniserver.py install <hostname>
You need to have built the image before it can be deployed. The install
command will symlink /etc/systemd/system/{nginx,lego}.service to the
ones in the installation directory, and enable and start the nginx unit. The
installation command is idempotent, it is safe to run it multiple times. (Each
time will create an entry in the deploy log, however.)
After the initial installation, you can update with:
./miniserver.py deploy <hostname>
This will restart nginx.service after uploading a new version.
The code in this repository is licensed under the GNU General Public License, version 3.