Last active
August 10, 2019 22:27
-
-
Save ckandoth/2281dab10324a7316fcf to your computer and use it in GitHub Desktop.
Set up nginx and uwsgi emperor on a CentOS 6.7 box
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# GOAL: On a CentOS 6.7 minimal install, set up nginx as a reverse proxy to uWSGI Emperor with python 2.7.11 as a plugin to run Flask apps | |
# ::NOTE:: All instructions below are run as a sudoer, not as root. Talk to your sysadmins if you're not a sudoer. | |
# Install bare essentials: | |
sudo yum install -y epel-release | |
sudo yum groupinstall 'Development Tools' | |
sudo yum install -y vim openssl unzip nginx openssl-devel zlib-devel sqlite-devel bzip2-devel libffi-devel lapack-devel blas-devel libpng-devel freetype-devel | |
# Set SELINUX=disabled in the file below, and reboot, or this tutorial will get unnecessarily complicated: | |
sudo vim /etc/sysconfig/selinux | |
############# | |
### Nginx ### | |
############# | |
# Create an nginx virtual host that redirects everything to uWSGI: | |
# ::NOTE:: Let nginx handle static/media files; it's more efficient at those than uWSGI | |
sudo vim /etc/nginx/conf.d/uwsgi.conf | |
## -------------- Contents for /etc/nginx/conf.d/uwsgi.conf -------------- ## | |
server { | |
listen 80; | |
server_name haystack-dev.mskcc.org; # Replace with your IP or FQDN | |
location / { | |
include uwsgi_params; | |
uwsgi_pass unix:/var/tmp/uwsgi.sock; | |
} | |
} | |
## -------------------------------------------------------------------------- ## | |
# Start the nginx service, and make sure it restarts on reboot: | |
sudo service nginx start | |
sudo chkconfig nginx on | |
################ | |
## Python 2.7 ## | |
################ | |
# Move to a folder where we can download and build various source code: | |
cd /opt/common/CentOS_6-dev/python/src | |
# Point to the folder where we want to install python 2.7: | |
export PYTHON_PREFIX=/opt/common/CentOS_6-dev/python/python-2.7.11 | |
# Download Python source, configure, make, and install to folder above: | |
curl -LO https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz | |
tar -zxf Python-2.7.11.tgz | |
cd Python-2.7.11 | |
./configure --prefix=$PYTHON_PREFIX --enable-shared --enable-unicode=ucs4 LDFLAGS="-Wl,-rpath=$PYTHON_PREFIX/lib" | |
make | |
make install | |
cd ../ | |
# Make sure the latest setuptools and pip are installed: | |
$PYTHON_PREFIX/bin/python -m ensurepip | |
$PYTHON_PREFIX/bin/pip install --upgrade setuptools pip | |
# Install all the various packages we use here at MSKCC: | |
$PYTHON_PREFIX/bin/pip install --upgrade alabaster ansi argparse azure babel biopython drmaa filemagic fireworks fusepy ipython lockfile markerlib nose powerline-status pygments pyvcf sh snowballstemmer sphinx virtualenv wheel | |
$PYTHON_PREFIX/bin/pip install --upgrade pysam matplotlib pandas cython scipy | |
##################### | |
### uWSGI Emperor ### | |
##################### | |
# Move to a folder where we can download and build various source code: | |
cd /opt/common/CentOS_6-dev/python/src | |
# Download uWSGI source, build it, an http plugin, and a plugin for our python 2.7 install above: | |
curl -LO https://github.com/unbit/uwsgi/archive/2.0.12.tar.gz | |
tar -zxf 2.0.12.tar.gz | |
cd uwsgi-2.0.12 | |
$PYTHON_PREFIX/bin/python uwsgiconfig.py --build core | |
$PYTHON_PREFIX/bin/python uwsgiconfig.py --plugin plugins/http core | |
$PYTHON_PREFIX/bin/python uwsgiconfig.py --plugin plugins/python core python27 | |
# Install uWSGI, and store the plugins where uWSGI will be configured to find it: | |
sudo cp uwsgi /usr/local/bin/ | |
sudo mkdir -p /usr/local/lib/uwsgi | |
sudo cp *_plugin.so /usr/local/lib/uwsgi/ | |
cd ../ | |
# Create a unix user+group named uwsgi, which will run the Emperor: | |
sudo adduser uwsgi | |
# Create a uWSGI init.d file to start/stop/restart the Emperor as a daemonized service: | |
sudo vim /etc/init.d/uwsgi | |
## --------------------- Contents for /etc/init.d/uwsgi --------------------- ## | |
#!/bin/sh | |
# | |
# uwsgi - This script starts and stops the uWSGI emperor | |
# | |
# chkconfig: - 85 15 | |
# description: Fast, self-healing, application container server | |
# processname: uwsgi | |
# Source function library. | |
. /etc/rc.d/init.d/functions | |
PATH=/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | |
PROG=/usr/local/bin/uwsgi | |
OWNER=uwsgi | |
NAME=uwsgi | |
DAEMON_OPTS="--ini /usr/local/etc/uwsgi.ini --daemonize /var/log/uwsgi.log" | |
[ -f /etc/sysconfig/uwsgi ] && . /etc/sysconfig/uwsgi | |
lockfile=/var/lock/subsys/uwsgi | |
start () { | |
echo -n "Starting $NAME: " | |
daemon $PROG $DAEMON_OPTS | |
retval=$? | |
echo | |
[ $retval -eq 0 ] && touch $lockfile | |
return $retval | |
} | |
stop () { | |
echo -n "Stopping $NAME: " | |
killproc $PROG -INT | |
retval=$? | |
echo | |
[ $retval -eq 0 ] && rm -f $lockfile | |
return $retval | |
} | |
restart () { | |
stop | |
start | |
} | |
rh_status () { | |
status $PROG | |
} | |
rh_status_q() { | |
rh_status >/dev/null 2>&1 | |
} | |
case "$1" in | |
start) | |
rh_status_q && exit 0 | |
$1 | |
;; | |
stop) | |
rh_status_q || exit 0 | |
$1 | |
;; | |
restart) | |
$1 | |
;; | |
status) | |
rh_status | |
;; | |
condrestart|try-restart) | |
rh_status_q || exit 0 | |
restart | |
;; | |
*) | |
echo "Usage: $0 {start|stop|restart|condrestart|try-restart|status}" >&2 | |
exit 2 | |
;; | |
esac | |
exit 0 | |
## -------------------------------------------------------------------------- ## | |
# Make it an executable script: | |
sudo chmod 755 /etc/init.d/uwsgi | |
# Edit the uWSGI core config file, to customize Emperor defaults: | |
sudo vim /usr/local/etc/uwsgi.ini | |
## ---------------------- Contents for /usr/local/etc/uwsgi.ini ----------------------- ## | |
[uwsgi] | |
binary-path = /usr/local/bin/uwsgi | |
uid = uwsgi | |
gid = uwsgi | |
plugins-dir = /usr/local/lib/uwsgi | |
emperor = /srv/www/vassals/*/*.ini | |
cap = setgid,setuid | |
## -------------------------------------------------------------------------- ## | |
# ::NOTE:: Change "/srv/www/vassals" above to where Emperor can glob for subfolders | |
# with .ini files for each app that it needs to monitor for edits, and load. | |
# Start uWSGI Emperor, and make sure it restarts on reboot: | |
sudo service uwsgi start | |
sudo chkconfig uwsgi on | |
######################### | |
### Test 2 Flask Apps ### | |
######################### | |
# Create 2 minimalist flask apps, and 1 .ini file for Emperor to find. | |
## --------------- Contents for /srv/www/vassals/app1/app1.py --------------- ## | |
from flask import Flask | |
app = Flask(__name__) | |
@app.route('/') | |
def index(): | |
return "<span style='color:red'>Hello World! I am App 1...</span>" | |
## -------------------------------------------------------------------------- ## | |
## --------------- Contents for /srv/www/vassals/app2/app2.py --------------- ## | |
from flask import Flask | |
app = Flask(__name__) | |
@app.route('/') | |
def index(): | |
return "<span style='color:blue'>Hello World! I am App 2...</span>" | |
## -------------------------------------------------------------------------- ## | |
## -------------- Contents for /srv/www/vassals/uwsgi/uwsgi.ini --------------- ## | |
[uwsgi] | |
socket = /var/tmp/uwsgi.sock | |
chmod-socket = 666 | |
plugin = /usr/local/lib/uwsgi/python27 | |
mount = /app1=/srv/www/vassals/app1/app1.py | |
mount = /app2=/srv/www/vassals/app2/app2.py | |
callable = app | |
manage-script-name = true | |
processes = 4 | |
master = true | |
vacuum = true | |
## -------------------------------------------------------------------------- ## | |
# After creating the files above, check Emperor's log file: | |
sudo tail -n40 /var/log/uwsgi.log | |
# If it says something like the following, then Emperor loaded it correctly: | |
# [emperor] vassal /srv/www/vassals/uwsgi/uwsgi.ini is ready to accept requests | |
# Visit http://haystack-dev.mskcc.org/app1 and http://haystack-dev.mskcc.org/app2 which should | |
# correctly show their respective Hello World messages. | |
# If you see a "502 Bad Gateway" message, then the bug is at nginx. See this file for errors: | |
sudo tail -n40 /var/log/nginx/error.log |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment