Ubuntu 22.04において、uWSGIとNginxを使用してFlaskアプリケーションを提供する方法。

以下の内容を日本語で自然な言い回しに言い換えてください。一つの選択肢で構いません。

イントロダクション

このガイドでは、Ubuntu 22.04上でFlaskマイクロフレームワークを使用してPythonアプリケーションを構築します。この記事の大部分は、uWSGIアプリケーションサーバーのセットアップ方法やアプリケーションの起動方法、Nginxのフロントエンド逆プロキシとしての設定方法について説明します。

前提条件

このガイドを始める前に、次を準備しておいてください:

  • A server with Ubuntu 22.04 installed and a non-root user with sudo privileges. Follow our initial server setup guide for guidance.
  • Nginx installed, following Steps 1 through 3 of How To Install Nginx on Ubuntu 22.04.
  • A domain name configured to point to your server. You can purchase one on Namecheap or get one for free on Freenom. You can learn how to point domains to Silicon Cloud by following the relevant documentation on domains and DNS. This tutorial assumes you’ve created the following DNS records:An A record with your_domain pointing to your server’s public IP address.
    An A record with www.your_domain pointing to your server’s public IP address.

さらに、このガイドで設定するアプリケーションサーバーであるuWSGIと、WSGI仕様について一部知識を身につけると役に立つかもしれません。この定義や概念の議論では、それらについて詳しく説明しています。

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

最初のステップは、Ubuntuのリポジトリから必要なすべてのパーツをインストールすることです。 インストールする必要のあるパッケージには、Pythonパッケージマネージャであるpipが含まれており、Pythonコンポーネントを管理するために使用します。 また、uWSGIをビルドするために必要な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仮想環境の作成

Pythonの仮想環境とは、特定のPythonバージョンとそのプロジェクトに必要なPythonモジュールが含まれる自己完結型のプロジェクトディレクトリのことです。これは、各アプリケーションの依存関係を個別に管理することにより、同じシステム上の他のアプリケーションとの間を分離するために役立ちます。この手順では、Flaskアプリケーションを実行するためのPythonの仮想環境をセットアップします。

python3-venvパッケージをインストールして、venvモジュールもインストールしましょう。

  1. sudo apt install python3-venv

 

次に、Flaskプロジェクトの親ディレクトリを作成してください。

  1. mkdir ~/myproject

 

作成したディレクトリに移動してください。 (Sakusei shita direkutori ni idō shite kudasai.)

  1. cd ~/myproject

 

以下のコマンドを入力して、FlaskプロジェクトのPythonの要件を保存するための仮想環境を作成してください。

  1. python3.10 -m venv myprojectenv

 

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

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

  1. source myprojectenv/bin/activate

 

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

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

仮想環境に入っているので、FlaskとuWSGIをインストールし、アプリケーションのデザインに取り掛かることができます。

最初に、ホイールアーカイブが不足していてもパッケージがインストールされるよう、pipのローカルインスタンスにホイールをインストールしてください。

  1. pip install wheel

 

Note

注意:Pythonのどのバージョンを使っているかに関係なく、仮想環境がアクティブ化されている場合は、pipコマンド(pip3ではなく)を使用する必要があります。

次に、FlaskとuWSGIをインストールしてください。

  1. pip install uwsgi flask

 

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

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

あなたのアプリケーションはより複雑かもしれませんが、この例ではFlaskアプリを1つのファイル、myproject.pyとして作成します。nanoまたはお気に入りのテキストエディタでmyproject.pyを開いてください。

  1. nano ~/myproject/myproject.py

 

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

~/私のプロジェクト/私のプロジェクト.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 + X、Y、そしてENTERキーを押して保存してください。

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

  1. sudo ufw allow 5000

 

今、Flaskアプリをテストするためには、入力してください。

  1. python myproject.py

 

次のような出力を見ることがあります。このサーバー設定を本番環境では使用しないようにとの注意書きが表示されます。

Output

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Serving Flask app ‘myproject’ * Debug mode: off * Running on all addresses (0.0.0.0) WARNING: This is a development server. Do not use it in a production deployment. * Running on http://127.0.0.1:5000 * Running on http://your_server:5000 (Press CTRL+C to quit)

