Is there a way to centralize services.octoprint's configuration?

I have a Raspberry Pi 4b I use to drive a 3D printer (Prusa Mk3S+). Previously I’ve used Raspberry OS (nee Raspbian), a Debian derivative on this rpi4 for this purpose.
I’m trying to migrate from Raspberry OS to NixOS (24.11), and my primary goal is a centralized configuration.nix that includes all of the machine’s configuration for ease of versioning/backup/restore.
I was excited to find services.octoprint already exists and it successfully brings up an OctoPrint instance that can talk to my printer (yay!), but I was disappointed to find I had to do quite a bit of manual configuration in OctoPrint’s UI (e.g. printer profiles), which is then persisted under /var/lib/octoprint.

My question: is there a way to configure OctoPrint entirely from configuration.nix?

Note: I see services.octoprint.extraConfig but that seems to only provide for adding to OctoPrint’s config.yaml file, not to e.g. printerProfiles/_default.profile

I have not used Octoprint, but I can give you advice from my general experience configuring things on NixOS. You certainly can have everything be in a single configuration.nix, but in this case it may not all be Nix-language code.

Sometimes you are just out of luck with certain configuration settings not being supported by NixOS options. I am assuming that printerProfiles/_default.profile is located somewhere in /etc. In that case you can use the environment.etc option to write the contents of those files. Or if it is somewhere else then you can use systemd.tmpfiles to specify files anywhere on your system.

Using tmpfiles, you have the choice of pasting your _default.profile into your nixos config as a string or having it copy the contents of another file into this new _default profile. For example, if I want to create a file named “/tmp/example_file.txt” with contents “example contents”, I could do either of the following:

Directly writing the contents as a string:
configuration.nix:

systemd.tmpfiles.rules = [
 "f /tmp/example_file.txt 0660 root root - example contents" 
];

Writing the contents in another file and copying that file:
example_file_to_be_copied.txt:

example contents

configuration.nix:

systemd.tmpfiles.rules = [
 "C /tmp/example_file.txt 0660 root root - ${./example_file_to_be_copied}" 
];

The choice is up to you. I generally prefer to split it up into multiple files (all located next to each other in the same directory) because if there is only 1 language per file, then my IDE gives more accurate syntax highlighting. But you can definitely do it all in a single configuration.nix if you like.

1 Like

Thanks for your reply, @zachliebl!
Unfortunately the example I gave of printerProfiles/_default.profile is just one of several (or many, depending on the complexity of one’s setup) configuration files OctoPrint uses. I was hoping for the service’s definition to write them all out, with whatever settings/modifications were provided in configuration.nix overriding defaults.
Still, having recipes for writing out individual files is quite useful, thanks!