Configuration
(Auto)start application as a service in Linux

(Auto)start application as a service in Linux

Two examples how to autostart services in Linux will be presented here. To run applications you have to use systemd suite. Systemd configuration files are stored at:

/etc/systemd/system/

Jupyter

Create a new file at:

vim /etc/systemd/system/jupyter.service

Copy-paste the following configuration there:

[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/home/$USER/.local/share/virtualenvs/$USER-$VENV_ID/bin/jupyter-notebook --config=/home/$USER/.jupyter/jupyter_notebook_config.py
User=$USER
Group=$USER
WorkingDirectory=/home/$USER
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Where:

  • $USER — is a username who owns the resources containing you instance/virtual environment
  • $VENV_ID — ID of your virtual environment
[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/home/ubuntu/.local/share/virtualenvs/ubuntu-6trdHBQq/bin/jupyter-notebook --config=/home/ubuntu/.jupyter/jupyter_notebook_config.py
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Start the service with:

sudo systemctl start jupyter.service
sudo systemctl enable jupyter.service

Custom .*rc file

When running as a service, you may wish to load environmental variables from .bashrc or .zshrc as well. Note that pipenv shell and jupyter have their own environments.

[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/bin/bash -c '. "$0" && exec "$@"' /home/$USER/.zshrc /home/$USER/.local/share/virtualenvs/$USER-$VENV_ID/bin/jupyter-notebook --config=/home/$USER/.jupyter/jupyter_notebook_config.py
User=$USER
Group=$USER
WorkingDirectory=/home/$USER
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

E.g.:

[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/bin/bash -c '. "$0" && exec "$@"' /home/ubuntu/.zshrc /home/ubuntu/.local/share/virtualenvs/ubuntu-6trdHBQq/bin/jupyter-notebook --config=/home/ubuntu/.jupyter/jupyter_notebook_config.py
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Running Jupyter outside virtual environment

Alternatively, you can run a Jupyter Notebook server outside a virtual environment, although it is not recommended. It will look like this:

[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/bin/bash -c '. "$0" && exec "$@"' /home/$USER/.zshrc /usr/local/bin/jupyter-notebook --config=/home/$USER/.jupyter/jupyter_notebook_config.py
User=$USER
Group=$USER
WorkingDirectory=/home/$USER
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

E.g.:

[Unit]
Description=Jupyter Workplace

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/bin/bash -c '. "$0" && exec "$@"' /home/ubuntu/.zshrc /usr/local/bin/jupyter-notebook --config=/home/ubuntu/.jupyter/jupyter_notebook_config.py
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Flask

I tried to run Python Flask server as a service in Linux with systemd.

It turned out that gunicorn is necessary for that (see this blog entry).

In order to be able to use gunicorn you need a virtual environment. Go to the place where your Flask project is located and run:

pipenv install Flask gunicorn

Then you should see gunicorn executable in the directory of your virtual environment, under location similar to:

/home/ubuntu/.local/share/virtualenvs/flask_request_history-evCMGJKR/bin/gunicorn

Check if you application works with the following command:

sudo /home/ubuntu/.local/share/virtualenvs/flask_request_history-evCMGJKR/bin/gunicorn -b 0.0.0.0:80 -w 4 flask_request_history.app:app

Note, flask_request_history.app means that you want to run application from a file app.py, located under flask_request_history directory.

Ultimately, you should use apache for proxy requests incoming to your server from port 80 (0.0.0.0:80, external world) to Flask instance using localhost (127.0.0.1:8000, or localhost:8000). However, this tutorial doesn’t cover configuring apache so it will assume that a sufficient layer of security is provided by the administrator of your server (e.g., by an apache running on a separate machine which is part of your server’s virtual environment).

Now, to configure systemd entry:

sudo vim /etc/systemd/system/flask-app.service

And copy-paste the following content:

[Unit]
Description=Flask Request History

[Service]
Type=simple
PIDFile=/run/flaskrequesthistory.pid
ExecStart=/home/ubuntu/.local/share/virtualenvs/flask_request_history-evCMGJKR/bin/gunicorn -b 0.0.0.0:80 -w 4 flask_request_history.app:app
User=root
Group=root
WorkingDirectory=/home/ubuntu/flask_request_history
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Note! This assumes that your Flask project is located at:

/home/ubuntu/flask_request_history

and that the filename of your application is “app.py”:

/home/ubuntu/flask_request_history/app.py

Now you can start and enable your service with:

sudo systemctl start flask-request-history.service
sudo systemctl enable flask-request-history.service

Cover picture from: https://dev.to/dstarner/the-myth-of-sisyphus-failure-the-meaning-of-imperfect-code-25e3

Leave a Reply