Help us understand the problem. What is going on with this article?

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

More than 5 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/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした