Ubuntu18.04でGunicornとNginxを使用してFlaskアプリケーションを提供する方法
序章
このガイドでは、Ubuntu18.04でFlaskマイクロフレームワークを使用してPythonアプリケーションを構築します。 この記事の大部分は、 Gunicornアプリケーションサーバーをセットアップする方法と、アプリケーションを起動してNginxをフロントエンドリバースプロキシとして機能するように構成する方法について説明します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
-
Ubuntu 18.04がインストールされ、sudo権限を持つ非rootユーザーであり、ファイアウォールが有効になっているサーバー。 ガイダンスについては、初期サーバーセットアップガイドに従ってください。
-
Ubuntu 18.04にNginxをインストールする方法のステップ1と2に従って、Nginxをインストールしました。
-
サーバーを指すように構成されたドメイン名。 Namecheap で購入するか、Freenomで無料で入手できます。 ドメインとDNSに関する関連するドキュメントに従うことで、ドメインをDigitalOceanにポイントする方法を学ぶことができます。 必ず次のDNSレコードを作成してください。
- とのAレコード
your_domain
サーバーのパブリックIPアドレスを指します。 - とのAレコード
www.your_domain
サーバーのパブリックIPアドレスを指します。
- とのAレコード
-
GunicornサーバーがFlaskアプリケーションとの通信に使用するWSGI仕様に精通していること。 このディスカッションでは、WSGIについて詳しく説明します。
ステップ1—Ubuntuリポジトリからコンポーネントをインストールする
最初のステップは、デフォルトのUbuntuリポジトリから必要なすべてのパッケージをインストールすることです。 これも pip
、Pythonコンポーネントを管理するPythonパッケージマネージャー。 また、Gunicornコンポーネントの一部を構築するために必要なPython開発ファイルも入手できます。
まず、ローカルパッケージを更新します。
- sudo apt update
次に、Python環境を構築できるようにするパッケージをインストールします。 これらには以下が含まれます python3-pip
、堅牢なプログラミング環境に必要ないくつかのパッケージと開発ツールとともに:
- sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
これらのパッケージを配置したら、プロジェクトの仮想環境の作成に進みます。
ステップ2—Python仮想環境を作成する
次に、仮想環境をセットアップして、Flaskアプリケーションをシステム上の他のPythonファイルから分離します。
インストールすることから始めます python3-venv
パッケージ、インストールします venv
モジュール:
- sudo apt install python3-venv
次に、Flaskプロジェクトの親ディレクトリを作成します。
- mkdir ~/myproject
次に、ディレクトリを作成した後、ディレクトリに移動します。
- cd ~/myproject
次のように入力して、FlaskプロジェクトのPython要件を保存する仮想環境を作成します。
- python3.6 -m venv myprojectenv
これにより、Pythonのローカルコピーがインストールされ、 pip
と呼ばれるディレクトリに myprojectenv
プロジェクトディレクトリ内。
仮想環境内にアプリケーションをインストールする前に、以下を実行してアプリケーションをアクティブ化する必要があります。
- source myprojectenv/bin/activate
プロンプトが変わり、仮想環境内で操作していることを示します。 次のようになります。
(myprojectenv)\ssammy@host:~/myproject$
ステップ3—Flaskアプリケーションのセットアップ
仮想環境にいるので、FlaskとGunicornをインストールして、アプリケーションの設計を開始できます。
まず、インストールします wheel
のローカルインスタンスで pip
ホイールアーカイブがない場合でもパッケージが確実にインストールされるようにするには、次のようにします。
- pip install wheel
注:使用しているPythonのバージョンに関係なく、仮想環境がアクティブ化されている場合は、 pip
コマンド(ではない pip3
).
次に、FlaskとGunicornをインストールします。
- pip install gunicorn flask
Flaskを使用できるようになったので、次のステップで基本的なアプリケーションを作成できます。
サンプルアプリケーションの作成
Flaskはマイクロフレームワークであるため、よりフル機能のフレームワークに含まれる可能性のあるツールの多くは含まれていません。 Flaskは主に、Webアプリケーションの初期化を支援するためにプロジェクトにインポートできるモジュールとして存在します。
アプリケーションはもっと複雑かもしれませんが、Flaskアプリケーションを1つのファイルに作成します。 myproject.py
. お好みのテキストエディタを使用してこのファイルを作成します。 ここでは使用します nano
:
- nano ~/myproject/myproject.py
アプリケーションコードはこのファイルに存在します。 Flaskをインポートし、Flaskオブジェクトをインスタンス化します。 これを使用して、特定のルートが要求されたときに実行する必要がある関数を定義できます。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
これは、ルートドメインにアクセスしたときに表示するコンテンツを定義します。 終了したら、ファイルを保存して閉じます。 nanoを使用している場合は、を押すことでこれを行うことができます CTRL + X
それから Y
と ENTER
.
前提条件の初期サーバーセットアップガイドに従っている場合は、UFWファイアウォールを有効にする必要があります。 アプリケーションをテストするには、最初にポートへのアクセスを許可する必要があります 5000
:
- sudo ufw allow 5000
次に、以下を実行して、Flaskアプリケーションをテストできます。
- python myproject.py
このサーバーセットアップを本番環境で使用しないように通知する役立つ警告を含む、次のような出力が表示されます。
Output * Serving Flask app 'myproject' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://your_server_ip:5000/ (Press CTRL+C to quit)
サーバーのIPアドレスにアクセスしてから :5000
Webブラウザで:
http://your_server_ip:5000
次のようなものを受け取るはずです。
終了したら、 CTRL + C
ターミナルウィンドウでFlask開発サーバーを停止します。
WSGIエントリポイントの作成
次に、アプリケーションのエントリポイントとして機能するファイルを作成します。 これにより、Gunicornサーバーにアプリケーションとの対話方法が通知されます。
お好みのテキストエディタを使用して新しいファイルを作成し、名前を付けます。 ここでは、ファイルを呼び出します wsgi.py
:
- nano ~/myproject/wsgi.py
このファイルで、アプリケーションからFlaskインスタンスをインポートして、実行します。
from myproject import app
if __name__ == "__main__":
app.run()
終了したら、ファイルを保存して閉じます。
ステップ4—Gunicornの設定
これで、アプリケーションはエントリポイントが確立された状態で作成され、Gunicornの設定に進むことができます。
ただし、最初に、適切なディレクトリに移動します。
- cd ~/myproject
次に、エントリポイントの名前を渡すことで、Gunicornがアプリケーションを正しく提供できることを確認できます。 これは、モジュールの名前として作成されます(マイナス .py
拡張機能)に加えて、アプリケーション内の呼び出し可能オブジェクトの名前。 私たちの場合、これは次のように書かれています wsgi:app
.
また、公開されているインターフェイスでアプリケーションが起動するように、バインドするインターフェイスとポートを指定します。
- gunicorn --bind 0.0.0.0:5000 wsgi:app
次のような出力が表示されます。
Output[2021-11-19 23:07:57 +0000] [8760] [INFO] Starting gunicorn 20.1.0
[2021-11-19 23:07:57 +0000] [8760] [INFO] Listening at: http://0.0.0.0:5000 (8760)
[2021-11-19 23:07:57 +0000] [8760] [INFO] Using worker: sync
[2021-11-19 23:07:57 +0000] [8763] [INFO] Booting worker with pid: 8763
[2021-11-19 23:08:11 +0000] [8760] [INFO] Handling signal: int
[2021-11-19 23:08:11 +0000] [8760] [INFO] Shutting down: Master
でサーバーのIPアドレスにアクセスします :5000
Webブラウザの最後に再び追加されます:
http://your_server_ip:5000
アプリケーションの出力は、以下を生成します。
正常に機能していることを確認したら、を押します CTRL + C
ターミナルウィンドウで。
これで仮想環境が完成したので、それを非アクティブ化します。
- deactivate
すべてのPythonコマンドは、システムのPython環境を再び使用するようになります。
次に、systemdサービスユニットファイルを作成します。 systemdユニットファイルを作成すると、Ubuntuのinitシステムが自動的にGunicornを起動し、サーバーが起動するたびにFlaskアプリケーションを提供できるようになります。
で終わるユニットファイルを作成します .service
以内 /etc/systemd/system
開始するディレクトリ:
- sudo nano /etc/systemd/system/myproject.service
内部では、 [Unit]
セクション。メタデータと依存関係を指定するために使用されます。 ここにサービスの説明を追加し、ネットワークターゲットに到達した後にのみこれを開始するようにinitシステムに指示します。
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
次に、 [Service]
セクション。 これにより、プロセスを実行するユーザーとグループが指定されます。 プロセスは関連するすべてのファイルを所有しているため、プロセスの通常のユーザーアカウントの所有権を提供します。 また、 www-data グループにグループの所有権を付与して、NginxがGunicornプロセスと通信できるようにします。 ここでのユーザー名を自分のユーザー名に置き換えることを忘れないでください。
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
次に、作業ディレクトリをマップし、 PATH
プロセスの実行可能ファイルが仮想環境内にあることをinitシステムが認識できるようにするための環境変数。 また、サービスを開始するコマンドを指定してください。 このコマンドは次のことを行います。
- 3つのワーカープロセスを開始します(ただし、必要に応じてこれを調整する必要があります)
- Unixソケットファイルを作成してバインドし、
myproject.sock
、プロジェクトディレクトリ内。 - のumask値を設定します
007
他のアクセスを制限しながら、所有者とグループにアクセスを許可するためにソケットファイルが作成されるようにします - WSGIエントリポイントのファイル名と、そのファイル内で呼び出し可能なPythonを指定します(
wsgi:app
)
Systemdでは、仮想環境内にインストールされているGunicorn実行可能ファイルへのフルパスを指定する必要があります。
ユーザー名とプロジェクトパスを独自の情報に置き換えることを忘れないでください。
[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]
セクション。 これにより、起動時にサービスを開始できるようにした場合に、このサービスを何にリンクするかがsystemdに通知されます。 通常のマルチユーザーシステムが稼働しているときにこのサービスを開始する必要があります。
[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
ステータスを確認します。
- sudo systemctl status myproject
次のような出力を受け取るはずです。
Output● myproject.service - Gunicorn instance to serve myproject
Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset
Active: active (running) since Fri 2021-11-19 23:08:44 UTC; 6s ago
Main PID: 8770 (gunicorn)
Tasks: 4 (limit: 1151)
CGroup: /system.slice/myproject.service
├─9291 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9309 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9310 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
└─9311 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
…
エラーが発生した場合は、チュートリアルを続行する前に必ず解決してください。
ステップ5—リクエストをプロキシするためのNginxの設定
これで、Gunicornアプリケーションサーバーが稼働し、プロジェクトディレクトリのソケットファイルに対するリクエストを待機しているはずです。 次に、構成ファイルにいくつかの小さな追加を行うことにより、そのソケットにWeb要求を渡すようにNginxを構成します。
Nginxで新しいサーバーブロック構成ファイルを作成することから始めます sites-available
ディレクトリ。 これを呼びます myproject
ガイドの残りの部分との一貫性を保つために:
- sudo nano /etc/nginx/sites-available/myproject
サーバーブロックを開き、Nginxにデフォルトポートでリッスンするように指示します 80
. また、サーバーのドメイン名のリクエストにこのブロックを使用するように指示します。
server {
listen 80;
server_name your_domain www.your_domain;
}
次に、すべてのリクエストに一致するロケーションブロックを追加します。 このブロック内に、 proxy_params
設定する必要のあるいくつかの一般的なプロキシパラメータを指定するファイル。 次に、を使用して定義したソケットにリクエストを渡します。 proxy_pass
指令:
server {
listen 80;
server_name your_domain www.your_domain;
location / {
include proxy_params;
proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
}
終了したら、ファイルを保存して閉じます。
作成したNginxサーバーブロック構成を有効にするには、ファイルをにリンクします sites-enabled
ディレクトリ。 これを行うには、 ln
コマンドと -s
ハードリンクではなく、シンボリックリンクまたはソフトリンクを作成するためのフラグ:
- sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
そのディレクトリ内のリンクを使用して、構文エラーをテストできます。
- sudo nginx -t
これが問題を示さずに戻った場合は、Nginxプロセスを再起動して、新しい構成を読み取ります。
- sudo systemctl restart nginx
最後に、ファイアウォールを再度調整します。 ポート経由でアクセスする必要がなくなったため 5000
、そのルールを削除します。
- sudo ufw delete allow 5000
次に、Nginxサーバーへのフルアクセスを許可します。
- sudo ufw allow 'Nginx Full'
これで、Webブラウザでサーバーのドメイン名に移動できるようになります。
http://your_domain
アプリケーションの出力がブラウザに表示されます。
エラーが発生した場合は、以下を確認してください。
sudo less /var/log/nginx/error.log
:Nginxエラーログをチェックします。sudo less /var/log/nginx/access.log
:Nginxアクセスログをチェックします。sudo journalctl -u nginx
:Nginxプロセスログをチェックします。sudo journalctl -u myproject
:FlaskアプリのGunicornログを確認します。
ステップ6—アプリケーションの保護
サーバーへのトラフィックを安全に保つには、ドメインのSSL証明書を取得する必要があります。 これを行うには、 Let’s Encrypt から無料の証明書を取得する、自己署名証明書を生成する、別のプロバイダーから証明書を購入するなど、複数の方法があります。 Nginxは、 Ubuntu18.04でNginxの自己署名SSL証明書を作成する方法のステップ2から6に従って使用します。 便宜上、オプション1を使用します。
まず、を使用してCertbotをインストールします snap
:
- sudo snap install --classic certbot
出力には、Certbotの現在のバージョンが表示され、インストールが成功したことが示されます。
Outputcertbot 1.21.0 from Certbot Project (certbot-eff✓) installed
次に、新しくインストールされたものへのシンボリックリンクを作成します /snap/bin/certbot
から実行可能 /usr/bin/
ディレクトリ。 これにより、 certbot
コマンドはサーバー上で正しく実行できます。
- sudo ln -s /snap/bin/certbot /usr/bin/certbot
Certbotは、プラグインを介してSSL証明書を取得するためのさまざまな方法を提供します。 Nginxプラグインは、Nginxの再構成と、必要に応じて構成の再読み込みを処理します。 このプラグインを使用するには、次のように入力します。
- sudo certbot --nginx -d your_domain -d www.your_domain
これは実行されます certbot
とともに --nginx
プラグイン、使用 -d
証明書を有効にする名前を指定します。
初めてのランニングの場合 certbot
、メールアドレスを入力して利用規約に同意するよう求められます。 そうした後、 certbot
Let’s Encryptサーバーと通信して、ドメインの証明書を要求します。 成功すると、次の出力が表示されます。
OutputSuccessfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/jeanellehorcasitasphd.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/jeanellehorcasitasphd.com/privkey.pem
This certificate expires on 2022-03-03.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate foryour_domain to /etc/nginx/sites-enabled/myproject
Successfully deployed certificate for your_domain to /etc/nginx/sites-enabled/myproject
Congratulations! You have successfully enabled HTTPS on https://your_domain and https://your_domain
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
前提条件でNginxのインストール手順に従った場合、冗長なHTTPプロファイルの許容量は不要になります。
- sudo ufw delete allow 'Nginx HTTP'
構成を確認するには、を使用してもう一度ドメインに移動します https://
:
https://your_domain
サイトが保護されていることを示すブラウザのセキュリティインジケータとともに、アプリケーションの出力をもう一度受け取る必要があります。
結論
このガイドでは、Python仮想環境内で基本的なFlaskアプリケーションを作成して保護しました。 WSGI対応のアプリケーションサーバーがWSGIエントリポイントとインターフェイスできるようにWSGIエントリポイントを作成し、この機能を提供するようにGunicornアプリケーションサーバーを構成しました。 その後、起動時にアプリケーションサーバーを自動的に起動するsystemdサービスファイルを作成しました。 また、Let’s Encryptを使用して、外部リクエストを中継するためにWebクライアントトラフィックをアプリケーションサーバーに渡し、サーバーへのトラフィックを保護するNginxサーバーブロックを作成しました。
Flaskは、構造や設計をあまり制限することなく、アプリケーションに機能を提供することを目的とした非常に柔軟なフレームワークです。 このガイドで説明されている一般的なスタックを使用して、設計したフラスコアプリケーションを提供できます。