Auto Start Python Script on Boot (Ubuntu 20.04, Systemd)

October 27, 2020

Create a Systemd Entry

sudo nano /etc/systemd/system/myapp.service
[Unit]
# After=network.service
Description=My App

[Service]
Type=simple
# WorkingDirectory=/code/python/myapp
ExecStart=/code/scripts/myapp.sh
# User=do-user

[Install]
WantedBy=multi-user.target
# WantedBy=default.target

NOTE: Use After=network.service if you require network.

Create Bash Script

nano /code/scripts/myapp.sh
#!/bin/bash

# cd /code/python/myapp
python3 /code/python/myapp/run.py >> /code/logs/myapp.log 2>&1
mkdir /code/logs

Create Python Script

nano /code/python/myapp/run.py
import signal
import time
import datetime

is_shutdown = False

def stop(sig, frame):
  print(f"SIGTERM at {datetime.datetime.now()}")
  global is_shutdown
  is_shutdown = True

def ignore(sig, frsma):
  print(f"SIGHUP at {datetime.datetime.now()}")

signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)

print(f"START at {datetime.datetime.now()}")

while not is_shutdown:
  print('.', end='', flush=True)
  time.sleep(1)

print(f"END at {datetime.datetime.now()}")

Test Systemd

Set file permission

sudo chmod 744 /code/scripts/myapp.sh
sudo chmod 664 /etc/systemd/system/myapp.service

Enable Service

sudo systemctl daemon-reload
sudo systemctl enable myapp.service

Test Service

sudo systemctl start myapp.service

Check Status

sudo systemctl start status.service

Check Log

tail -f /code/logs/myapp.log

Stop Service

sudo systemctl stop myapp.service

Restart server to test if the service started on reboot

sudo reboot

Anaconda

Systemd is run as root by default. If you are using Anaconda (or maybe pyenv), current user might not run the same python version/environment as root.

NOTE: I tried changing the user via Service.User, but it still uses the system default python interpreter

python -V
sudo python -V

You can find the python interpreter path using which python or python -c "import sys; print(sys.executable)"

which python
sudo which python

Edit the bash script to use the correct python interpreter

/opt/conda/bin/python3 /code/python/myapp/run.py >> /code/logs/myapp.log 2>&1
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.