序章

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

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • Ubuntu 18.04がインストールされ、sudo権限を持つ非rootユーザーであり、ファイアウォールが有効になっているサーバー。 ガイダンスについては、初期サーバーセットアップガイドに従ってください。

  • Ubuntu 18.04にNginxをインストールする方法のステップ1と2に従って、Nginxをインストールしました。

  • サーバーを指すように構成されたドメイン名。 Namecheap で購入するか、Freenomで無料で入手できます。 ドメインとDNSに関する関連するドキュメントに従うことで、ドメインをDigitalOceanにポイントする方法を学ぶことができます。 必ず次のDNSレコードを作成してください。

    • サーバーのパブリックIPアドレスを指すyour_domainのAレコード。
    • サーバーのパブリックIPアドレスを指すwww.your_domainのAレコード。
  • GunicornサーバーがFlaskアプリケーションとの通信に使用するWSGI仕様に精通していること。 このディスカッションでは、WSGIについて詳しく説明します。

ステップ1—Ubuntuリポジトリからコンポーネントをインストールする

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

まず、ローカルパッケージを更新します。

  1. sudo apt update

次に、Python環境を構築できるようにするパッケージをインストールします。 これらには、python3-pipに加えて、堅牢なプログラミング環境に必要ないくつかのパッケージと開発ツールが含まれます。

  1. sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

これらのパッケージを配置したら、プロジェクトの仮想環境の作成に進みます。

ステップ2—Python仮想環境を作成する

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

python3-venvパッケージをインストールすることから始めます。これにより、venvモジュールがインストールされます。

  1. sudo apt install python3-venv

次に、Flaskプロジェクトの親ディレクトリを作成します。

  1. mkdir ~/myproject

次に、ディレクトリを作成した後、ディレクトリに移動します。

  1. cd ~/myproject

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

  1. python3.6 -m venv myprojectenv

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

仮想環境内にアプリケーションをインストールする前に、以下を実行してアプリケーションをアクティブ化する必要があります。

  1. source myprojectenv/bin/activate

プロンプトが変わり、仮想環境内で操作していることを示します。 次のようになります。

(myprojectenv)\ssammy@host:~/myproject$

ステップ3—Flaskアプリケーションのセットアップ

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

まず、pipのローカルインスタンスを使用してwheelをインストールし、ホイールアーカイブがない場合でもパッケージがインストールされるようにします。

  1. pip install wheel

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

次に、FlaskとGunicornをインストールします。

  1. pip install gunicorn flask

Flaskを使用できるようになったので、次のステップで基本的なアプリケーションを作成できます。

サンプルアプリケーションの作成

Flaskはマイクロフレームワークであるため、よりフル機能のフレームワークに含まれる可能性のあるツールの多くは含まれていません。 Flaskは主に、Webアプリケーションの初期化を支援するためにプロジェクトにインポートできるモジュールとして存在します。

アプリケーションはもっと複雑かもしれませんが、myproject.pyという単一のファイルにFlaskアプリケーションを作成します。 お好みのテキストエディタを使用してこのファイルを作成します。 ここではnanoを使用します。

  1. nano ~/myproject/myproject.py

アプリケーションコードはこのファイルに存在します。 Flaskをインポートし、Flaskオブジェクトをインスタンス化します。 これを使用して、特定のルートが要求されたときに実行する必要がある関数を定義できます。

〜/ myproject / myproject.py
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 + XYENTERの順に押すとこれを行うことができます。

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

  1. sudo ufw allow 5000

次に、以下を実行して、Flaskアプリケーションをテストできます。

  1. 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)

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

http://your_server_ip:5000

次のようなものを受け取るはずです。

Flask sample app

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

WSGIエントリポイントの作成

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

お好みのテキストエディタを使用して新しいファイルを作成し、名前を付けます。 ここでは、ファイルをwsgi.pyと呼びます。

  1. nano ~/myproject/wsgi.py

このファイルで、アプリケーションからFlaskインスタンスをインポートして、実行します。

〜/ myproject / wsgi.py
from myproject import app

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

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

ステップ4—Gunicornの設定

これで、アプリケーションはエントリポイントが確立された状態で作成され、Gunicornの設定に進むことができます。

ただし、最初に、適切なディレクトリに移動します。

  1. cd ~/myproject

