Python
nginx
Ubuntu
Flask
uwsgi

Ubuntu 12.04でpyenvを利用して速攻でPython3.4 + Nginx + uWSGI + FlaskなWebアプリケーション実行環境を作る

More than 3 years have passed since last update.


登場人物


  • ぼく

    去年まで女子校だった私立高校に通う普通の高校生。人間が嫌い。これ以降登場しない。

  • Ubuntu

    Linuxらしいが、よく知らない。

  • pyenv

    Pythonのバージョンを切り替えるやつ。virtualenvとの連携で使い勝手が超いいらしいが、よく知らない。

  • Nginx

    Webサーバーらしいが、よく知らない。

  • uWSGI

    WSGIサーバーらしいが、何のことか分からない。そもそもWSGIを知らない。

  • Flask

    Webアプリケーションを気軽に作れる軽量のフレームワークらしいが、よく知らない。


pyenvの設定とPythonのインストール

システムのPythonには指一本触れません。

更にpyenvでインストールしたPythonに対しても直接いじることはしません。

パッケージのインストールなどはすべてvirtualenvを使います。

また、普通はpyenvのディレクトリは$HOME以下に作ることが多いと思いますが、

システムから利用するのが$HOME以下にあるのがイマイチ落ち着かないので、ここでは/opt以下に用意します。

なので、pyenv絡みの作業はrootで行うことが多くなります。

とりあえずgitが要ります。

$ sudo apt-get install git


Pythonのビルドのためのパッケージインストール

Pythonのビルドには以下のパッケージが要るのでインストールしておく。

Cコンパイラなど

$ sudo apt-get install build-essential

SQLiteサポートのためのSQLiteライブラリなど

$ sudo apt-get install libsqlite3-dev

$ sudo apt-get install sqlite3
$ sudo apt-get install bzip2 libbz2-dev

pipが必要とするSSLライブラリ

$ sudo apt-get install libssl-dev openssl

readline拡張が必要とするreadlineライブラリ

$ sudo apt-get install libreadline6 libreadline6-dev


pyenv本体とpyenv-virtualenvプラグインのインストール

rootでやります。

sudo su

cd /opt
git clone git://github.com/yyuu/pyenv.git pyenv

echo 'export PYENV_ROOT="/opt/pyenv"' >> ~/.bashrc
echo 'if [ -d "${PYENV_ROOT}" ]; then' >> ~/.bashrc
echo ' export PATH=${PYENV_ROOT}/bin:$PATH' >> ~/.bashrc
echo ' eval "$(pyenv init -)"' >> ~/.bashrc
echo 'fi' >> ~/.bashrc

exec $SHELL -l

cd $PYENV_ROOT/plugins
git clone git://github.com/yyuu/pyenv-virtualenv.git


Python 3.4.0 のインストール

sudo su

pyenv install 3.4.0


pyenvの簡単な使い方

メモ的に。


  • インストール可能なバージョンのリストを表示


  pyenv install --list


  • 3.4.0をインストール


  pyenv install 3.4.0


  • インストール済みバージョンのリスト


  pyenv versions


  • virtualenv環境の作成


  pyenv virtualenv 3.4.0 my-virtual-env-3.4.0


  • virtualenv環境のリスト


  pyenv virtualenvs


  • virtualenvの有効化


  pyenv activate my-virtual-env-3.4.0


  • インストールした環境の削除


  pyenv uninstall my-virtual-env-3.4.0


Nginxのインストール

add-apt-repositoryコマンドを利用するため、python-software-propertiesパッケージをインストール

sudo apt-get install python-software-properties

Nginxのstableリポジトリを追加

$ sudo add-apt-repository ppa:nginx/stable

いつものupdate/upgrade

sudo apt-get update

sudo apt-get upgrade

Nginxのインストールと起動

sudo apt-get install nginx

sudo /etc/init.d/nginx start

ブラウザで接続し、Nginxのgreetingsページが表示されることを確認する。


flaskサンプルアプリケーションの構築


アプリケーションのディレクトリを作成

アプリケーションのディレクトリを作成。

アプリケーションの関連ファイルは全てここに格納する。

※ただし、virtualenv環境は/opt以下などでpyenvに一括管理させる。

sudo mkdir -p /var/www/demoapp

ユーザー権限がrootのままだとあれなので、自分の利用しているユーザーに変更しておく

sudo chown -R username:username /var/www/demoapp/


サンプルアプリケーション用のvirtualenvの作成

sudo -s

pyenv virtualenv 3.4.0 demoapp


Flaskのインストール

virtualenvにFlaskのインストール

sudo -s

pyenv activate demoapp
pip install flask


Flaskアプリケーションの作成