ウェブブラウザで、サーバーのIPアドレスに続いて「:5000」と入力してアクセスしてください。

http://your_server_ip:5000

こんな感じのものが見えるでしょう。

Flask sample app

Flaskの開発サーバーを停止するには、ターミナルウィンドウでCTRL + Cを押してください。

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

次に、アプリケーションのエントリーポイントとなるファイルを作成してください。このファイルは、あなたのuWSGIサーバーがそれとやり取りする方法を指示します。

ファイル名をwsgi.pyと呼んでください。

  1. nano ~/myproject/wsgi.py

 

このファイルでは、アプリケーションからFlaskのインスタンスをインポートし、それを実行してください。

「~/myproject/wsgi.py」を日本語で言い換えると、以下のようになります:
「~/myproject/wsgi.py」
from myproject import app

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

作業が終わったら、ファイルを保存して閉じてください。

ステップ4 — uWSGIの設定

あなたのアプリケーションは、エントリーポイントが設定されて書かれています。次はuWSGIの設定に進むことができます。

「uWSGIがアプリケーションを提供できるかテストしてみる」

最初のステップとして、uWSGIが正しくアプリケーションを提供できるかを確認するために、エントリーポイントの名前を渡してテストしてください。これは、モジュールの名前(.py拡張子を除く)とアプリケーション内の呼び出し可能なオブジェクトの名前から構成されます。このチュートリアルの文脈では、エントリーポイントの名前はwsgi:appです。

また、以前に開いたポート番号(5000番)を使用し、公開可能なインターフェースでソケットを開始するように指定し、uwsgiバイナリプロトコルの代わりにHTTPを使用するプロトコルを指定してください。

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

 

再びウェブブラウザで、サーバーのIPアドレスの末尾に「:5000」を付けてアクセスしてください。

http://your_server_ip:5000

あなたは再びアプリケーションの出力を見ることができます。

Flask sample app

動作が正常に確認できたら、ターミナルウィンドウでCTRL + Cを押してください。

あなたは今、仮想環境を終了することができます。

  1. deactivate

 

今後、Pythonのコマンドは再びシステムのPython環境を使用します。

uWSGIの設定ファイルを作成する

uWSGIがアプリケーションを提供できることをテストしましたが、長期利用にはさらに堅牢なものが必要です。これに適したuWSGI設定ファイルを作成できます。

あなたのプロジェクトディレクトリにそのファイルを配置し、「myproject.ini」と呼んでください。

  1. nano ~/myproject/myproject.ini

 

ファイルの中で、[uwsgi]ヘッダーで開始し、uWSGIが設定を適用することを知るようにします。その下に、拡張子を除いた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ソケットを使用する方が速く、安全です。ソケットをmyproject.sockと呼び、このディレクトリに配置してください。

次に、ソケットの権限を変更します。後でNginxグループがuWSGIプロセスの所有権を持つことになるので、ソケットのグループ所有者が情報を読み取り、書き込みできるように確認する必要があります。また、vacuumオプションを追加し、trueに設定します。これにより、プロセスが停止した際にソケットをクリーンアップすることができます。

~/マイプロジェクト/マイプロジェクト.ini
[uwsgi]
module = wsgi:app

master = true
processes = 5

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

最後に行うべきことは、die-on-termオプションを設定することです。これにより、initシステムとuWSGIが各プロセスシグナルについて同じ前提を持つことができます。これを設定することで、2つのシステムコンポーネントが一致し、期待される動作が実装されます。

私のプロジェクトのプロジェクト.iniファイル
[uwsgi]
module = wsgi:app

master = true
processes = 5

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

die-on-term = true

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

作業が終了したら、ファイルを保存して閉じてください。

それにより、uWSGIはシステムに設定されます。Flaskアプリケーションの管理方法により柔軟性を持たせるため、それをsystemdサービスとして設定することができます。

Step 5 — systemdのユニットファイルを作成する

Systemdは、システムサービスの管理に高速かつ柔軟なinitモデルを提供するツールのスイートです。systemdユニットファイルを作成すると、Ubuntuのinitシステムは、サーバーブート時に自動的にuWSGIを起動してFlaskアプリケーションを提供します。

