virtualenv -p python3 venv
source ./venv/bin/activate
pip install Flask gunicornmkdir app
cd app
pip freeze > requirements.txt
pip install -t . -r requirements.txtcp -r ../flaskr .
cd ..or install it this way if you have a nice distributable Python package that has a setup.py
pip install -t . ../flaskrrm -rf ./__pycache__ ./*.dist-infoSet the entrypoint of the archive to gunicorn.app.wsgiapp:run with the -m flag which is the same exact function when you run the gunicorn command. Also set the interpreter to /usr/bin/env python3 with the -p flag.
python3 -m zipapp app -m 'gunicorn.app.wsgiapp:run' -p '/usr/bin/env python3'You get an executable .pyz archive with all dependencies bundled inside.
ls -lh app.pyz-rwxr--r-- 1 user user 4.0M Dec 18 09:38 app.pyz
file app.pyzapp.pyz: a /usr/bin/env python3 script executable (binary data)
./app.pyz flaskr:app[2017-12-18 09:38:35 +0200] [39081] [INFO] Starting gunicorn 19.7.1
[2017-12-18 09:38:35 +0200] [39081] [INFO] Listening at: http://127.0.0.1:8000 (39081)
[2017-12-18 09:38:35 +0200] [39081] [INFO] Using worker: sync
[2017-12-18 09:38:35 +0200] [39084] [INFO] Booting worker with pid: 39084
Let's say I don't want to add flaskr:app each time I want to run this archive.
You can do it by creating an entrypoint app/__main__.py with this content:
# -*- coding: utf-8 -*-
import sys
from gunicorn.app.wsgiapp import run
sys.argv.append('flaskr:app')
sys.exit(run())Repackage your app
python3 -m zipapp app -p '/usr/bin/env python3'Run it
./app.pyz[2017-12-18 13:35:30 +0200] [44258] [INFO] Starting gunicorn 19.7.1
[2017-12-18 13:35:30 +0200] [44258] [INFO] Listening at: http://127.0.0.1:8000 (44258)
[2017-12-18 13:35:30 +0200] [44258] [INFO] Using worker: sync
[2017-12-18 13:35:30 +0200] [44261] [INFO] Booting worker with pid: 44261