CentOSもWebサーバの構築も無知な自分が,Flask・Nginx・uWSGIに足を踏み入れた話.
その手順をここにまとめておく.
前提
- OS : CentOS 7
- root権限が付与されたユーザ
- Pythonの仮想環境にはpipenvを使う
準備
登場人物
適宜置き換えて読むべし.
user
: ユーザ名
proj
: プロジェクトのディレクトリ
test.py
: Flaskを動かすコードを書く.projの直下に配置
作業は常時プロジェクトディレクトリ下で行う
$ cd /home/user/proj
Flaskの導入
Flaskを使い,PythonでWebアプリを簡単に作れるようにするための環境を作る.
Python3のインストール
$ sudo yum install epel-release # リポジトリを入れる
$ sudo yum install python3-devel # python3を入れる
仮想環境を作る
$ pip3 install pipenv # pipenvを導入
$ export PIPENV_VENV_IN_PROJECT=true # 仮想環境をプロジェクトディレクトリ内に作るように設定
$ pipenv --python 3 # 仮想環境の生成
$ ls -a # ファイル一覧を確認
.venv
ができてるのが確認できればOK.
必要なモジュールのインストール
最低限必要なのはこれだけ.
$ pipenv install flask markupsafe
移行のときに困りたくなければ,pip
ではなくpipenv
でインストールすること.
他に必要なモジュールがあったら,同様にpipenv install
で入れる.
Flaskを使ってみる
Flaskを書く
test.py
を作る.
$ vi test.py
i
で挿入モードに入り,以下を記述.
書き終わったらEsc
→:wq
で抜ける.
from flask import *
app = Flask(__name__)
@app.route("/")
def main():
return 'Hello, World!\n'
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=80)
トップページにアクセスされたら'Hello, World!'を出力するだけのコードである.
Flaskの実行
いくらモジュールをインストールしようが,仮想環境に入らないことには始まらない.
$ pipenv shell # 仮想環境に入る
test.py
を実行!
$ python test.py
Google Chrome等のブラウザで,これを実行したサーバのIPアドレスを打ち込んでアクセスする.
'Hello, World!'と表示されたらOK.
ターミナルに戻り,Ctrl+C
で実行を止める.
Nginxの導入
Nginxのインストール
まずnginx.repo
をvim等で開く.
$ sudo vi /etc/yum.repos.d/nginx.repo
以下を記述.
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
HTTPポートの開放
ファイアウォールがHTTPサービスを許可するように設定.
$ sudo firewall-cmd --add-service=http --zone=public --permanent
$ sudo firewall-cmd --reload
Nginxの起動
$ sudo systemctl start nginx # 即時起動
$ lsof -i:80 # nginxが表示されればOK
uWSGIの導入
uWSGIは,FlaskとNginxの仲介役となるアプリケーションサーバ.
uWSGIのインストール
$ pipenv install uwsgi
設定ファイルの作成
$ vi test_uwsgi.ini
以下を記述.
[uwsgi]
base = /home/user/proj
app = test
module = %(app)
virtualenv = /home/user/proj/.venv
pythonpath = %(base)
socket = /tmp/test_uwsgi.sock
chmod-socket = 666
callable = app
logto = /home/user/proj/log/%n.log
自分でアレンジしたいなら↓
uWSGIのiniファイルの文法まとめ
ログ用のディレクトリも作っておく.
$ mkdir log
Nginx側の設定
proj
ディレクトリの下でNginx用の設定ファイルを作る.
$ vi test_nginx.conf
以下を記述.
server {
listen 80;
server_name [IPアドレス];
charset utf-8;
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/tmp/test_uwsgi.sock;
}
}
Nginxが起動時にこれを参照できるように,シンボリックリンクを配置する.
sudo ln -s /home/user/proj/test_nginx.conf /etc/nginx/conf.d/
必ず絶対パスで指定すること.
(Optional) SELinuxを無効化する
SELinuxは,Linux内部でのアクセスの監視と制御を常時行ってるらしい.
PCに侵入されたときの被害を最小限に抑えるためだとか.
Nginx起動時にエラーを吐かれる場合は,以下のようにすることで解決できるかも.
$ setenforce 0
これでアクセス制御はオフになる.
Permissiveモードになるだけで完全なオフになるわけではないらしい.
再起動しても元に戻らないよう,設定ファイル自体も編集する.
$ vi /etc/selinux/config # "SELINUX=enforcing"を"SELINUX=permissive"に書き換える
SELinuxを使わなくても,セキュリティ的に大丈夫なのか?
使うに越したことは無いけど,ファイアーウォールとかしっかり設定しとけばまぁ大丈夫でしょ,という結論に.
uWSGI動作確認
$ sudo systemctl restart nginx # SELinuxをオフにしないとここでエラーを吐くかも
$ uwsgi --ini test_uwsgi.ini # 設定ファイルからuWSGIを起動
ブラウザをリロードし,'Hello, World!'と表示されればOK.
サービス化
サーバ起動時に,これらが自動で起動されるようにする.
uWSGIのサービス用の設定ファイルを作る
vi /etc/systemd/system/uwsgi.service
以下を記述.
[Unit]
Description=uWSGI
After=syslog.target
[Service]
ExecStart=/home/user/proj/.venv/bin/uwsgi --ini /home/user/proj/test_uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
$ cat /lib/systemd/system/nginx.service # 今書いたものが表示されればOK
サービスの設定
$ sudo systemctl daemon-reload # uwsgi.serviceの再読み込み
$ sudo systemctl enable uwsgi nginx # uWSGIとNginxのサービスを有効化
サーバを再起動してみて,ブラウザで確認.'Hello, World!'と表示されればOK.
お疲れ様でした!!