「/etc/systemd/system」ディレクトリ内に拡張子が「.service」で終わるユニットファイルを作成して、始めましょう。

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

 

インサイドでは、メタデータと依存関係を指定するために使用される「[Unit]」セクションを開始します。その後、ここにサービスの説明を記載し、ネットワーキングターゲットに到達後にのみ、イニシャライズシステムに起動されるよう指示してください。

私のプロジェクトのサービスは、/etc/systemd/system/myproject.serviceにあります。
[Unit]
Description=uWSGI instance to serve myproject
After=network.target

次に、[Service] セクションを作成します。ここでは、プロセスを実行するユーザーとグループを指定します。関連するファイルをすべて所有するため、通常のユーザーアカウントにプロセスの所有権を与えます。次に、NginxがuWSGIプロセスと通信できるように、www-dataグループにグループ所有権を与えます(これはUbuntuでNginxがデフォルトで実行されるグループです)。ここではご自身のユーザー名に置き換えることを忘れないでください。

私のプロジェクトのサービスは、/etc/systemd/system/myproject.serviceです。
[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=sammy
Group=www-data

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

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

以下のコマンドを日本語で自然に言い換えてください。一つのオプションで構いません:
「/etc/systemd/system/myproject.service」
[Unit]
Description=uWSGI 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/uwsgi --ini myproject.ini

最終的に、[Install] セクションを追加してください。これにより、システム起動時にこのサービスを有効にする場合に、systemdがどのようにリンクするかが指定されます。この場合、通常のマルチユーザーシステムが起動している時にサービスを開始するように設定してください。

以下の文を日本語でパラフレーズしてください、ただし1つのオプションで十分です:
「/etc/systemd/system/myproject.service」
[Unit]
Description=uWSGI 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/uwsgi --ini myproject.ini

[Install]
WantedBy=multi-user.target

それにより、あなたのsystemdサービスファイルは完成です。今保存して閉じてください。

uWSGIサービスを開始する前に、Ubuntu 22.04以降ではNginxのwww-dataユーザーがデフォルトではホームディレクトリ内のファイルを読むことができないため、アクセス権の変更が必要です。これにより、ホームディレクトリ内のウェブアプリケーションの提供が妨げられる可能性があります。簡単な修正方法は、chgrpを使用してホームディレクトリに関連付けられたグループを変更することです。

  1. sudo chgrp www-data /home/sammy

 

これにより、Nginxはソケットファイルにアクセスするために必要な、あなたのホームディレクトリの内容を見ることができます。しかし、あなたのホームディレクトリのファイルはウェブ上に公開されることはありません。

作成したuWSGIサービスを開始することができます。

  1. sudo systemctl start myproject

 

それから、起動時に自動で起動するように設定してください。

  1. sudo systemctl enable myproject

 

状況を確認してください。

  1. sudo systemctl status myproject

 

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

Output

● myproject.service – uWSGI instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: ena> Active: active (running) since Fri 2022-08-05 17:22:05 UTC; 6s ago Main PID: 4953 (uwsgi) Tasks: 6 (limit: 2327) Memory: 20.9M CPU: 241ms CGroup: /system.slice/myproject.service ├─4953 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini ├─4954 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini ├─4955 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini ├─4956 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini ├─4957 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini └─4958 /home/sammy/myproject/myprojectenv/bin/uwsgi –ini myproject.ini

もしエラーがあった場合は、チュートリアルを続ける前に必ず修正してください。そうでなければ、Nginxの設定を行い、リクエストをmyproject.sockソケットに渡すことができます。

ステップ6 – Nginxのリクエストをプロキシに設定する

あなたのuWSGIアプリケーションサーバーは現在稼働中であり、プロジェクトディレクトリのソケットファイルでリクエストを待っています。このステップでは、Nginxを設定してuwsgiプロトコルを使用してWebリクエストをそのソケットに渡すようにします。

最初に、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;
}

次に、すべてのリクエストにマッチするロケーションブロックを追加します。このブロック内には、設定する必要のある一般的なuWSGIパラメータを指定するuwsgi_paramsファイルを含めます。その後、uwsgi_passディレクティブを使用して、定義したソケットにリクエストを渡します。

