ConoHa VPS(CentOS 7.6)でFlask + Nginx + uWSGIのWebアプリ(複数)実行環境構築

# はじめに
ConoHa VPS(CentOS 7.6)でFlask + Nginx + uWSGI(Emperor)構成のwebアプリケーションの実行環境を作成します。

複数アプリを実行したかったため、`uWSGI Emperor`を使用しています。

この記事をかなり参考にして作成させていただきました。
- [Ubuntu 14.04 LTSでvenvを利用して速攻でPython3.4 + Nginx + uWSGI + FlaskなWebアプリケーション実行環境を作る](https://qiita.com/5t111111/items/3f2065699fbc4b43c4a8)

ところどころコマンドが違ったりするので、自分用のメモとして
この記事を残させていただきます。


# Nginx 導入

インストール

```
yum install -y nginx
```

起動、状態確認。

```
sudo systemctl start nginx    # 起動
sudo systemctl enable nginx   # サーバ起動時の自動起動設定(任意)
sudo systemctl status nginx   # ステータス確認。
```

起動中なら、`active (running)`という文字が見えるはずです。


一応ブラウザでも確認。(80番PORT開放してから)
<img width="892" alt="スクリーンショット 2019-06-14 22.23.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260131/8baaca44-a158-a38f-0f4b-d77b266402b0.png">


# Flask 導入

## まずpython3
```
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-libs python36u-devel python36u-pip
```

```
python3.6 --version
```




## Flask準備

### アプリ用のdir作成

demoapp/というディレクトリで作業をします。

```
sudo mkdir -p /var/www/demoapp
```

作業がし辛いので、demoapp/の所有権を今ログインしているユーザにします。

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

### アプリ作成用のvenv作成

```
cd /var/www/demoapp
python3.6 -m venv venv
source ./venv/bin/activate
```

### flaskインストール

```
pip install flask
```

## run.pyの作成
`/var/www/demoapp/run.py`

```python:run.py
from flask import Flask

app = Flask(__name__)

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

if __name__ == "__main__":
  app.run(host="0.0.0.0" ,port=5000)
```

## 実行

```
python run.py
```

```:サーバ実行した状態で別端末から
curl localhost:5000
```

で`Hello, World!`が返ってきたら大丈夫です。
ブラウザで確認する場合はPORTの5000番を開ける必要があります。

# Nginxの設定

## 今回のアプリ用の設定ファイル作成
`/var/www/demoapp/demoapp_nginx.conf`

```demoapp_nginx.conf
server {
  listen      80;
  server_name 118.27.xx.xxx(サーバのIPアドレス);
  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のメインの設定ファイルは`/etc/nginx/nginx.conf`になります。
`nginx.conf`内で`/etc/nginx/conf.d/`フォルダから`*.conf`ファイルを読み取るようになっているため、
`/etc/nginx/conf.d/`に個々のアプリ設定ファイルを置いていきます。

シンボリックリンクで配置。

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

一応確認。(同じ中身になっているはず!)

```
cat /etc/nginx/conf.d/demoapp_nginx.conf
```

## Nginx再起動

```
sudo systemctl restart nginx
```

ブラウザでアクセスしてみると、この画面になると思います。
(uWSGIサーバまだ準備してない！)

<img width="546" alt="スクリーンショット 2019-06-14 22.52.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260131/aefa95d9-a7c1-bfb6-b2e8-13c007f56a2e.png">

# uWSGI

## インストール

uWSGI用のvenvを作成し、そこへuWSGIをインストールしていきます。

```
deactivate
cd /opt
sudo python3.6 -m venv venv
source ./venv/bin/activate
pip install uwsgi
```
## 設定ファイルの作成

`/var/www/demoapp/demoapp_uwsgi.ini`

```ini:demoapp_uwsgi.ini
[uwsgi]
#application's base folder
base = /var/www/demoapp

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

#virtualenv folder
virtualenv = /var/www/demoapp/venv

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を起動します。

```
/opt/venv/bin/uwsgi --ini /var/www/demoapp/demoapp_uwsgi.ini
```

# uWSGI Emperor

複数アプリ起動する際に使用します。
`/etc/uwsgi/vassals/`に個々のアプリのuwsgi設定ファイルを配置します。

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

エンペラーによる起動。

```
/opt/venv/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid username --gid username
```

ブラウザで確認！

# コマンドのサービス化

> サービスとはLinux起動時に実行され、システム終了までバックグランドで動き続けるプログラムのことで、デーモン(daemon)やサーバとも言い、その名の通り、様々な機能を他のプログラムやユーザに提供する。稼働中のサービスはpsコマンドで確認できる。
> http://linux.k-sakabe.com/Linux_Server1_c2.html

`/etc/systemd/system/` の下にUnit定義ファイルを作成します。

`/etc/systemd/system/uwsgi.service`

```uwsgi.service
[Unit]
Description=uWSGI
After=syslog.target

[Service]
ExecStart=/opt/venv/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid username --gid username --logto /var/log/uwsgi/emperor.log
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
```

参考
- [Systemdを使ってさくっと自作コマンドをサービス化してみる](https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff)

## 実行

```
sudo systemctl daemon-reload  # Unitファイル読み込み 
sudo systemctl start uwsgi    # 起動
sudo systemctl enable uwsgi   # サーバ起動時の自動起動設定(任意)
```

ブラウザで`Hello, World!`が確認できるかと思います。


# おわりに

はじめての作業ばかりで、間違ったところもあるかと思います。。(T_T)
大変でしたが、すごく楽しかったので`もっと早くVPS借りればよかった-！`という気持ちです。

間違いやもっとこうしたほうが良い！というのがあれば、
ご教示ください...。



# 参考
- [Ubuntu 14.04 LTSでvenvを利用して速攻でPython3.4 + Nginx + uWSGI + FlaskなWebアプリケーション実行環境を作る](https://qiita.com/5t111111/items/3f2065699fbc4b43c4a8)
- [ちゃんと運用するときのuWSGI設定メモ](https://qiita.com/yasunori/items/64606e63b36b396cf695)
- [Flask+Nginx+uWSGI+CentOS7でアプリケーションを作る際にやったこと+日記::12/9](https://fgjiutx.hatenablog.com/entry/2018/12/10/013755)
- [ConoHa VPS(CentOS7)+Flask+Nginx+uWSGIでWEBアプリを作ってみる(1)](https://qiita.com/shikao_yuzu/items/ddfaf2c8bd47f098a464)