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

前書き

このガイドでは、Ubuntu 18.04でFlaskマイクロフレームワークを使用してPythonアプリケーションを構築します。 この記事の大部分は、http://uwsgi-docs.readthedocs.io/en/latest/ [uWSGIアプリケーションサーバー]をセットアップする方法と、アプリケーションを起動してhttps://www.nginxを構成する方法について説明します。 com / [Nginx]は、フロントエンドリバースプロキシとして機能します。

前提条件

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

  • Ubuntu 18.04がインストールされたサーバーと、sudo特権を持つ非rootユーザー。 ガイダンスについては、https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04 [初期サーバーセットアップガイド]に従ってください。

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

  • サーバーを指すように構成されたドメイン名。 https://namecheap.com [Namecheap]で購入するか、http://www.freenom.com/en/index.html [Freenom]で無料で入手できます。 関連するhttps://www.digitalocean.com/docs/networking/dns/ [ドメインとDNSに関するドキュメント]に従って、ドメインをDigitalOceanにポイントする方法を学習できます。 次のDNSレコードを必ず作成してください。

  • サーバーのパブリックIPアドレスを指す「++」を持つAレコード。

  • サーバーのパブリックIPアドレスを指す「+ www。+」を持つAレコード。

  • アプリケーションサーバーであるuWSGIおよびWSGI仕様に精通している。 https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14-04#definitions-and-concepts [定義と概念のこの議論は、両方の詳細に渡ります。

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

最初のステップは、Ubuntuリポジトリから必要なすべてのピースをインストールすることです。 Pythonコンポーネントを管理するために、Pythonパッケージマネージャーである `+ pip +`をインストールします。 また、uWSGIのビルドに必要なPython開発ファイルも取得します。

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

sudo apt update
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 ~/
cd ~/

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

python3.6 -m venv

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

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

source /bin/activate

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

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

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

まず、ホイールアーカイブが欠落している場合でもパッケージが確実にインストールされるように、 `+ pip `のローカルインスタンスで ` wheel +`をインストールしましょう。

pip install wheel

Note

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

pip install uwsgi flask

サンプルアプリの作成

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

あなたのアプリケーションはもっと複雑かもしれませんが、 `+ myproject.py +`と呼ばれる単一のファイルでFlaskアプリを作成します:

nano ~//.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 +`へのアクセスを許可する必要があります。

sudo ufw allow 5000

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

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

WebブラウザーでサーバーのIPアドレスの後に「:5000」を入力します。

http://:5000

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

image:https://assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Flaskサンプルアプリ]

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

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

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

ファイルを「+ wsgi.py +」と呼びましょう:

nano ~//wsgi.py

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

〜/ myproject / wsgi.py

from myproject import app

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

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

ステップ4-uWSGIの構成

これで、エントリポイントが確立されたアプリケーションが作成されました。 uWSGIの構成に進むことができます。

uWSGIサービングのテスト

uWSGIがアプリケーションを提供できることをテストしてみましょう。

これを行うには、エントリポイントの名前を渡すだけです。 これは、モジュールの名前(拡張子「+ .py 」を除く)とアプリケーション内の呼び出し可能オブジェクトの名前で構成されます。 私たちの場合、これは ` wsgi:app`です。

また、ソケットを指定して、公開されているインターフェイスとプロトコルで開始されるようにして、 `+ uwsgi `バイナリプロトコルの代わりにHTTPを使用するようにします。 以前に開いたのと同じポート番号「+5000」を使用します。

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

ウェブブラウザの末尾に「:5000」が追加されたサーバーのIPアドレスに再度アクセスします。

http://:5000

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

image:https://assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Flaskサンプルアプリ]

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

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

deactivate

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

uWSGI構成ファイルの作成

uWSGIがアプリケーションを提供できることをテストしましたが、最終的には長期的な使用に対してより堅牢なものが必要になります。 これに関連するオプションを使用して、uWSGI構成ファイルを作成できます。

そのファイルをプロジェクトディレクトリに配置して、 `+ myproject.ini +`と呼びます。

nano ~//.ini

内部では、uWSGIが設定を適用することを認識できるように、 + [uwsgi] +`ヘッダーから始めます。 2つのことを指定します:モジュール自体、拡張子を除いた `+ wsgi.py +`ファイルを参照すること、およびファイル内の呼び出し可能オブジェクト `+ app +

〜/ myproject / myproject.ini

[uwsgi]
module = wsgi:app

次に、uWSGIにマスターモードで起動し、5つのワーカープロセスを生成して実際のリクエストを処理するように指示します。

〜/ myproject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

テスト中に、ネットワークポートでuWSGIを公開しました。 ただし、実際のクライアント接続を処理するためにNginxを使用し、uWSGIにリクエストを渡します。 これらのコンポーネントは同じコンピューター上で動作しているため、Unixソケットのほうがより高速で安全です。 ソケットを「+ .sock +」と呼び、このディレクトリに配置します。

ソケットのアクセス許可も変更しましょう。 Nginxグループに、uWSGIプロセスの所有権を後で与えるため、ソケットのグループ所有者がそこから情報を読み取り、書き込みできることを確認する必要があります。 プロセスが停止したときに `+ vacuum +`オプションを追加してソケットをクリーンアップします:

〜/ myproject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

最後に行うことは、 `+ die-on-term`オプションを設定することです。 これは、initシステムとuWSGIが各プロセス信号の意味について同じ仮定を持っていることを保証するのに役立ちます。 これを設定すると、2つのシステムコンポーネントが調整され、予想される動作が実装されます。

〜/ myproject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

die-on-term = true

