(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/
Table of Contents
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