Creating a Linux service with systemd¶
- You can find the source code for this video in my GitHub Repo.
Intro¶
Once in a while, you need to create a script and run it in the background. There are a few approaches that you can take.
Probably the simplest one is to just add a &
to the end of the command.
Also, if you want to close the terminal, append nohup
. If your script exists for some reason, you would need to restart it manually.
The better approach is to use the systemd system and service manager for Linux. In this tutorial, I'll show you how to create a simple systemd service that can run your script in the background and restart it in case of failure.
Create Python HTTP Server¶
First of all, let's create a simple Python HTTP server.
We're going to run in on localhost:8080
.
It will accept only HTTP GET requests and return Hello
string back to the client.
We can also allow the user to exit the program by hitting Control-C
or Delete
key on a keyboard.
Let's try to run in the foreground first and make sure that it works.
Then open a new tab and try to access the server with the curl
command.
If you get a Hello
message from the server, that means it works.
Now we want this HTTP server to run all the time, be restarted in case of a failure, and even survive Linux restarts.
That’s where systemd comes into play.
Create Systemd Linux Service¶
Let's go ahead and create a systemd service file.
It's the bare minimum configuration to get you started. Make sure to specify your Linux User
and a ExecStart
command to start the server. You can also provide Environment
variables to your script.
The important parameter is a Restart
. You can either set it to always
or restart your script only on-failure
. By default, when you configure Restart=always
as we did,
the systemd gives up restarting your service if it fails to start more than 5 times within a 10 seconds interval.
The RestartSec
directive also has an impact on the outcome: if you set it to restart after 3 seconds, then you can never reach 5 failed retries within 10 seconds.
The simple fix that always works is to setStartLimitIntervalSec=0
. This way, the systemd will attempt to restart your service forever.
It's a good idea to set RestartSec
to at least 1 second, though, to avoid putting too much stress on your server when things start going wrong.
my-server.service | |
---|---|
Now let's test the system service. Go ahead and start the server.
To automatically start your service when Linux boots up, enable the service.
Then check the status.
In case it fails, and you need to find a reason, or you just want to follow the logs, you can use a journactl
command.
Use curl
to test.
The last thing that I want to discuss in this video is that you can manage dependencies for your service.
For example, if your server needs a database, you may use After=postgresql.service
directive to instruct systemd to start your python server only after the Postgres starts.
This will only work when the Linux boots up and both services are enabled.
If you want, you can add another Requires=postgresql.service
directive. Even if the Progress is down and you try to start your Python server, the systemd first starts the Postgres and then your program.
Systemd has been the default system and service manager for Linux in RHEL/CentOS, Fedora, Ubuntu, Debian, and others for several years now, and it should become your go-to tool to run services and your scripts in the background.