Skip to content

Latest commit

 

History

History
83 lines (61 loc) · 2.88 KB

systemd.md

File metadata and controls

83 lines (61 loc) · 2.88 KB

Systemd

Pros

  • highly customizable
  • ability to bind to ports smaller than 1024 with the AmbientCapabilities=CAP_NET_BIND_SERVICE setting
  • boring technology

Cons

Cheatsheet

# start your application on boot
sudo systemctl enable ${appName}
# start your application
sudo systemctl start ${appName}
# restart application
sudo systemctl restart ${appName}
# view application logs
journalctl -u ${appName}

A simple Systemd service file for a Django application

Create a ${appName}.service file inside /etc/systemd/system/ that uses the ".env" and "run" file to launch the application:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
EnvironmentFile=/srv/${appName}/.env
WorkingDirectory=/srv/${appName}/
ExecStart=/srv/${appName}/run
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=${appUser}
Group=${appGroup}

[Install]
WantedBy=multi-user.target
  • The [Unit] section is used to specify metadata and dependencies. It has a description and an instruction to start after the network is up.
  • The [Service] section specifies your service configuration.
    • /srv is the recommended location, according to the Filesystem Hierarchy Standard
    • The run file is a bash script that executes gunicorn
    • AmbientCapabilities allows you to use ports below 1024
  • The [Install] section tells Systemd at which moment during the boot process this service should be started.

I like the idea of creating a single executable file to keep all instructions for starting the application in one place. Here is an example:

#! /bin/bash

set -a
source .env
set +a

export PYTHONPATH="/patho/to/repo/src:$PYTHONPATH"
export VIRTUAL_ENV="/path/to/virtualenv"

exec $VIRTUAL_ENV/bin/gunicorn project.wsgi
  • set -a, source .env, set +a allows to read the environment variables from a .env file (see StackOverflow)
  • By specifying the environment variable PYTHONPATH to point to the application's directory, you can specify the path to your wsgi.py as a python module path.
  • The $VIRTUAL_ENV environment variable points to the folder where your python dependencies are installed
  • exec is required, so the program does not daemonize itself. This implies that exec will replace the current shell with the command, so any instructions after that line will never be executed. Read this post for more information.

The run file needs to be marked as executable with:

chmod +x run

References