Creating a Custom Linux Service

Creating a Custom Linux Service

It often useful to create custom services to perform tasks without user intervention. They are flexible allowing you to customize or extend functionality whenever you need, and allow you the granularity of control to ensure their security.

Custom services should be created in the following directory: /etc/systemd/system for systemd based distros.

Below is an example of the custom service I built to easily start and stop this blogging application.

As you can see it's split into three sections, the sections (Unit, Service, Install) are pre-defined and case-sensitive. While there are other sections available for use we only need the aforementioned three for our use-case. Each section has specific directives defined for use as well.

First up is the [Unit] section. This is used for defining metadata and the relationship of the unit to other units.

  • Description=: Used to describe the name and basic functionality of the unit. It is returned by various systemd tools, so providing something is beneficial.
  • Requires=: This directive lists any units upon which this unit depends. If the current unit is activated, the units listed here must successfully activate as well, else this unit will fail.
  • After=: The units listed in this directive will be started before starting this unit.

Next we have [Service] which provides service specific configurations

  • User=: Refers to the user the programs defined is started as.
  • Group=: Same as above except for group.
  • WorkingDirectory=: What path to begin any subsequent operations in.
  • ExecStart=: Specifies the full path of a command that will be executed to start a service. We have some optional parameters made available through fgunicorn (web server).
    • --error-logfile: Defines the path and file name where any error generated during use will be written to execution
    • --workers: Gunicorn is used for concurrency and relies on a pre-fork worker design model, meaning that there is a central master process that manages a set of worker processes. Here we've set 3 for use.
    • --bind: Here we bind to listen to a socket rather than an address to reduce TCP/IP related overhead.
    • main:app: This is the name of the application as defined in the web app code

Finally we have [Install] This section is optional but is used to define behavior and whether a unit if it is enabled or disabled.

  • WantedBy: I think of this as a reverse dependency. Allowing you to set this service to be started whenever the defined boot type is occurs in this case, multi-user.target.

This is a brief introduction into building services. There is a lot more function and flexibility they can provide than what I've shown here.

4:04:59 PM 14/04/2024
Tags: Linux SystemD