-
Notifications
You must be signed in to change notification settings - Fork 0
Deploying Python API to Production
The development server that runs when python3 app.py is called is not sufficient for a production environment. A more scalable and optimized server is needed. All Python APIs need a Web Server Gateway Interface (WSGI) to run. Gunicorn was chosen as the WSGI to run the API. Gunicorn is written in a fast, scalable, and simple WSGI library.
- To install the latest version of gunicorn, run
pip3 install gunicorn - Create the systemd file for gunicorn. Systemd is the Linux service that manages processes that run in the background. Create the
gunicorn.servicefile in/lib/systemd/system/directory. Change theWorkingDirectoryandExecStartPrepaths to point to the directory where app.py is located.
[Unit]
Description = The gunicorn service
After = network.target
[Service]
Type = simple
WorkingDirectory = /home/ubuntu/api/
ExecStartPre = /bin/bash -c 'source /home/ubuntu/api/myvenv/bin/activate'
ExecStart = gunicorn app:app -w 3
ExecReload = /bin/kill -s HUP $MAINPID
ExecStop = /bin/kill -s TERM $MAINPID
PrivateTmp = true
Restart=on-failure
RestartSec=5s
[Install]
WantedBy = multi-user.target- To allow the gunicorn process to run on startup, run the following command:
systemctl enable gunicorn.service - To start the service, run:
service gunicorn start
Let's Encrypt is a non-profit that issues TLS certificates for free. TLS allows clients to use HTTPS to establish a secure connection to the server. Certbot is the client main client for Let's Encrypt. The installation instructions for Certbot can be found here.
Exposing Gunicorn to the internet is possible, however it doesn't offer features such as TLS, HTTP Headers, or support for multiple domains. NGINX is a speedy, secure, and popular reverse proxy that runs in front of Gunicorn that handles incoming requests and routes them to the appropriate application.
NOTE: The user running the Gunicorn service needs to be in the "shadow" group for the ability to authenticate other users with PAM.
- See the NGINX Installation Instructions for how to install NGINX on Ubuntu
- Replace the
nginx.conffile in/etc/nginx/with the following. Most of the TLS settings are taken from Mozilla.
worker_processes 1;
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Redirect any HTTP request to its HTTPS equivalent
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.tabot.sh;
ssl_certificate /etc/letsencrypt/live/tabot.sh/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/tabot.sh/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# intermediate configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/tabot.sh/fullchain.pem;
# replace with the IP address of your resolver
resolver 8.8.8.8;
#access_log logs/host.access.log main;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}