DebianでNginx+Unit+Flask環境を構築する

Debian Busterで構築したサーバーでFlaskアプリを使えるようにします。レンタルサーバーのエックスサーバーやロリポップ!でFlask環境を構築したときは簡単にできたので、Debianでもすぐにできるだろうと思っていましたが、予想以上に大変でした。

Nginxをインストール

Apache2を停止

Apache2を起動していると、Nginxのインストール時に起動エラーが出るのでApache2を停止しておきます。

sudo systemctl stop apache2

さらに、Apache2の自動起動を停止する場合は、

sudo systemctl disable apache2

Nginxのインストール

sudo apt install nginx

インストールできたら、Nginxのステータスを確認します。

sudo systemctl status nginx

デフォルトで常時起動する設定になっていますが、常時起動するには

sudo systemctl enable nginx

Nginx Unitをインストール

https://unit.nginx.org/installation/を参考にNginx Unitをインストールしていきます。

curlをインストール

curlがインストールされていない場合は、curlをインストールします。

sudo apt install curl
curlとは

コマンドラインツールの一種で、シェルなどから “curl” というコマンドに続けてダウンロードしたいURLやオプションなどを記述して実行することで、その場所からファイルを取得して表示したり、ファイルとして保存することができる。URLで指定した場所にファイルをアップロードすることもできる。

引用:IT用語辞典 e-Words https://e-words.jp/w/CURL.html

NGINXの signing key をダウンロードして追加

sudo curl -sL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Unitのレポジトリファイルを作成

sudo nano /etc/apt/sources.list.d/unit.list

以下の内容を書き込んで保存します。

unit.list
deb https://packages.nginx.org/unit/debian/ buster unit
deb-src https://packages.nginx.org/unit/debian/ buster unit

Unitをインストール

sudo apt update
sudo apt install unit
sudo apt install unit-dev unit-go unit-jsc11 unit-perl unit-php unit-python2.7 unit-python3.7 unit-ruby

Unitのステータスを確認します。

sudo systemctl status unit

デフォルトで常時起動する設定になっていますが、常時起動するには

sudo systemctl enable unit

Flaskのインストールと仮想環境の構築

ディレクトリはどこでもいいのですが、今回は少し面倒な/var/www/html/にtestという名前のディレクトリを作成し、その中に仮想環境構築とFlaskをインストールして、稼働テストをしていきます。

treeで表示すると最終的にはこんな感じになります。

/var/www/html/
└── test
    ├── config.json
    ├── flask_test
    └── wsgi.py

コマンドはこんな感じです。まだ、wsgi.pyとconfig.jsonは作成していません。

dattesar@debian:~$ su -
パスワード:
root@debian:~# mkdir /var/www/html/test
root@debian:~# apt install python3-venv
root@debian:~# python3 -m venv /var/www/html/test/flask_test
root@debian:~# source /var/www/html/test/flask_test/bin/activate
(flask_test) root@debian:~# pip install flask
(flask_test) root@debian:~# deactivate
root@debian:~# exit

rootユーザーに切替

まずは、rootユーザーに切り替えます。

su -

または

sudo su -

ディレクトリを作成

mkdir /var/www/html/test
  1. pythonの仮想環境(flask_test)
  2. Flaskアプリ(wsgi.py)
  3. Unit用設定ファイル(config.json)

以上の3点を、このディレクトリの中に追加していきます。

venvをインストール

venvが入っていない場合は、インストールします。

apt install python3-venv

仮想環境を構築

python3 -m venv /var/www/html/test/flask_test

仮想環境をactivate

source /var/www/html/test/flask_test/bin/activate

Flaskをインストール

pip install flask

仮想環境をdeactivate

deactivate

ここまでできたら、rootユーザーからexitします。

exit

Nginx Unitの設定

https://unit.nginx.org/howto/flask/を参考にNginxUnitの設定をしていきます。

wsgi.pyファイルを作成

sudo nano /var/www/html/test/wsgi.py
wsgi.py
from flask import Flask
app = Flask(__name__)

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

所有者をunitに変更

https://unit.nginx.org/howto/flask/では、ディレクトリの所有者をunitに変更するように書いてありますが、今回のHello, World!と表示するだけのアプリでは、所有者を変更しなくても問題ない気がします。

/var/www/html/test/のディレクトリと中のファイルの所有者をunitに変更します。

sudo chown -R unit:unit /var/www/html/test/

Flask用configファイルの設定

configファイルを作成

