Skip to content

Instantly share code, notes, and snippets.

@bockor
Last active March 3, 2021 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bockor/9a15788b9b1a27da06fc8463a71ad8b6 to your computer and use it in GitHub Desktop.
Save bockor/9a15788b9b1a27da06fc8463a71ad8b6 to your computer and use it in GitHub Desktop.
uwsgi-as-a-systemd-service with python3 and bottle framework
*****************************************************
*** APPROACH 1: install uwsgi as a system package ***
*****************************************************
install packages
----------------
apt install uwsgi uwsgi-plugin-python3
Configure uwsgi daemon
----------------------
cat /etc/uwsgi/apps-available/site_inventory_http.ini
sudo ln -s /etc/uwsgi/apps-available/site_inventory_http.ini /etc/uwsgi/apps-enabled/
[uwsgi]
#strict = true ; need more info here
# Create a virtual environment for our application
# python3 -m venv bottle-venv
# virtualenv = bottle-venv
plugins = python3
# Respawns processes when they die and handles much of the built-in
# prefork+threading multi-worker management, generally always advised
master = true
enable-threads = true
# processes = n - Adds concurrency to the app by adding n additional processes
# threads = n - Adds additional cuncurrency by adding n additional threads
# As a starting point, one could set processes to the number of CPU cores on
# the machine and threads at 2 per CPU core
processes = 4
threads = 2
# Delete sockets during shutdown
vacuum = true
single-interpreter = true
# Shutdown when receiving SIGTERM (default is respawn)
die-on-term = true
need-app = true
# If you need to bind to privileged ports (like 443 for HTTPS), use shared sockets.
# They are created before dropping privileges and can be referenced with the =N syntax,
# where N is the socket number (starting from 0):
shared-socket = :80
http-socket = =0
# Run uwsgi as root but not recommended
#http-socket = 0.0.0.0:80
# Run uwsgi protocol with nginx frontend
#socket = /run/uwsgi/app/site_inventory/socket
chdir = /srv/site_inventory
module = site_inventory:app
# OR:
#wsgi-file = app.py
# Always avoid running your uWSGI instances as root
# Requires sudo chown -R www-data:www-data /var/log/uwsgi/app for uwsgi logging
uid = www-data
gid = www-data
# logto2 only opens the log file after privileges have been dropped to the specified uid/gid.
logto2 = /var/log/uwsgi/app/site_inventory_http.log
logfile-chown = uid:gid
logfile-chmod = 640
# uWSGI default logging
#log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) %(uri) => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core))
# Apache-style combined request logging
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"
Application: /srv/site_inventory/site_inventory.py EXCERPT
----------------------------------------------------------
...
# this is the hook for uWSGI to run the Bottle based application
app = bottle.default_app()
systemd commands
----------------
systemctl list-units --type=service --state=active
systemctl status uwsgi
systemctl start uwsgi
systemctl stop uwsgi
journalctl -fu uwsgi # tail log
Test (and get RESPONSE Header)
------------------------------
wget -S -q -O - http://127.0.0.1
**************************************************************************
*** APPROACH 2: install uwsgi as a pip package in a virtual environment***
**************************************************************************
which python3
cd /home/bruno/usgi_project
python3 -m venv uwsgi_venv
source uwsgi_project/uwsgi_venv/bin/activate
which python3
python3 -m pip download uWSGI
python3 -m pip download bottle
python3 -m pip install uWSGI-2.0.19.1.tar.gz
python3 -m pip install bottle-0.12.19-py3-none-any.whl
python3 -m pip list
uwsgi
deactivate
sudo usermod bruno -a -G www-data
/etc/systemd/system/bottle.ini
RHES7 --> https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd
-->10.6.2. Creating Custom Unit Files
-------------------------------------------------------------------------------
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=bruno
Group=www-data
WorkingDirectory=/home/bruno/uwsgi_project
Environment="PATH=/home/bruno/uwsgi_project/uwgi_venv/bin"
ExecStart=/home/bruno/uwsgi_project/uwsgi_venv/bin/uwsgi --ini bottle.ini
[Install]
WantedBy=multi-user.target
/home/bruno/uwsgi_project/bottle.ini
-------------------------------------------------------------------------------
[uwsgi]
# Specify virtual environment for our application
virtualenv = uwsgi_venv
# Respawns processes when they die and handles much of the built-in
# prefork+threading multi-worker management, generally always advised
master = true
enable-threads = true
# processes = n - Adds concurrency to the app by adding n additional processes
# threads = n - Adds additional cuncurrency by adding n additional threads
# As a starting point, one could set processes to the number of CPU cores on
# the machine and threads at 2 per CPU core
processes = 4
threads = 2
# Delete sockets during shutdown
vacuum = true
single-interpreter = true
# Shutdown when receiving SIGTERM (default is respawn)
die-on-term = true
need-app = true
#socket = /run/uwsgi/app/bottle/socket
http-socket = 127.0.0.1:8000
chdir = /home/bruno/uwsgi_project
module = app:app
#OR:
#wsgi-file = app.py
#master process controls the worker tasks, restarting them when they stop, among other things.
#Always avoid running your uWSGI instances as root
#Requires sudo chown -R www-data:www-data /var/log/uwsgi/app for uwsgi logging
#uid = bruno
#gid = bruno
logto = /home/bruno/uwsgi_project/bottle.log
/home/bruno/uwsgi_project/app.py
-------------------------------------------------------------------------------
import bottle
from bottle import route, run, Response
# a basic URL route to test whether Bottle is responding properly
@route('/')
def index():
return Response("Open the bottle and enjoy!\n")
# these two lines are only used for python myapp.py
if __name__ == '__main__':
run(host='0.0.0.0', port=8000, debug=True, reloader=True)
# this is the hook for uwsgi to run Bottle
app = application = bottle.default_app()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment