2
2

More than 3 years have passed since last update.

nginx+gunicorn+flask環境をComputeEngine上で構築する

Last updated at Posted at 2019-12-26
1 / 14

はじめに

GCPのロードバランサーの動作を確認したく、ComputeEngineでウェブアプリを立てることにしました。
もともとはロードバランサーの検証作業が目的だったのですが、その過程の作業もちゃんと記録しておいた方がいいなと思い、今回これを記事にすることにしました。

「ComputeEngineを使ってPython3系+flask環境でウェブアプリを構築する」という内容については、Qiitaの別記事にしていますので、よかったらそちらも参考にしてください。

今回はの内容は「nginx+gunicorn+flask」環境を作ることです。

インストールはできても設定の仕方が分からず上手く動かなかった!
という経験をされた方もいらっしゃるのではないでしょうか。

自分も普段はnginxやgunicornを触る機会があまりないので、色々と手探りで環境を構築しました。
自分の作業の備忘録として記事にしておくという意味もあります:sweat_smile:

よかったら参考にしてください:thumbsup:


前提

この記事の内容を進めるにあたっての前提は下記の通りです。

  • Linux環境(Debian9)があること
  • Python3系環境がインストールされていること
  • pip3コマンドが使える状態になっていること
  • flaskがインストールされていること

上記の環境を構築するには、こちら↓の記事を参考にしてください。
GCPのComputeEngine上にPython3系+flask環境を構築する


nginxのインストール

インストールは簡単です。次の2つのコマンドを打てばサクッとインストールできます。

sudo apt update
sudo apt install nginx

Shot 2.png

はい、これでインストールは完了です。
5秒もかかりません:wink:


nginxの動作確認

nginxが動作しているか確認していきましょう。

1. デーモン状態確認

まずは、systemctlでデーモンの状態を確認します。

sudo systemctl status nginx

Shot 4.png

緑の文字のところで「active(Running)」が確認できればOKです。
インストール完了後、自動的にデーモン起動してますね。

もし、activeになっていなかったら、次のコマンドを試してみて下さい。

sudo systemctl start nginx

2. クライアントリクエストの応答確認

Webサーバが起動しているということで、クライアントからのリクエストにちゃんと応答しているかどうか確認してみましょう。

次のcurlコマンドで確認でいます。

curl 127.0.0.1

Shot 5.png

はい、ちゃんとリクエストに応答してくれてますね:ok_hand:

ちなみに、nginxをストップした後、curlコマンドを打つと↓のようになります。
Shot 6.png


gunicornの環境準備

gunicornをインストールしていきます。
インストールは簡単です。
下記のコマンドでサクッとインストールできます。

※gunicornとは何か?については、こちらのページの絵が分かりやすいです。

では、次のコマンドでインストールしていきましょう。

sudo pip3 install gunicorn

Shot 7.png

このような画面になればOKです。


gunicornの動作確認

まず、gunicornを動かすためにコンフィグファイルを用意してあげます。

1. gconf.pyの準備

gunicornのコンフィグファイルを準備します。
※コンフィグファイルなのに.pyファイルなんです…:sweat_smile:
※ちなみに、今回はgconf.pyというファイル名にしましたが、この名前は任意です。

nanoやvimなどで、このファイルを作成してください。
作成場所はflaskアプリのPythonファイルのある場所に配置します。

今回の例では、ホームディレクトリ直下に配置します。

~/gconf.py
import multiprocessing

# Worker Processes
workers = 2
worker_class = 'sync'

# Logging
logfile = '/var/www/apps/sampleapp/app.log'
loglevel = 'info'
logconfig = None

# Socket Definition
socket_path = 'unix:/tmp/gunicorn.sock'
bind = socket_path

この設定ファイルのポイントとしては、ソケットの定義(一番下の2行目)部分です。

この定義によってnginxとflaskをソケット経由で連携できるようにしています。

こんな感じでファイルを作ります。

Shot 3.png

配置場所は、この通りホームディレクトリ直下です。

Shot 9.png

ちなみに同じディレクトリにあるflaskの中身であるmain.pyの内容は次の通りです。

~/main.py
from flask import Flask
app = Flask(__name__)

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

if __name__ == '__main__':
    app.run(debug=False, host='127.0.0.1', port=5000)

2. gunicornの起動

gconf.pyファイルも準備できたので、次はgunicornの起動を確認します。

次のコマンドでgunicornを起動します。
※前提としては、main.pyとgconf.pyがカレントディレクトリに存在することです。

gunicorn main:app --config gconf.py

Shot.png