私のプロジェクトの場所は、/etc/nginx/sites-available/myprojectです。
server {
    listen 80;
    server_name your_domain www.your_domain;

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

作業が終わったら、ファイルを保存して閉じてください。

作成したNginxサーバーブロックの設定を有効にするために、ファイルをsites-enabledディレクトリにリンクしてください。

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

 

Nginxをインストールした際、プロセスは自動的にサーバーブロック設定ファイルであるdefaultをsites-availableディレクトリに作成し、そのファイルとsites-enabledディレクトリの間にシンボリックリンクを作成しました。このシンボリックリンクをそのままにしておくと、デフォルト設定によりサイトが読み込まれなくなります。以下のコマンドを使ってリンクを削除することができます。

  1. sudo unlink /etc/nginx/sites-enabled/default

 

その後、次のように入力して構文エラーをテストすることができます。

  1. sudo nginx -t

 

もし何も問題がないまま戻ってきた場合、新しい設定を読み込むためにNginxプロセスを再起動してください。

  1. sudo systemctl restart nginx

 

最終的に、ファイアウォールを再度調整してください。ポート5000を介したアクセスはもう必要ないので、そのルールを削除してください。そして、Nginxサーバへのアクセスを許可してください。

  1. sudo ufw delete allow 5000
  2. sudo ufw allow ‘Nginx Full’

 

今後、ウェブブラウザでサーバーのドメイン名にアクセスできるようになります。

http://your_domain

あなたはアプリケーションの出力を見ることができます。

Flask sample app

もし何かエラーが出たら、以下の点をチェックしてみてください。

  • sudo less /var/log/nginx/error.log: checks the Nginx error logs.
  • sudo less /var/log/nginx/access.log: checks the Nginx access logs.
  • sudo journalctl -u nginx: checks the Nginx process logs.
  • sudo journalctl -u myproject: checks your Flask app’s uWSGI logs.

ステップ7 — アプリケーションのセキュリティ確保

サーバーへのトラフィックの安全性を確保するために、ドメインのためにSSL証明書を取得してください。このためには、いくつかの方法があります。Let’s Encryptから無料の証明書を取得する方法、自己署名証明書を生成する方法、または商業プロバイダーから購入する方法があります。このチュートリアルでは、時間の短縮のために、Let’s Encryptから無料の証明書を取得する方法について説明します。

最初に、aptを使用してCertbotとそのNginxプラグインをインストールしてください。

  1. sudo apt install certbot python3-certbot-nginx

 

Certbotは、プラグインを通じて様々な方法でSSL証明書を取得することができます。Nginxプラグインは、必要な場合にNginxの再設定と構成のリロードを自動で行います。このプラグインを使用するには、以下を入力してください。

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

 

以下のようにネイティブな日本語に言い換えます(一つのオプションのみ):
このコマンドは、–nginxプラグインを使用してcertbotを実行し、-dオプションを使って、証明書が有効であると希望する名前を指定します。

もしサーバーでcertbotを初めて実行する場合、メールアドレスの入力と利用規約への同意を求められます。それを行った後、certbotはLet’s Encryptサーバーと通信し、ドメインの所有権を確認するためのチャレンジを実行します。

設定が更新され、Nginxは新しい設定を読み込むためにリロードされます。certbotは、プロセスが成功したことと証明書が保存されている場所を示すメッセージで完了します。

Output

Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem This certificate expires on 2022-11-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 for your_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://www.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エントリーポイントを作成し、uWSGIアプリケーションサーバーを構成しました。その後、システム起動時に自動的にアプリケーションサーバーを起動するためのsystemdサービスファイルも作成しました。また、外部リクエストを中継し、サーバーへのトラフィックをLet’s Encryptでセキュリティ強化するために、Nginxのサーバーブロックも作成しました。

Flaskは、アプリケーションの機能性を制限せずに、柔軟性のあるフレームワークです。このガイドで説明されているスタックを使用して、設計したFlaskアプリケーションを提供することができます。

コメントを残す 0

Your email address will not be published. Required fields are marked *