お気付きかもしれませんが、コマンドラインからのようにプロトコルを指定していません。 デフォルトでは、uWSGIは他のサーバーと通信するために設計された高速バイナリプロトコルである `+ uwsgi +`プロトコルを使用して話すためです。 Nginxはこのプロトコルをネイティブに話すことができるため、HTTPによる通信を強制するよりもこれを使用する方が適切です。

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

ステップ5-systemdユニットファイルの作成

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

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

sudo nano /etc/systemd/system/.service

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

/etc/systemd/system/myproject.service

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

次に、 `+ [Service] `セクションを開きます。 これにより、プロセスを実行するユーザーとグループを指定します。 関連するすべてのファイルを所有しているため、通常のユーザーアカウントにプロセスの所有権を与えましょう。 NginxがuWSGIプロセスと簡単に通信できるように、グループの所有権を「 www-data」グループに付与しましょう。 ここのユーザー名をユーザー名に置き換えてください:

/etc/systemd/system/myproject.service

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

[Service]
User=
Group=www-data

次に、作業ディレクトリをマップし、 `+ PATH`環境変数を設定して、initシステムがプロセスの実行可能ファイルが仮想環境内にあることを認識できるようにします。 サービスを開始するコマンドも指定しましょう。 Systemdでは、仮想環境内にインストールされているuWSGI実行可能ファイルへのフルパスを指定する必要があります。 プロジェクトディレクトリで作成した `+ .ini +`設定ファイルの名前を渡します。

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

/etc/systemd/system/myproject.service

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

[Service]
User=
Group=www-data
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

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

/etc/systemd/system/myproject.service

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

[Service]
User=
Group=www-data
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

[Install]
WantedBy=multi-user.target

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

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

sudo systemctl start
sudo systemctl enable

ステータスを確認しましょう:

sudo systemctl status

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

Output● myproject.service - uWSGI instance to serve myproject
  Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled)
  Active:  since Fri 2018-07-13 14:28:39 UTC; 46s ago
Main PID: 30360 (uwsgi)
   Tasks: 6 (limit: 1153)
  CGroup: /system.slice/myproject.service
          ├─30360 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
          ├─30378 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
          ├─30379 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
          ├─30380 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
          ├─30381 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
          └─30382 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

エラーが表示された場合は、チュートリアルを続行する前にエラーを解決してください。

ステップ6-リクエストをプロキシするためのNginxの設定

これで、uWSGIアプリケーションサーバーが起動して実行され、プロジェクトディレクトリのソケットファイルに対する要求を待機します。 `+ uwsgi +`プロトコルを使用してWebリクエストをそのソケットに渡すようにNginxを設定しましょう。

Nginxの `+ sites-available `ディレクトリに新しいサーバーブロック構成ファイルを作成することから始めます。 この「+」を呼び出して、残りのガイドに合わせてみましょう。

sudo nano /etc/nginx/sites-available/

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

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name  www.;
}

次に、すべてのリクエストに一致する場所ブロックを追加しましょう。 このブロック内に、設定する必要があるいくつかの一般的なuWSGIパラメーターを指定する `+ uwsgi_params `ファイルを含めます。 次に、 ` uwsgi_pass +`ディレクティブを使用して定義したソケットにリクエストを渡します。

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name  www.;

   location / {
       include uwsgi_params;
       uwsgi_pass unix:/home///.sock;
   }
}

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

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

sudo ln -s /etc/nginx/sites-available/ /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ブラウザでサーバーのドメイン名に移動できるはずです。

http://

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

image:https://assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Flaskサンプルアプリ]

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

  • + sudo less / var / log / nginx / error.log +:Nginxエラーログをチェックします。

  • + sudo less / var / log / nginx / access.log +:Nginxアクセスログをチェックします。

  • + sudo journalctl -u nginx +:Nginxプロセスログをチェックします。

  • + sudo journalctl -u +:FlaskアプリのuWSGIログを確認します。

ステップ7-アプリケーションの保護

サーバーへのトラフィックを安全に保つために、ドメインのSSL証明書を取得しましょう。 これを行うには、https://letsencrypt.org/ [Let’s Encrypt]、https://www.digitalocean.com/community/tutorials/how-to-create-a-selfから無料の証明書を取得するなど、複数の方法があります。 -signed-ssl-certificate-for-nginx-in-ubuntu-18-04 [自己署名証明書の生成]、またはhttps://www.digitalocean.com/community/tutorials/how-to-install-an- ssl-certificate-from-a-commercial-certificate-authority [別のプロバイダーから購入]および] https://www.digitalocean.com/community/tutorials/how-toのステップ2から6に従ってNginxを使用するように構成する-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-18-04#step-2-%E2%80%93-configuring-nginx-to-use-ssl [作成方法Ubuntu 18.04でのNginxの自己署名SSL証明書]。 便宜上、オプション1を使用します。

最初に、Certbot Ubuntuリポジトリを追加します。

sudo add-apt-repository ppa:certbot/certbot

受け入れるには `+ ENTER`を押す必要があります。

次に、 `+ apt +`を使用してCertbotのNginxパッケージをインストールします。

sudo apt install python-certbot-nginx

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

sudo certbot --nginx -d  -d www.

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

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

それが成功すると、 `+ certbot +`はHTTPS設定をどのように構成するかを尋ねます。

OutputPlease 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 +`は、プロセスが成功したこと、および証明書が保存されている場所を通知するメッセージで終了します。

OutputIMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
  /etc/letsencrypt/live//fullchain.pem
  Your key file has been saved at:
  /etc/letsencrypt/live//privkey.pem
  Your cert will expire on 2018-07-23. 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プロファイルの許可は不要になります。

sudo ufw delete allow 'Nginx HTTP'

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

https://

ブラウザのセキュリティインジケータとともに、アプリケーションの出力がもう一度表示され、サイトが保護されていることを示すはずです。

結論

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

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

Related