これでgunicornが起動してます。
ポイントは下記の2つです。

  • 「main:aap」のところで、カレントディレクトリにある「main.py」を指定している。
  • gconf.pyでgunicornの設定をしている。

もう一つ、SSHでシェルを立ち上げて、curlコマンドで応答を確認してみます…
と、いいたいところですが、これはまだできません。

nginxとgunicornを繋げてあげる必要があるからです。
それについては、次に説明します。


nginxとgunicornを繋げる

nginxとgunicornはsocketで連携します。

gunicorn側の設定は、すでにgconf.pyの中でソケットの定義をしています。

後は、nginx側の設定が必要になりますので、ここではその設定について説明します。

nginxのディレクトリ(/etc/nginx/conf.d/)にproject.confファイルを作成します。

sudo nano /etc/nginx/conf.d/project.conf
/etc/nginx/conf.d/project.conf
upstream app_server{
    server unix:/tmp/gunicorn.sock;
}

server{
    listen 80;
    server_name appserver;

    location = /favicon.ico { access_log off; log_not_found off;}

    location /static/ {
        alias /usr/share/nginx/html/static;
    }
}

そして、もともとあったdefaultのnginx設定ファイルを次のコマンドで移動します。
※defaultの設定を無効化するため

sudo mv /etc/nginx/sites-enabled/default ~/default

そして、設定を読み込ませるために次のコマンドでnginxをreloadします。

sudo systemctl reload nginx

※この段階でエラーが出る場合は、設定ファイルが誤っている可能性があります。
ファイルチェックするには次のコマンドを打ってください。

sudo nginx -t

nginxの動作確認(gunicorn連携)

gunicornの設定及びnginxの設定が完了したので、動作確認してみます。

改めて下記のコマンドでgunicornを起動します。

gunicorn main:app --config gconf.py

このような画面になるはずです。
Shot 2.png

もう一つSSHで別のシェルを立ち上げてcurlしてみます。

curl localhost

次のような画面になればOKです。
nginxとgunicornが連携されていることになります。

Shot 1.png


その他

環境構築する過程で、その他必要になる可能性のあるコマンドなどを、ここで紹介します。

gunicornのプロセス稼働確認

ps ax|grep gunicorn

gunicornのプロセスkill

pkill gunicorn

nginxコンフィグファイルの構文チェック

sudo nginx -t

nginxの状態確認

sudo systemctl status nginx

nginxエラーログの確認

cat /var/log/nginx/error.log

gunicorn.socketの状態確認

sudo systemctl status gunicorn.socket

gunicorn.serviceの状態確認

sudo systemctl status gunicorn.service

gunicornの自動起動(SystemDの設定)

一応、これまでの記事内容で「nginx+gunicorn+flask」環境は構築できます。
ただ、私の場合、サーバ起動時に自動的にgunicornプロセスも起動させたかったので、その方法をここに記録しておきます。

serviceファイルとsocketファイルの2つが必要になりますので、下記の通り作成します。

serviceファイル作成

sudo nano /etc/systemd/system/gunicorn.service
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
PIDFile=/run/gunicorn/pid
User=masato_kikukawa_topgate_co_jp
Group=masato_kikukawa_topgate_co_jp
RuntimeDirectory=gunicorn
WorkingDirectory=/home/masato_kikukawa_topgate_co_jp/
ExecStart=/usr/local/bin/gunicorn main:app --config gconf.py
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

socketファイル作成

sudo nano /etc/systemd/system/gunicorn.socket
/etc/systemd/system/gunicorn.socket
Description=gunicorn socket

[Socket]
ListenStream=/tmp/gunicorn.sock

[Install]
WantedBy=sockets.target

ソケットの有効化

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

gunicorn自動起動の動作確認

ComputeEngineのVMを再起動して、gunicornが問題なく起動しているかcurlコマンドで確認します。

curl localhost

Shot 2.png

このようにウェブアプリケーションの応答が返ってくればOKです:relaxed:


おわりに

いかがでしたでしょうか。

nginxやgunicorn、そしてsystemdの設定に普段から慣れていないと、結構躓くポイントがあります。
自分も何度か躓きながらこの記事を作りました。

特に全体像が見えないと、躓いたときに自分の作業内容を見失いがちです。

今回の設定の全体像をチャートにしましたので、これをイメージしながら作業すると迷子を防げるかと思います。

また、デーモンやプロセスの状態を適宜確認しながら進めると不具合の原因箇所を特定しやすくなるので、「その他」の項にかかれているコマンドを活用しながら進めるといいかと思います。

IMG_6822.jpg

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2