Greetings!
I am building my own website, and would like to make deploying it painless, whether it is for development or production, whether it is for NixOS or non-NixOS.
Backstory which shows how to use portable services.
I found out about pkgs.portableService, which exports a systemd
portable service.
I wrote a minimal example of a Flake which does just that:
{
description = "Minimal example of a Nix flake exporting a `systemd` unit";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs =
inputs@{ self, ... }:
let
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
in
{
packages.x86_64-linux.default = self.packages.x86_64-linux.portableService;
packages.x86_64-linux.portableService =
let
example-website-service = pkgs.writeText "example-website.service" ''
[Unit]
Description=Example service for my website
[Service]
ExecStart=${pkgs.lib.getExe pkgs.caddy} file-server
'';
in
pkgs.portableService {
pname = "example-website";
version = "0.1";
units = [ example-website-service ];
};
};
}
Running this service requires someone to use sudo portablectl attach --profile=trusted result/example-website_0.1.raw
, before being able to sudo systemctl start example-website
like a real service. If I don’t use --profile=trusted
, the user running Caddy doesn’t have the permissions to bind to ports 80 and 443.
My actual website tries to make use of the official caddyfile.service, the only modification being that I’m trying to use DynamicUser=yes
instead of manually giving the service a particular user and group.
The problem?
Well, for once, I think that using --profile=trusted
like I did in my backstory is wrong. I think the systemd
defaults should be fine, and that giving permissions to bind to lower ports and create sockets, in AmbiantCapabilities
, should make it so that Caddy doesn’t show an error when it tries to serve websites on ports 80 and 443.
But also, I’m thinking that this manual way of managing a “personal website service” is bad in production. Is there any way to attach a portable service to some NixOS config? I haven’t seen any option for that.
And, lastly, I think that Caddy’s official systemd
unit file is not good enough for NixOS – it gives warnings related to read-only filesystems, lack of a $HOME
directory, things like that.
So…
Currently, my website’s flake exports a filesystem with a /etc/caddy/Caddyfile
for Caddy’s configuration, a /var/www/
directory with the website’s contents, and expects the end user (myself, or anyone wanting to run my website locally) to run Caddy on their own.
Is there a better way to distribute a website, including the webserver itself?
In a way that makes it easy to run without installing anything (with nix run
), but also installable as a service if needed? How to do it in such a way that it’s possible to be deployed on a non-NixOS server?
I think my “portable service” solution was a nice idea, but Caddy doesn’t seem to like it very much.
Thank you kindly!