venv 🤝 systemd

TL;DR: I wanted to automatically restart a script that’s written in Python through systemd - but I “needed” support for virtual environments. It was embarrassingly easy.

I try to get rid of my habit to simply stuff any script that I need to run continuously (or in the background) into a tmux-session, calling it a day. Yes, it works. But I know better.

Since I exclusively run Debian on my computers - which isn’t intended as some weird, neckbeard-ish bragging, I mention it to explain why I didn’t bother looking for other alternatives - the obvious choice to me is turning the script into a service.

Which is all fine, writing the unitfile for systemd isn’t all that tricky. But at first thought, getting a unitfile to use the virtual environment I want it to use is. In my head, I thought I had to do something ugly like this:

/usr/bin/bash -c "source ./bin/activate; ./myscript.py"

Luckily, I was wrong there. I can simply use the “venv’d” Python-interpreter directly, which makes for a sane unitfile like this:

[Unit]
Description=$description

[Service]
User=$username
Restart=on-failure
RestartSec=2s
WorkingDirectory=/path/to/working/directory
ExecStart=/path/to/venv/bin/python3 script.py

[Install]
WantedBy=multi-user.target

One of the things I like about computers is that even after using it for quite a while, there are still (in hindsight) blatantly obvious things that you can discover and learn about.