Package and deploy a (Rust) web app that needs a database with Nix(OS).
- The NixOS Server is setup to infect and run on a cheap Hetzner Virtualmachine
- You have to create such a server with e.g. Ubuntu first to get a static IP address for it.
- Run
nix run github:numtide/nixos-anywhere -- --flake .#hetzner-cloud root@<vm-ip>to infect and replace the VM operating system completely with NixOS (careful: deletes everything on server!).- It formats the VM disks automatically using the Nix library disko
- The
nixosConfigurationfor the server is inflake.nixand calledhetzner-cloud.
- Any subsequent redeploy must use
nixos-rebuild switch --flake .#hetzner-cloud --target-host root@<vm-ip>! Seeflake.nixandnixos-modulesfor configs.
- NixOS runs all apps (web app, database, migration app, reverse-proxy) as declarative systemd services, easy and concise to setup.
- The configured database is Postgresql.
- NixOS makes really easy to setup DBs without overhead and unrealibility of Docker containers.
- Migrations are managed by dbmate.
- Systemd allows us to run migrations on every web app upgrade.
- The configured reverse-proxy that secures the web app behind a smaller attack surface and enables automatic, browser-trusted web encryption is Caddy.
- Secrets are managed by agenix.
nixos-rebuildcan only copy data from the nix-store, which is open for everyone to see.- So data to pass to the server must be encrypted on the way.
- You encrypt your secret into a secure
secret.agefile, which is put into the store. Agenix uses age for encryption)- NixOS on the server creates a public/private key combination.
- On the server you get its public key (that works with agenix) with
[root@nixos:~]# cat /etc/ssh/ssh_host_ed25519_key.pub - On you local computer you encrypt with the servers public key.
- The agenix on the server decrypts the
secret.agefile with the servers private key. - The key is then readable on the server at
/run/agenix/secret.
- Packaging the Rust app is done with nix-community/dream2nix framework to create a Nix package that is exposed as a modular Nix flake so that servers can download and run this app wherever.
sudo nixos-container create db-dev --flake .#db-dev
sudo nixos-container start db-dev --flake .#db-dev
curl --connect-to localhost:80:all:80 --connect-to localhost:443:all:443 http://localhost -k -L
sudo nixos-container update db-dev --flake .#db-dev
sudo nixos-container root-login db-dev --flake .#db-dev