Ubuntu 16.04でGunicornとNginxを使用してFlaskアプリケーションを提供する方法

前書き

このガイドでは、Ubuntu 16.04でFlaskマイクロフレームワークを使用して簡単なPythonアプリケーションをセットアップします。 この記事の大部分は、Gunicornアプリケーションサーバーをセットアップしてアプリケーションを起動し、Nginxをフロントエンドリバースプロキシとして機能させる方法について説明します。

前提条件

このガイドを開始する前に、サーバーで非rootユーザーを構成する必要があります。 このユーザーは、管理機能を実行できるように、sudo特権を持っている必要があります。 これを設定する方法については、initial server setup guideに従ってください。

アプリケーションサーバーがFlaskアプリとの通信に使用するWSGI仕様の詳細については、this guideのリンクされたセクションを参照してください。 これらの概念を理解すると、このガイドを理解しやすくなります。

続行する準備ができたら、読み進めてください。

Ubuntuリポジトリからコンポーネントをインストールする

最初のステップは、リポジトリから必要なすべてのピースをインストールすることです。 Pythonコンポーネントをインストールして管理するために、Pythonパッケージマネージャーであるpipをインストールします。 また、Gunicornコンポーネントの一部を構築するために必要なPython開発ファイルも入手します。 Nginxもインストールします。

ローカルパッケージインデックスを更新してから、パッケージをインストールします。 必要な特定のパッケージは、プロジェクトで使用しているPythonのバージョンによって異なります。

Python 2を使用している場合は、次のように入力します。

sudo apt-get update
sudo apt-get install python-pip python-dev nginx

代わりに、Python 3を使用している場合は、次のように入力します。

sudo apt-get update
sudo apt-get install python3-pip python3-dev nginx

Python仮想環境を作成する

次に、Flaskアプリケーションをシステム上の他のPythonファイルから分離するために、仮想環境を設定します。

pipを使用してvirtualenvパッケージをインストールすることから始めます。

Python 2を使用している場合は、次のように入力します。

sudo pip install virtualenv

Python 3を使用している場合は、次のように入力します。

sudo pip3 install virtualenv

これで、Flaskプロジェクトの親ディレクトリを作成できます。 作成後、ディレクトリに移動します。

mkdir ~/myproject
cd ~/myproject

次を入力して、FlaskプロジェクトのPython要件を保存する仮想環境を作成できます。

virtualenv myprojectenv

これにより、Pythonとpipのローカルコピーがプロジェクトディレクトリ内のmyprojectenvというディレクトリにインストールされます。

仮想環境にアプリケーションをインストールする前に、アクティブ化する必要があります。 これを行うには、次のように入力します。

source myprojectenv/bin/activate

プロンプトが変わり、仮想環境内で操作していることが示されます。 この(myprojectenv)user@host:~/myproject$のようになります。

Flaskアプリケーションのセットアップ

仮想環境にいるので、FlaskとGunicornをインストールして、アプリケーションの設計を開始できます。

FlaskとGunicornをインストールする

pipのローカルインスタンスを使用して、FlaskとGunicornをインストールできます。 次のコマンドを入力して、これらの2つのコンポーネントを取得します。

Note

[.note]#使用しているPythonのバージョンに関係なく、仮想環境をアクティブ化するときは、(pip3ではなく)pipコマンドを使用する必要があります。

pip install gunicorn flask

サンプルアプリを作成する

Flaskが使用可能になったので、簡単なアプリケーションを作成できます。 フラスコはマイクロフレームワークです。 より多くのフル機能のフレームワークが提供するツールの多くは含まれておらず、主にプロジェクトにインポートしてWebアプリケーションの初期化を支援できるモジュールとして存在します。

アプリケーションはもっと複雑かもしれませんが、Flaskアプリを単一のファイルで作成します。これをmyproject.pyと呼びます。

nano ~/myproject/myproject.py

このファイル内に、アプリケーションコードを配置します。 基本的に、フラスコをインポートし、Flaskオブジェクトをインスタンス化する必要があります。 これを使用して、特定のルートが要求されたときに実行される機能を定義できます。

