How to Configure systemd Socket Activation for a Webcam

24.05.25    tools and tricks

In the great tradition of the Trojan Room coffee pot I like to watch machines doing their work in another room using a webcam. In particular, I watch my 3d printer using my connected OctoPrint setup. It gets the webcam stream from a mjpeg-streamer service. Most of the time nobody is watching, but the service is still running and powering the webcam unnecessarily.

Here I show how this problem can be solved using systemd socket activation. This is a feature, where systemd, the init system and daemon running on most contemporary Linux distributions, opens a socket itself and only starts a connecting system service when remote connection is established.

The service program needs to specifically designed to be able to accept this connection from systemd. But mjpeg-streamer is not. This is why we need an additional helper program called systemd-socket-proxyd. As the name suggests, this helper proxies the data on the systemd provided socket to a different socket.

In total, we need these three unit files, which can be put in the user systemd directory ~/.config/systemd/user/:

mjpeg-streamer.service1

[Unit]
StopWhenUnneeded=true

[Service]
Type=exec
ExecStart=/home/pi/start_mjpg_streamer.sh
ExecStartPost=sleep 1

mjpeg-streamer-proxy.service

[Unit]
Requires=mjpeg-streamer.service
After=mjpeg-streamer.service
Requires=mjpeg-streamer-proxy.socket
After=mjpeg-streamer-proxy.socket

[Service]
Type=exec
ExecStart=/usr/lib/systemd/systemd-socket-proxyd --exit-idle-time=300 127.0.0.1:8085

mjpeg-streamer-proxy.socket

[Socket]
ListenStream=8080

[Install]
WantedBy=sockets.target

After the unit files are created and loaded using systemctl --user daemon-reload, we only need to explicitly activate the socket with systemctl --user enable --now mjpeg-streamer-proxy.socket. Now when somebody connects, the two service units will start and stream the webcam content. If nobody listens for five consecutive minutes (see --exit-idle-time=300 above), the service units shut themselves down and power down the webcam.


  1. The sleep helps to avoid race conditions. This way the dependent mjpeg-streamer-proxy.service waits for the mjpeg-streamer.service to fully start and listen on its own socket.