/var/www/demoapp/hello.pyを作成。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"

if __name__ == "__main__":
app.run(host='0.0.0.0', port=8080)


flaskアプリケーションの起動テスト

pyenv activate demoapp

python /var/www/demoapp/hello.py

webブラウザでサーバーのポート:8080に接続し確認。


uWSGIのインストール


uWSGI用のvirtualenv環境の構築

uWSGIは複数アプリケーションで共用すると思うので、

アプリケーション用のvirtualenvとはまた別に用意する。

アプリケーション用の demoapp virtualenvを有効化していたらdeactivate.

deactivate

uWSGI用のvirtualenv

sudo -s

pyenv virtualenv 3.4.0 uwsgi-3.4.0


uWSGIのインストール

sudo -s

pyenv activate uwsgi-3.4.0
pip install uwsgi


Nginxの設定

デフォルトのサイト設定を削除

sudo rm /etc/nginx/sites-enabled/default

サンプルアプリケーション用の設定ファイルを作成

/var/www/demoapp/demoapp_nginx.conf を作成

server {

listen 80;
server_name localhost;
charset utf-8;
client_max_body_size 75M;

location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/var/www/demoapp/demoapp_uwsgi.sock;
}
}

Nginxの設定ファイルのディレクトリにシンボリックリンクを貼る

sudo ln -s /var/www/demoapp/demoapp_nginx.conf /etc/nginx/conf.d/

Nginxの再起動

sudo /etc/init.d/nginx restart

webブラウザでサーバーに接続し確認。

この時点では"502 Bad Gateway"のエラーが出るはず。


uWSGIの設定


アプリケーションのuWSGI設定ファイルを作成する

/var/www/demoapp/demoapp_uwsgi.ini を作成

[uwsgi]

#application's base folder
base = /var/www/demoapp

#python module to import
app = hello
module = %(app)

#virtualenv folder
home = /opt/pyenv/versions/demoapp

pythonpath = %(base)

#socket file's location
socket = /var/www/demoapp/%n.sock

#permissions for the socket file
chmod-socket = 666

#the variable that holds a flask application inside the module imported at line #6
callable = app

#location of log files
logto = /var/log/uwsgi/%n.log


ログ出力先ディレクトリの作成

sudo mkdir -p /var/log/uwsgi

sudo chown -R username:username /var/log/uwsgi


uWSGIの起動

pyenv activate uwsgi-3.4.0

uwsgi --ini /var/www/demoapp/demoapp_uwsgi.ini

webブラウザでサーバーに接続し確認。

NginxとuWSGIが問題なくソケット通信できていれば、Hello World!が表示される。


uWSGI Emperor

uWSGI EmperorはuWSGIの設定ファイルを読み込んでuWSGIプロセスを起動する機能。

複数の設定を読み込みプロセス起動を一括管理することができる。


Upstartファイルの作成

/etc/init/uwsgi.conf を作成

description "uWSGI"

start on runlevel [2345]
stop on runlevel [06]
respawn

env UWSGI=/opt/pyenv/versions/uwsgi-3.4.0/bin/uwsgi
env LOGTO=/var/log/uwsgi/emperor.log

exec $UWSGI --master --emperor /etc/uwsgi/vassals --die-on-term --uid www-data --gid www-data --logto $LOGTO

上記の最後の行は、/etc/uwsgi/vassalsに存在する設定ファイルを探しuWSGIデーモンを起動することを意味しているので、

サンプルアプリケーションのuWSGI設置ファイルへのシンボリックリンクを/etc/uwsgi/vassalsに作成。

sudo mkdir -p /etc/uwsgi/vassals

sudo ln -s /var/www/demoapp/demoapp_uwsgi.ini /etc/uwsgi/vassals


権限の設定

uWSGIデーモンをwww-dataユーザーで起動する設定としている。

したがって、アプリケーションとログのディレクトリのオーナーをwww-dataにしておく。

sudo chown -R www-data:www-data /var/www/demoapp/

sudo chown -R www-data:www-data /var/log/uwsgi/

NginxとuWSGIが同一のwww-dataユーザーで動作するため、ソケットのパーミッションを644に変更しておく。

/var/www/demoapp/demoapp_uwsgi.ini を編集

...

#permissions for the socket file
chmod-socket = 644


uWSGIの起動

sudo start uwsgi

webブラウザでサーバーに接続し確認。

ここまですべて問題なければ、Hello World!が表示される。


終わりに

一応これでFlaskアプリケーションを動かせるところまではできました。

注意点というか突っ込みどころは色々あるかと思います。

特にNginxとuWSGIの周りは、それぞれのドキュメントやググって設定を詰めてください。


参考

http://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/