~/myproject/myproject.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "

Hello There!

" if __name__ == "__main__": app.run(host='0.0.0.0')

これは基本的に、ルートドメインにアクセスしたときに表示するコンテンツを定義します。 完了したら、ファイルを保存して閉じます。

サーバーの初期セットアップガイドに従った場合、UFWファイアウォールを有効にする必要があります。 アプリケーションをテストするには、ポート5000へのアクセスを許可する必要があります。

次のように入力して、ポート5000を開きます。

sudo ufw allow 5000

次のように入力して、Flaskアプリをテストできます。

python myproject.py

サーバーのドメイン名またはIPアドレスにアクセスし、続いてWebブラウザで:5000にアクセスします。

http://server_domain_or_IP:5000

このようなものが見えるはずです。

Flask sample app

終了したら、ターミナルウィンドウでCTRL-Cを数回押して、Flask開発サーバーを停止します。

WSGIエントリポイントを作成する

次に、アプリケーションのエントリポイントとして機能するファイルを作成します。 これにより、Gunicornサーバーにアプリケーションとの対話方法が通知されます。

ファイルをwsgi.pyと呼びます。

nano ~/myproject/wsgi.py

ファイルは非常にシンプルで、アプリケーションからFlaskインスタンスをインポートして実行するだけです。

~/myproject/wsgi.py

from myproject import app

if __name__ == "__main__":
    app.run()

完了したら、ファイルを保存して閉じます。

Gunicornのプロジェクト提供能力のテスト

先に進む前に、Gunicornが正しく実行できることを確認する必要があります。

これを行うには、エントリポイントの名前を渡すだけです。 これは、モジュールの名前(通常どおり、.py拡張子を差し引いたもの)とアプリケーション内の呼び出し可能オブジェクトの名前で構成されます。 この場合、これはwsgi:appになります。

また、公開するインターフェイスで開始されるように、バインドするインターフェイスとポートを指定します。

cd ~/myproject
gunicorn --bind 0.0.0.0:5000 wsgi:app

サーバーのドメイン名またはIPアドレスにアクセスします。Webブラウザーの末尾に:5000が追加されます:

http://server_domain_or_IP:5000

アプリケーションの出力が再び表示されるはずです。

Flask sample app

正しく機能していることを確認したら、ターミナルウィンドウでCTRL-Cを押します。

これで仮想環境が完成したので、非アクティブ化できます。

deactivate

Pythonコマンドはすべて、システムのPython環境を再び使用するようになります。

systemdユニットファイルを作成する

次に注意する必要があるのは、systemdサービスユニットファイルです。 systemdユニットファイルを作成すると、Ubuntuの初期化システムがGunicornを自動的に起動し、サーバーが起動するたびにFlaskアプリケーションを提供できるようになります。

/ etc / systemd / systemディレクトリ内に.serviceで終わるユニットファイルを作成して開始します。

sudo nano /etc/systemd/system/myproject.service

内部では、メタデータと依存関係を指定するために使用される[Unit]セクションから始めます。 ここにサービスの説明を入力し、ネットワーキングターゲットに到達した後にのみこれを開始するようにinitシステムに指示します。

/etc/systemd/system/myproject.service

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

次に、[Service]セクションを開きます。 プロセスを実行するユーザーとグループを指定します。 関連するすべてのファイルを所有しているため、通常のユーザーアカウントにプロセスの所有権を付与します。 NginxがGunicornプロセスと簡単に通信できるように、www-dataグループにグループの所有権を付与します。

次に、作業ディレクトリをマップし、PATH環境変数を設定して、プロセスの実行可能ファイルが(仮想環境内で)どこにあるかをinitシステムが認識できるようにします。 次に、コマンドを指定してサービスを開始します。 Systemdでは、仮想環境内にインストールされているGunicorn実行可能ファイルへのフルパスを指定する必要があります。

