this post was submitted on 15 Jan 2025
4 points (83.3% liked)

NixOS

1063 readers
6 users here now

NixOS is a Linux distribution built on top of the Nix package manager. Its declarative configuration allows reliable system upgrades via several official channels of stability and size.

This community discusses NixOS, Nix, and everything related.

founded 2 years ago
MODERATORS
 

Hi everyone I'm currently in the process to move one of my RPI4s from RaspberryOS to NixOS and I'm struggling to setup one of the services.

On the RPI I have a python script that is creating offsite backups via a Wireguard tunnel:

  • Open the wg tunnel
  • mount and encrypt the external disk on the offsite RPI
  • mount the source from my nas
  • start the restic-rest server container offsite
  • trigger the restic command to backup to the restic repo

allthough it's a bit overkill it works quite well for a few years now. Since most of the tasks are actually outsourced to systemd units those where quite easy to setup in nixOS. What I'm struggling is, how can I create a virtual python env to run the python script. All the guides I found for managing python dependencies are usually for development and use nix shell

My current workaround is, that I copy the script and requirements.txt from my script repo and create the venv manually. This does work, but I feel there is a better way, maybe the whole setup is already on the wrong pat as I tried to solve each hurdle separately?

Here's my current implementation of the remotebackup module (the wireguard and mount units are in different modules):

{inputs, config, pkgs, lib, ... }:

let configpath = builtins.toString inputs.infra-configs;
in
{
systemd.tmpfiles.settings = {
  "remotebackup" = {
    "/var/lib/remotebackup" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
      };
    };
    "/var/lib/remotebackup/assets" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
        };
      };

    };
  };

sops.secrets = {
  "restic/remotebackup/rest" = {};
  "restic/remotebackup/restic" = {};
};

sops.templates."remotebackup" = {
  content = ''
  {
    "rest" : "${config.sops.placeholder."restic/remotebackup/rest"}",
    "restic": "${config.sops.placeholder."restic/remotebackup/restic"}",
  }
  '';
  path = "/var/lib/remotebackup/assets/restic.cred";
  };


system.activationScripts.addPythonScript = lib.stringAfter ["var"] ''
    cp ${configpath}/scripts/remotebackup/script/restic_remotebackup.py /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/requirements.txt /var/lib/remotebackup/requirements.txt
    chmod 733 /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/assets/backup_paths.txt /var/lib/remotebackup/assets/backup_paths.txt
    '';

}

Also, on the RPI I'm triggering the script with cron, according to the wiki cron should be replaced by systemd.timers. Would you also suggest moving to systemd.timers

P.S.: If at all possible, I'd like to keep the script within my script repo...

top 1 comments
sorted by: hot top controversial new old
[–] jlh@lemmy.jlh.name 1 points 1 month ago

I believe the "nix"y way to do this would be to have a flake that installs the python dependencies, creates a reference to the script file, and then sets up the systemd service to run it.