Skip to content

Instantly share code, notes, and snippets.

@shapiromatron
Last active August 20, 2020 04:10
Show Gist options
  • Select an option

  • Save shapiromatron/edc7224cae0f0f0e6e5b49b40f08affc to your computer and use it in GitHub Desktop.

Select an option

Save shapiromatron/edc7224cae0f0f0e6e5b49b40f08affc to your computer and use it in GitHub Desktop.
centos7 + httpd + python3.6 + flask

Running a python3 app on centos7 w/ apache

Similar to how things are done in nginx-land, we'll run a separate process for serving a flask application (or any other wsgi python app), and then we'll configure apache to serve it by a reverse proxy.

Let's get started:

# install the things
sudo yum install httpd python3 vim

# make sure we have `proxy_module` and `proxy_http_module`
sudo systemctl restart httpd
sudo httpd -M | grep proxy

# copy code from gist
mkdir /var/www/demo
vim /var/www/demo/hello.py
vim /var/www/demo/gunicorn.conf.py
vim /etc/httpd/conf.d/demo.conf

# setup python the correct way in a virtual environment
python3 -m venv /var/www/demo/venv
source /var/www/demo/venv/bin/activate
pip install -U pip
pip install flask pandas requests gunicorn
deactivate

# test our flask app in debug mode
/var/www/demo/venv/bin/python /var/www/demo/hello.py
# (in another shell)
curl http://127.0.0.1:5050
curl http://127.0.0.1:5050/user/1

# kill the dev server, let's run a production server
mkdir -p /var/log/hello-flask
/var/www/demo/venv/bin/gunicorn -c /var/www/demo/gunicorn.conf.py hello:app
tail -f /var/log/hello-flask/*

# (in another shell)
curl http://127.0.0.1:5000/
curl http://127.0.0.1:5000/user/1

# (to stop): `pkill gunicorn`

# os-setting required for a reverse proxy
sudo setsebool -P httpd_can_network_connect on

# now let's make sure it works through apache
sudo systemctl restart httpd
systemctl status httpd.service
tail -f /var/log/httpd/*

# (test it from another computer)
curl http://157.245.82.74/
curl http://157.245.82.74/user/1

Note: An older version of this gist (not recommended) uses mod_wsgi to use the apache httpd server to serve the wsgi app. This adds lots of complexity and is not recommended.

<VirtualHost *:*>
ProxyPreserveHost On
ProxyPass "/" "http://127.0.0.1:5000/"
ProxyPassReverse "/" "http://127.0.0.1:5000/"
</VirtualHost>
bind = "0.0.0.0:5000"
workers = 2
accesslog = "/var/log/hello-flask/access.log"
errorlog = "/var/log/hello-flask/error.log"
pythonpath = "/var/www/demo"
daemon = True
from flask import Flask
import pandas as pd
app = Flask(__name__)
@app.route("/")
def hello():
# this print will fail on python2
print('yo')
# make sure we can load from the virtual environment
return pd.DataFrame(dict(colors=['red', 'green','blue'], numbers=[1,2,3])).to_html(index=False)
@app.route("/user/<int:user_id>")
def query(user_id: int):
# check our server can serve arbitrary URL paths
return f'<p>You entered the user id {user_id}</p>\n'
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5050, debug=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment