Deploying This Blog

Andrew Fontaine <>

Alright, let’s get technical.

Deployments: The Tools

As [previously mentioned], I use nix for as much as possible, which means using NixOS for as many machines as I can. For a while, I was managing this VPS via NixOps, which has the benefit of being able to spin up new servers on many tools. It, however, has some downsides:

[previously mentioned]:

Instead, I use a tool called deploy-rs, (a W.I.P. name according to their matrix channel), which was built to use flakes from the start and has no hidden state to manage, which means deploying from multiple machines (and maybe even CD eventually) is much easier.

As the configuration for this server is in a git repo, I need to manage secrets somehow. To accomplish this, I utilize sops-nix, a tool that integrates sops, a GPG-based secrets management system made by mozilla, and git-crypt, a GPG-based way of encrypting git repo contents, for secrets that don’t work with sops-nix, which is few and far between.

Deployments: The Configuration

The repository is already mentioned, the configuration for this server is listed as the federator, and is pretty simple. It runs this site, a pleroma instance, a dendrite server, and znc. I plan on using IRC from matrix soon, but have not gotten around to it yet. For the sake of speed, both pleroma and dendrite run in docker containers. They are pre-built, and require minimal set up. Also when I initially set this up, there were no NixOS modules for either. That may change in the future.

This site does have a NixOS module; however, it is not in nix/nixpkgs. It is instead defined with its source code in the flake file, which means I can update it as I develop things. A NixOS module is a function that takes some inputs and produces an attrset (or map for other language fans) that has 2 keys: options and config. options are those that are set by users to configure the service, like what port to listen to (services.home-web.port) or details on how to connect to the database (services.home-web.databaseUrlFile). config, generally, configures other NixOS modules based on the options set. Here, I make sure the default user and group are created if they are being used, as well as configure a SystemD service that knows how to start the application, as well as one that understands how to run database migrations.

The flake also describes the deployment in a way deploy-rs understands.

      deploy.nodes = {
        federator = {
          hostname = "";
          profiles.system = {
            user = "root";
            path = deploy.lib.x86_64-linux.activate.nixos

deploy.nodes is a set of all the different machines I deploy to. Here, there is only one: federator. Its configuration consists of its hostname (used to ssh to it), and a set of nix profiles to deploy. The system one is somewhat special in that it is the one used by NixOS for system configuration, which is why it uses the special helper function from deploy-rs: activate.nixos, along with the NixOS configuration to deploy to the machine.

On Secrets

There are a couple configuration items that expect files instead of values. This is because

  1. everything used by nix is placed in the globally-readable nix store, and
  2. these values are secret and should not be globally-readable.

Instead, we set them to the value created by sops-nix, which puts secrets under /run/secrets and sets permissions to however you configure it.

There’s also this SystemD Credentials thing that looks interesting, but I do not know how it works, and it won’t work on NixOS until SystemD is bumped to 248.

Deployments: The deploying

All of this set up, and deploying just comes down to one command: deploy.


That’s it! Things missing:

Want to discuss this post?

Reach out via email to ~afontaine/, and be sure to follow the mailing list etiquette.

Other posts