Use curl -X POST to backup configuration on switch?


We have 20-ish Raspberry Pis deployed, serving as Telegraf agents, configured via Nix and our own overlay to provide additional files and small packages to help bootstrap the configuration.

The configuration itself works well - but, we currently manually copy the file, each time. It would be awesome if we could automate the process. Right now, I am looking into system.activationScripts as a possibility, but I doubt that this is what it is supposed to be used for. So instead, I would like to know what I can do.

The idea is simple: We have a HTTPS server with an endpoint we can POST to. Now, we would like to automate this process:

  1. Set a token in a newly created option.
  2. Generate a shell script that launches after a successful switch
  3. Run that script with cURL in it’s $PATH (or just supply the full .outPath via something like $(pkgs.curl.outPath)) to upload the file to our server.

The server knows who we are by our token and moves the file into a date-time tagged archive.

How would you implement that?

The reason I am not using NixOps btw, is because all the Pis are behind different VPNs - and I have not found a way to associate each Pi with it’s own OVPN config and creds. So… we manually establish a tunnel, then SSH into the Pi, and do maintenance.

Kind regards and have a nice day!

Something like (not tested):

curl -X POST -H 'Token: secretToken' -H 'Content-Type: text/plain' -d @rpi.nix

Although I do not understand what config changes when you switch. Maybe I missed the point entirely.

Because we don’t use NixOps (too many different VPN configs associated with each individual Pi), we SSH into each device individually to update the configuration.nix and issue a nixos-rebuild switch respectively. However, we don’t have an automated mechanism to back up those configs at all - so my idea was to use some post-switch hook to send this config, to which a switch was in fact successful, to a remote storage with a basic but effective HTTP API - much like you demonstrated.

What I realized though is that there aren’t that many default packages loaded into the $PATH of those scripts; just coreutils, some net utillities and other basics. cURL is not included.

So I wondered if system.activationScripts is actually the way to go, considering how “early” it runs in a new generation - even the docs just say that it is ment to set up critical files…and just backing up the configuration, albeit being somewhat critical, may not apply.

Would it be possible to call cURL regardless with something like

system.activationScripts = {
  backup_config = ``
    $(pkgs.curl)/bin/curl ...

I am still relatively new to Nix and more or less speedrunning this due the demand in the company for more expertise. So chances are I overlooked something…


If you ssh into the devices to edit and switch anyway, I would keep /etc/nixos/in git. That gives you change history and backup to a remote host. Actually, that is how I manage NixOS and home-manager configurations on my servers and laptops.


Remote host (user is ‘git’ but can be anything):

users = {
    users = {
        git = {
            hashedPassword              = "";
            isNormalUser                =  true;
            openssh.authorizedKeys.keys = [ "ssh-ed25519 [..]" ];
            shell                       = "${pkgs.git}/bin/git-shell";

git init --bare -b main nixosconfigs
sudo mv nixosconfigs ~git/
sudo chown -R git ~git/nixosconfigs

Each device:

cd /etc/nixos/
git init .
git switch -c $(hostname)
git remote add origin git@<remotehost>:nixosconfigs
git pull
git add .; git commit -am 'initial commit'
git push -u origin $(hostname)

Oh that’s neat!

I think I can work off of that - we mainly use Github for our repos; but using prepared SSH keys should help.

Thanks for the pointer, this’ll help!

1 Like