How to use `services.self-deploy`?

Hello,

I would like to use the services.self-deploy on a server.
I find the concept of this service really interesting.

However, it is not clear to me how I should configure it.

Current configuration:

services.self-deploy = {
    enable = true;

    startAt = "hourly";

    repository = "git@github.com:GaetanLepage/server.git";
    nixFile = "/nix/${config.system.name}.nix";
    nixAttribute = "system";
    sshKeyFile = "${config.users.users.gaetan.home}/.ssh/rsa_server";
};

Generated service (/etc/systemd/system/self-deploy.service):

[Unit]
Requires=network-online.target

[Service]
Environment="GIT_SSH_COMMAND=/nix/store/rqffx2f2b2vyzbssjh2fbbmnx3p15c12-openssh-9.0p1/bin/ssh -i '/home/gaetan/.ssh/rsa_server'"
Environment="LOCALE_ARCHIVE=/nix/store/r4jm7wfirgdr84zmsnq5qy7hvv14c7l7-glibc-locales-2.34-210/lib/locale/locale-archive"
Environment="PATH=/nix/store/9hlxa3j3jaqfk2v7f95jnnqlfk4w8mjz-git-2.36.0/bin:/nix/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/bin:/nix/store/7jr7pr4c6yb85xpzay5xafs5zlcadkhz-coreutils-9.0/bin:/nix/store/140f6s4nwiawrr3xyxarmcv2mk62m62y-findutils-4.9.0/bin:/nix/store/qd9jxc0q00cr7fp30y6jbbww20gj33lg-gnugrep-3.7/bin:/nix/store/lgvd2fh4cndlv8mnyy49jp1nplpml3xp-gnused-4.8/bin:/nix/store/h37rpx0wmycs2l9n4zp1m4m67bndi4wp-systemd-250.4/bin:/nix/store/9hlxa3j3jaqfk2v7f95jnnqlfk4w8mjz-git-2.36.0/sbin:/nix/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/sbin:/nix/store/7jr7pr4c6yb85xpzay5xafs5zlcadkhz-coreutils-9.0/sbin:/nix/store/140f6s4nwiawrr3xyxarmcv2mk62m62y-findutils-4.9.0/sbin:/nix/store/qd9jxc0q00cr7fp30y6jbbww20gj33lg-gnugrep-3.7/sbin:/nix/store/lgvd2fh4cndlv8mnyy49jp1nplpml3xp-gnused-4.8/sbin:/nix/store/h37rpx0wmycs2l9n4zp1m4m67bndi4wp-systemd-250.4/sbin"
Environment="TZDIR=/nix/store/n83qx7m848kg51lcjchwbkmlgdaxfckf-tzdata-2022a/share/zoneinfo"

X-RestartIfChanged=false


ExecStart=/nix/store/7lcmdzmkxdqbc078xi12pa3dj1q4gkh6-unit-script-self-deploy-start/bin/self-deploy-start 

The service gets created correctly, it gets started correctly, but the execution fails.

[gaetan@backup:~/server]$ systemctl status self-deploy                                                                                                      
× self-deploy.service
     Loaded: loaded (/etc/systemd/system/self-deploy.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Mon 2022-08-01 17:05:41 CEST; 44s ago
TriggeredBy: ● self-deploy.timer
    Process: 18233 ExecStart=/nix/store/7lcmdzmkxdqbc078xi12pa3dj1q4gkh6-unit-script-self-deploy-start/bin/self-deploy-start (code=exited, status=1/FAILURE)
   Main PID: 18233 (code=exited, status=1/FAILURE)
         IP: 4.9K in, 5.2K out
        CPU: 52ms

Aug 01 17:05:39 backup systemd[1]: Started self-deploy.service.
Aug 01 17:05:41 backup self-deploy-start[18234]: From github.com:GaetanLepage/server
Aug 01 17:05:41 backup self-deploy-start[18234]:  * branch            master     -> FETCH_HEAD
Aug 01 17:05:41 backup self-deploy-start[18240]: HEAD is now at bbd0087 test self-deploy
Aug 01 17:05:41 backup self-deploy-start[18241]: error: anonymous function at /var/lib/nixos-self-deploy/repo/nix/backup.nix:1:1 called without required argument 'config'
Aug 01 17:05:41 backup systemd[1]: self-deploy.service: Main process exited, code=exited, status=1/FAILURE
Aug 01 17:05:41 backup systemd[1]: self-deploy.service: Failed with result 'exit-code'.
Aug 01 17:05:41 backup systemd[1]: self-deploy.service: Consumed 52ms CPU time, received 4.8K IP traffic, sent 5.2K IP traffic.

Here is the generated script (/nix/store/7lcmdzmkxdqbc078xi12pa3dj1q4gkh6-unit-script-self-deploy-start/bin/self-deploy-start):

#!/nix/store/iffl6dlplhv22i2xy7n1w51a5r631kmi-bash-5.1-p16/bin/bash
set -e
if [ ! -e /var/lib/nixos-self-deploy/repo ]; then
  mkdir --parents /var/lib/nixos-self-deploy/repo
  git init /var/lib/nixos-self-deploy/repo
fi

git -C /var/lib/nixos-self-deploy/repo fetch 'git@github.com:GaetanLepage/server.git' 'master'

git -C /var/lib/nixos-self-deploy/repo checkout FETCH_HEAD

nix-build '--attr' 'system' '--out-link' '/var/lib/nixos-self-deploy/system' '/var/lib/nixos-self-deploy/repo/nix/backup.nix'

nix-env --profile /nix/var/nix/profiles/system --set /var/lib/nixos-self-deploy/system

/var/lib/nixos-self-deploy/system/bin/switch-to-configuration switch

rm /var/lib/nixos-self-deploy/system

git -C /var/lib/nixos-self-deploy/repo gc --prune=all

The following line is posing problem:
nix-build '--attr' 'system' '--out-link' '/var/lib/nixos-self-deploy/system' '/var/lib/nixos-self-deploy/repo/nix/backup.nix'

Is it a problem of configuration ?
Is the generated nix-build command correct ?

Thank you very much in advance for your help !

2 Likes

It looks like the issue is with your configuration to me – more specifically, it looks like the file you’re referencing is what would normally be in your configuration.nix file exactly, aka a function. I’ve been meaning to document the self-deploy service for some time, but it requires the configuration be a “system closure”, which is created by using the methodology Gabriella Gonzalez describes here: Haskell for all: NixOS in production

The article is a bit out of date in a handful of regards, but the actual methodology of creating a buildable system closure is not. The parts you need to look at are “building the closure” (specifically the syntax used to create the closure, self-deploy does the building) and “pinning nixpkgs” (likely something you’d like to do when using self-deploy), self-deploy handles all of the other parts.

Ok, thank you for this explanation !

Indeed, the file I was referencing was simply a renamed configuration.nix.
I wrote a closure as detailed in the guide, however, I initially wanted something yo “automatically update” my system. In other words, pull the repository containing my configuration and nixos-rebuild switch it.
Combined to the use of system.autoUpgrade, I was hoping to get an “autonomous system” that keeps itself up to date both regarding the configuration on my git and the nixpkgs 22.05 channel.

Would it be possible ? Is it the proper approach ?

That certainly could be done, yes. You would want to ignore the instructions for pinning nixpkgs and instead use the nixpkgs channel, then leave autoUpgrade in charge of managing your nixpkgs channel.

1 Like

In case it’s useful, Cachix Deploy Public Beta - Cachix Blog addresses a lot of the design flaws related to self deploy while providing a clean interface.

3 Likes