序章

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

前提条件

このガイドを開始する前に、次のものが必要です。

  • Ubuntu 20.04がインストールされ、sudo権限を持つ非rootユーザーのサーバー。 ガイダンスについては、初期サーバーセットアップガイドに従ってください。

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

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

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

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

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

まず、ローカルパッケージインデックスを更新し、Python環境の構築を可能にするパッケージをインストールしましょう。 これらには以下が含まれます python3-pip、堅牢なプログラミング環境に必要ないくつかのパッケージと開発ツールとともに:

  1. sudo apt update
  2. 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
  2. cd ~/myproject

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

  1. python3 -m venv myprojectenv

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

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

  1. source myprojectenv/bin/activate

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

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

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

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

  1. pip install wheel

ノート

使用しているPythonのバージョンに関係なく、仮想環境がアクティブ化されている場合は、 pip コマンド(ではない pip3).

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

  1. pip install gunicorn flask

サンプルアプリの作成

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

アプリケーションはもっと複雑かもしれませんが、Flaskアプリを1つのファイルに作成します。 myproject.py:

  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')

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

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

  1. sudo ufw allow 5000

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

  1. python myproject.py

このサーバー設定を本番環境で使用しないように注意を促す便利な警告を含む、次のような出力が表示されます。

Output
* Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

サーバーのIPアドレスにアクセスしてから :5000 Webブラウザで:

http://your_server_ip:5000

次のように表示されます。

終了したら、 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の構成に進むことができます。

先に進む前に、Gunicornがアプリケーションを正しく提供できることを確認する必要があります。

これを行うには、エントリポイントの名前を渡すだけです。 これは、モジュールの名前として作成されます(マイナス .py 拡張機能)に加えて、アプリケーション内の呼び出し可能オブジェクトの名前。 私たちの場合、これは wsgi:app.

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

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

次のような出力が表示されます。

Output
[2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

でサーバーのIPアドレスにアクセスします :5000 Webブラウザの最後に再び追加されます:

http://your_server_ip:5000

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

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

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

  1. deactivate

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

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

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

  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、プロジェクトディレクトリ内。 umask値を 007 他のアクセスを制限しながら、所有者とグループへのアクセスを許可するソケットファイルが作成されるようにします
  • 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
  2. 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: enabled) Active: active (running) since Wed 2020-05-20 14:15:18 UTC; 1s ago Main PID: 46430 (gunicorn) Tasks: 4 (limit: 2344) Memory: 51.3M CGroup: /system.slice/myproject.service ├─46430 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46449 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46450 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─46451 /home/sammy/myproject/myprojectenv/bin/python3 /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

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

/ 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 ディレクトリ:

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

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

  1. sudo nginx -t

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

  1. sudo systemctl restart nginx

最後に、ファイアウォールをもう一度調整しましょう。 ポート経由でアクセスする必要がなくなりました 5000、そのルールを削除できます。 次に、Nginxサーバーへのフルアクセスを許可できます。

  1. sudo ufw delete allow 5000
  2. 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は、 Ubuntu20.04でNginxの自己署名SSL証明書を作成する方法のステップ2から6に従って使用します。 便宜上、オプション1を使用します。

CertbotのNginxパッケージをでインストールします apt:

  1. sudo apt install python3-certbot-nginx

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

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

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

初めてのランニングの場合 certbot、メールアドレスを入力して利用規約に同意するよう求められます。 そうした後、 certbot Let’s Encryptサーバーと通信し、チャレンジを実行して、証明書を要求しているドメインを制御していることを確認します。

それが成功した場合、 certbot HTTPS設定をどのように構成するかを尋ねられます。

Output
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

選択してからヒット ENTER. 構成が更新され、Nginxがリロードして新しい設定を取得します。 certbot プロセスが成功し、証明書が保存されている場所を通知するメッセージで締めくくられます。

Output
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - 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サービスファイルを作成しました。 また、Webクライアントトラフィックをアプリケーションサーバーに渡し、外部要求を中継し、Let’sEncryptを使用してサーバーへのトラフィックを保護するNginxサーバーブロックを作成しました。

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