configファイル
{
    "listeners": {
        "*:80": {
            "pass": "applications/flask"
        }
    },

    "applications": {
        "flask": {
            "type": "python 3.Y",
            "path": "/path/to/app/",
            "home": "/path/to/app/venv/",
            "module": "wsgi",
            "callable": "app"
        }
    }
}

これを元にポートと”path” “home”を変更していきます。

sudo nano /var/www/html/test/config.json
config.json
{
    "listeners": {
        "*:8100": {
            "pass": "applications/flask"
        }
    },

    "applications": {
        "flask": {
            "type": "python 3.7",
            "path": "/var/www/html/test/",
            "home": "/var/www/html/test/flask_test/",
            "module": "wsgi",
            "callable": "app"
        }
    }
}
  • 使っていないポート番号を指定(今回は、8100)
  • “type”には、pythonのバージョンを指定(“python”とバージョンを指定しなくても動きます)
  • “path”には、アプリのディレクトリを指定
  • “home”には、Flaskをインストールした仮想環境を指定
  • “module”には、先ほど作成したwsgi.pyファイルから.pyをとってwsgiと入力
  • “callable”には、wsgi.pyファイル内に記述した、app = Flask(name)appと入力

control.unit.sockファイルの場所を探す

sudo find / -name 'control.unit.sock'

Debianでは、/run/control.unit.sockにあります。

NginxUnitにconfigファイルを登録

ここは、すごく失敗しやすいです。Nginxを起動している場合は、https://unit.nginx.org/howto/flask/に書いてあるとおりにconfig.jsonを作成していると、エラーがでます。

@の部分には先ほど作成したconfig.jsonのパスを指定します。

sudo curl -X PUT --data-binary @/var/www/html/test/config.json --unix-socket /run/control.unit.sock http://localhost/config/
成功したときの表示
{
	"success": "Reconfiguration done."
}
失敗したときの表示
{
	"error": "Failed to apply new configuration."
}

エラーメッセージはエラー内容によって変わります。NginxUnitのログを見てエラー内容を確認します。

sudo cat /var/log/unit.log
エラー内容(例)
[alert] 2370#2370 bind(\"0.0.0.0:80\") failed (98: Address already in use)
[alert] 2374#2374 failed to apply new conf

ログファイルに、このように記述されている場合は、config.jsonで80番ポート以外を指定して登録し直してください。

登録したconfigファイルの確認

登録したconfigファイルの内容を確認するには、

sudo curl -X GET --unix-socket /run/control.unit.sock http://localhost/config/

アクセスできるか確認

curl http://localhost:8100

これで、Hello, World!と表示されれば成功です。

設定が成功していても、表示されない場合は、NginxUnitを再起動してみます。

sudo systemctl restart unit

ufwの設定

この段階でクライアントPCからブラウザで接続確認(http://IPアドレス:8100と入力)をする場合は、ufwでポートを開放しておく必要があります。

今回のように、後でNginxを設定する場合は、ポートを開放する必要はありません。

sudo ufw allow 8100

参考:プロセスが使用しているポートを調べる

sudo lsof -i -P

ポート番号を指定する場合

以下の例では、80番ポートを指定しています。

sudo lsof -i:80

Nginxの設定

http://IPアドレス/test にアクセスしたときに、wsgi.pyで設定したFlaskアプリでHello, World!と表示されるように、Nginxを設定していきます。

nginx.confの設定

sudo nano /etc/nginx/nginx.conf
nginx.conf
http {

        upstream unit_backend {
                server 127.0.0.1:8200;
        }

(中略)

}

使っていないポート番号を指定します

/etc/nginx/sites-available/defaultの設定

sudo nano /etc/nginx/sites-available/default
/etc/nginx/sites-available/default
server {

(中略)

        location /test {
                proxy_pass http://127.0.0.1:8100/;
        }

(中略)

}

ポート番号はconfig.jsonで設定したポート番号と同じ番号にします

{
    "listeners": {
        "*:8100": {
            "pass": "applications/flask"
        }
    },

    "applications": {
        "flask": {
            "type": "python 3.7",
            "path": "/var/www/html/test/",
            "home": "/var/www/html/test/flask_test/",
            "module": "wsgi",
            "callable": "app"
        }
    }
}

NginxとUnitを再起動

ここまで設定できたら、NginxとNginxUnitを再起動します。

sudo systemctl restart nginx
sudo systemctl restart unit

接続テスト

最後に、クライアントPCからブラウザにhttp://IPアドレス/test/と入力し、Hello, World!と表示されたら無事完了です。

DebianのIPアドレスが192.168.111.111の場合は、http://192.168.111.111/test/ と入力します。