次に、エントリポイントの名前を渡すことで、Gunicornがアプリケーションを正しく提供できることを確認できます。 これは、モジュールの名前(.py拡張子を除く)と、アプリケーション内の呼び出し可能オブジェクトの名前として構成されます。 この場合、これはwsgi:appと表記されます。

また、公開されているインターフェイスでアプリケーションが起動するように、バインドするインターフェイスとポートを指定します。

  1. 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

Webブラウザの末尾に:5000を追加して、サーバーのIPアドレスに再度アクセスします。

http://your_server_ip:5000

アプリケーションの出力は、以下を生成します。

Flask sample app

正常に動作していることを確認したら、ターミナルウィンドウでCTRL + Cを押します。

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

  1. deactivate

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

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

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

  1. 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]セクションを作成します。 これにより、プロセスを実行するユーザーとグループが指定されます。 プロセスは関連するすべてのファイルを所有しているため、プロセスの通常のユーザーアカウントの所有権を提供します。 また、 www-data グループにグループの所有権を付与して、NginxがGunicornプロセスと通信できるようにします。 ここでのユーザー名を自分のユーザー名に置き換えることを忘れないでください。

/etc/systemd/system/myproject.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data

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

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

Systemdでは、仮想環境内にインストールされているGunicorn実行可能ファイルへのフルパスを指定する必要があります。

ユーザー名とプロジェクトパスを独自の情報に置き換えることを忘れないでください。

/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]セクションを追加します。 これにより、起動時にサービスを開始できるようにした場合に、このサービスを何にリンクするかが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サービスを開始します。

  1. sudo systemctl start myproject

次に、起動時に開始するように有効にします。

  1. sudo systemctl enable myproject

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

  1. 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と呼びます。

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

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

/ etc / nginx / sites-available / myproject
server {
    listen 80;
    server_name your_domain www.your_domain;
}

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

/ etc / nginx / sites-available / myproject
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フラグを実行して、ハードリンクではなく、シンボリックリンクまたはソフトリンクを作成します。

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

そのディレクトリ内のリンクを使用して、構文エラーをテストできます。

  1. sudo nginx -t

これが問題を示さずに戻った場合は、Nginxプロセスを再起動して、新しい構成を読み取ります。

  1. sudo systemctl restart nginx

最後に、ファイアウォールを再度調整します。 ポート5000を介してアクセスする必要がなくなったため、次のルールを削除します。

  1. sudo ufw delete allow 5000

次に、Nginxサーバーへのフルアクセスを許可します。

  1. sudo ufw allow 'Nginx Full'

これで、Webブラウザでサーバーのドメイン名に移動できるようになります。

http://your_domain

アプリケーションの出力がブラウザに表示されます。

Flask sample app

エラーが発生した場合は、以下を確認してください。

  • 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を使用します。

まず、snapを使用してCertbotをインストールします。

  1. sudo snap install --classic certbot

出力には、Certbotの現在のバージョンが表示され、インストールが成功したことが示されます。

Output
certbot 1.21.0 from Certbot Project (certbot-eff✓) installed

次に、/usr/bin/ディレクトリから新しくインストールされた/snap/bin/certbot実行可能ファイルへのシンボリックリンクを作成します。 これにより、certbotコマンドをサーバーで正しく実行できるようになります。

  1. sudo ln -s /snap/bin/certbot /usr/bin/certbot

Certbotは、プラグインを介してSSL証明書を取得するためのさまざまな方法を提供します。 Nginxプラグインは、Nginxの再構成と、必要に応じて構成の再読み込みを処理します。 このプラグインを使用するには、次のように入力します。

  1. sudo certbot --nginx -d your_domain -d www.your_domain

これは、--nginxプラグインでcertbotを実行し、-dを使用して、証明書を有効にする名前を指定します。

certbotを初めて実行する場合は、メールアドレスを入力して利用規約に同意するよう求められます。 その後、certbotはLet’sEncryptサーバーと通信して、ドメインの証明書を要求します。 成功すると、次の出力が表示されます。

Output
Successfully 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プロファイルの許容量は不要になります。

  1. sudo ufw delete allow 'Nginx HTTP'

構成を確認するには、https://を使用して、もう一度ドメインに移動します。

https://your_domain

サイトが保護されていることを示すブラウザのセキュリティインジケータとともに、アプリケーションの出力をもう一度受け取る必要があります。

結論

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

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