From 55875f4c25112b599e0ab8882cb3bb714c3b630a Mon Sep 17 00:00:00 2001 From: saji Date: Mon, 21 Apr 2025 08:42:38 -0500 Subject: [PATCH] finalize nix-unprivileged-deployments --- content/blog/nix-unprivileged-deployments.md | 102 +++++++++++-------- styles/config/vocabularies/Base/accept.txt | 1 + 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/content/blog/nix-unprivileged-deployments.md b/content/blog/nix-unprivileged-deployments.md index a613ecb..9de51f8 100644 --- a/content/blog/nix-unprivileged-deployments.md +++ b/content/blog/nix-unprivileged-deployments.md @@ -118,8 +118,10 @@ $ ls /nix/store | grep myblog mqhssdlmg9f03avpajwcqaah2apknl02-myblog ``` -Now I just need a symlink to this file, and a nginx vhost. I'll create a small NixOS -module that will set this up: + +Before we go any further, let's set up the nginx server, +as well as a well-known path for our website. I'll also +add a user here that we can use to deploy. ```nix @@ -157,6 +159,7 @@ in }; # make this user trusted (spooky) + # you'll see why we need this in a moment. nix.settings.trusted-users = [ user ]; @@ -200,47 +203,47 @@ The last step is creating that symlink. This is where the concept of "activation For NixOS, `deploy-rs` activation just calls `switch-to-configuration` to make the system change the profile. We can effectively do whatever we want here. + Reading the [custom activator](https://github.com/serokell/deploy-rs/blob/aa07eb05537d4cd025e2310397a6adcedfe72c76/flake.nix#L58C13-L96C17) source: ```nix -custom = - { - __functor = customSelf: base: activate: - final.buildEnv { - name = ("activatable-" + base.name); - paths = - [ - base - (final.writeTextFile { - name = base.name + "-activate-path"; - text = '' - #!${final.runtimeShell} - set -euo pipefail +custom = { + __functor = customSelf: base: activate: + final.buildEnv { + name = ("activatable-" + base.name); + paths = + [ + base + (final.writeTextFile { + name = base.name + "-activate-path"; + text = '' + #!${final.runtimeShell} + set -euo pipefail - if [[ "''${DRY_ACTIVATE:-}" == "1" ]] - then - ${customSelf.dryActivate or "echo ${final.writeScript "activate" activate}"} - elif [[ "''${BOOT:-}" == "1" ]] - then - ${customSelf.boot or "echo ${final.writeScript "activate" activate}"} - else - ${activate} - fi - ''; - executable = true; - destination = "/deploy-rs-activate"; - }) - (final.writeTextFile { - name = base.name + "-activate-rs"; - text = '' - #!${final.runtimeShell} - exec ${final.deploy-rs.deploy-rs}/bin/activate "$@" - ''; - executable = true; - destination = "/activate-rs"; - }) - ]; - }; - }; + if [[ "''${DRY_ACTIVATE:-}" == "1" ]] + then + ${customSelf.dryActivate or "echo ${final.writeScript "activate" activate}"} + elif [[ "''${BOOT:-}" == "1" ]] + then + ${customSelf.boot or "echo ${final.writeScript "activate" activate}"} + else + ${activate} + fi + ''; + executable = true; + destination = "/deploy-rs-activate"; + }) + (final.writeTextFile { + name = base.name + "-activate-rs"; + text = '' + #!${final.runtimeShell} + exec ${final.deploy-rs.deploy-rs}/bin/activate "$@" + ''; + executable = true; + destination = "/activate-rs"; + }) + ]; + }; +}; ``` @@ -302,9 +305,24 @@ lrwxrwxrwx 1 static-site static-site 62 Apr 17 19:59 mysite-2-link -> /nix/sto lrwxrwxrwx 1 static-site static-site 62 Apr 17 21:33 mysite-8-link -> /nix/store/f1qsglj5zm6v0vzlllci3jqsay476d5l-activatable-myblog ``` -We can get an idea of how this works: +The chain looks like this: 1. `/var/lib/static-site/public` points to the public folder in the `myblog` profile 2. The profile is itself a link to `mysite-8-link`. -3. `mysite-8-link` is also a link to a derivation in the nix store. +3. `mysite-8-link` is again a link, this time to a derivation in the nix store. +A profile is just a symlink to a derivation in the nix store. One layer of indirection +exists to make rollbacks easier. + + +# End + +I hope this was useful for you. I think non-root deployment is +under-explored for nix since NixOS makes it easy to reconfigure. + +As a follow on, you can probably host arbitrary services like this, +if you used [home-manager](https://nix-community.github.io/home-manager/) +to manage the user and the systemd services. Or you could hack together +something similar yourself. + +ok bai diff --git a/styles/config/vocabularies/Base/accept.txt b/styles/config/vocabularies/Base/accept.txt index 8c8bee2..2aae40d 100644 --- a/styles/config/vocabularies/Base/accept.txt +++ b/styles/config/vocabularies/Base/accept.txt @@ -24,3 +24,4 @@ keypair whitelabel +systemd