3つのワーカープロセスを開始するように指示します(必要に応じて調整します)。 また、myproject.sockというプロジェクトディレクトリ内にUnixソケットファイルを作成してバインドするように指示します。 007のumask値を設定して、所有者とグループへのアクセスを許可するソケットファイルが作成され、他のアクセスは制限します。 最後に、WSGIエントリポイントのファイル名とPython callableを渡す必要があります。

/etc/systemd/system/myproject.service

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

最後に、[インストール]セクションを追加します。 これにより、起動時に起動できるようにした場合、このサービスをリンクする対象がsystemdに指示されます。 通常のマルチユーザーシステムが稼働しているときにこのサービスを開始する必要があります。

/etc/systemd/system/myproject.service

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

これで、systemdサービスファイルが完成しました。 今すぐ保存して閉じます。

これで、作成したGunicornサービスを開始し、起動時に開始できるように有効化できます。

sudo systemctl start myproject
sudo systemctl enable myproject

リクエストをプロキシするためのNginxの構成

これで、Gunicornアプリケーションサーバーが起動して実行され、プロジェクトディレクトリ内のソケットファイルに対する要求を待機するはずです。 Nginxを構成して、そのソケットにWebリクエストを渡すように構成ファイルに少し追加する必要があります。

Nginxのsites-availableディレクトリに新しいサーバーブロック構成ファイルを作成することから始めます。 ガイドの残りの部分と一致させるために、これを単にmyprojectと呼びます。

sudo nano /etc/nginx/sites-available/myproject

サーバーブロックを開き、Nginxにデフォルトのポート80でリッスンするように指示します。 また、サーバーのドメイン名またはIPアドレスのリクエストにこのブロックを使用するように指示する必要があります。

/etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name server_domain_or_IP;
}

追加する必要がある他の唯一のものは、すべての要求に一致するロケーションブロックです。 このブロック内に、設定する必要のあるいくつかの一般的なプロキシパラメータを指定するproxy_paramsファイルを含めます。 次に、proxy_passディレクティブを使用して定義したソケットにリクエストを渡します。

/etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
    }
}

実際にアプリケーションを提供するために必要なのはそれだけです。 完了したら、ファイルを保存して閉じます。

作成したNginxサーバーブロック構成を有効にするには、ファイルをsites-enabledディレクトリにリンクします。

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

そのディレクトリにあるファイルで、次のように入力して構文エラーをテストできます。

sudo nginx -t

問題が発生せずにこれが返された場合、Nginxプロセスを再起動して新しい構成を読み取ることができます。

sudo systemctl restart nginx

最後に行う必要があるのは、ファイアウォールを再度調整することです。 ポート5000からアクセスする必要がなくなったため、そのルールを削除できます。 その後、Nginxサーバーへのアクセスを許可できます。

sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'

これで、Webブラウザでサーバーのドメイン名またはIPアドレスにアクセスできるはずです。

http://server_domain_or_IP

アプリケーションの出力が表示されます。

Flask sample app

Note

[。注意]##

Nginxを構成したら、次のステップはSSL / TLSを使用してサーバーへのトラフィックを保護することです。 これは重要です。これがないと、パスワードを含むすべての情報がプレーンテキストでネットワーク経由で送信されます。

SSL証明書を取得してトラフィックを保護する最も簡単な方法は、Let’s Encryptを使用することです。 this guideに従って、Ubuntu 16.04でLet’s Encrypt with Nginxを設定します。

結論

このガイドでは、Python仮想環境内にシンプルなFlaskアプリケーションを作成しました。 WSGI対応のアプリケーションサーバーがインターフェイスできるようにWSGIエントリポイントを作成し、この機能を提供するようにGunicornアプリサーバーを構成します。 その後、systemdユニットファイルを作成して、起動時にアプリケーションサーバーを自動的に起動しました。 Webクライアントトラフィックをアプリケーションサーバーに渡し、外部リクエストを中継するNginxサーバーブロックを作成しました。

Flaskは非常にシンプルですが、非常に柔軟なフレームワークであり、構造や設計に制限をかけすぎることなく、アプリケーションに機能を提供することを目的としています。 このガイドで説明されている一般的なスタックを使用して、設計したフラスコアプリケーションを提供できます。

Related