CentOS7でuWSGIとNginxを使用してWeb2pyPythonアプリケーションをデプロイする方法
序章
web2pyフレームワークは、フル機能のPythonWebアプリケーションをすばやく開発するための強力で使いやすいツールです。 web2pyを使用すると、管理用Web UIを使用して、アプリケーションを簡単に開発および管理できます。
このガイドでは、CentOS7にweb2pyアプリケーションをデプロイする方法を示します。 uWSGIアプリケーションサーバーを使用して、複数のワーカープロセスを使用してアプリケーションとインターフェイスします。 uWSGIの前で、実際のクライアント接続を処理するためにリバースプロキシ構成でNginxをセットアップします。 これは、web2pyサーバーまたはuWSGIを単独で使用するよりもはるかに堅牢なデプロイメント戦略です。
前提条件と目標
このガイドを完了するには、sudo
権限が設定されたroot以外のユーザーがいる新しいCentOS7サーバーインスタンスが必要です。 初期サーバーセットアップガイドを実行すると、これをセットアップする方法を学ぶことができます。
web2pyフレームワークをダウンロードしてテストし、デフォルトのアプリケーション環境が正しく機能することを確認します。 その後、リクエストとweb2pyPythonコード間のインターフェイスとして機能するuWSGIアプリケーションコンテナをダウンロードしてインストールします。 この前にNginxを設定して、uWSGIへのクライアント接続とプロキシリクエストを処理できるようにします。 管理者の介入の必要性を最小限に抑えるために、起動時に開始するように各コンポーネントを構成します。
web2pyフレームワークをダウンロードする
最初のステップは、実際のweb2pyフレームワークをダウンロードすることです。 これはGitHubのgit
リポジトリに保持されているため、ダウンロードするのに最適な方法はgit
自体を使用することです。
次のように入力して、デフォルトのCentOSリポジトリからgit
をダウンロードしてインストールできます。
sudo yum install git
git
がインストールされると、リポジトリをユーザーのホームディレクトリに複製できます。 アプリケーションには任意の名前を付けることができます。 この例では、簡単にするためにmyapp
という名前を使用しています。 データベース抽象化レイヤーは独自のgit
サブモジュールとして処理されるため、--recursive
フラグを追加する必要があります。
git clone --recursive https://github.com/web2py/web2py.git ~/myapp
web2pyフレームワークは、ホームディレクトリ内のmyapp
というディレクトリにダウンロードされます。
ディレクトリに移動して、デフォルトのアプリケーションをテストできます。
cd ~/myapp
管理インターフェイスはSSLで保護する必要があるため、これをテストするための簡単な自己署名証明書を作成できます。 次のように入力して、サーバーキーと証明書を作成します。
openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout myapp.key -out myapp.crt
生成する証明書の情報を入力する必要があります。 この状況で実際に重要なのは、Common Name
フィールドだけです。このフィールドは、サーバーのドメイン名またはIPアドレスを参照する必要があります。
. . . Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:server_domain_or_IP Email Address []:[email protected]
終了したら、SSLキーと証明書がアプリケーションディレクトリにあるはずです。 これらはそれぞれmyapp.key
およびmyapp.crt
と呼ばれます。
これが完了したら、web2pyWebインターフェースを起動してテストできます。 これを行うには、次のように入力します。
python web2py.py -k myapp.key -c myapp.crt -i 0.0.0.0 -p 8000
管理インターフェースのパスワードを選択するように求められます。
これで、次の場所に移動して、Webブラウザでアプリケーションにアクセスできます。
https://server_domain_or_IP:8000
上記のアドレスでは、http
の代わりにhttps
を使用してください。 ブラウザがSSL証明書を認識しないという警告が表示されます。
これは、独自の証明書に署名したためです。 「詳細」リンクまたはブラウザに表示されるその他のリンクをクリックして、計画どおりにサイトに進みます。 web2pyインターフェースが表示されます。
右端の「管理インターフェース」ボタンをクリックすると、サーバーの実行時に選択したパスワードを入力して、管理サイトにアクセスできるようになります。
これにより、アプリケーションを実行している実際のコードにアクセスできるようになり、インターフェイス自体からファイルを編集および微調整できるようになります。
見回し終えたら、ターミナルウィンドウでCTRL-Cを入力します。 アプリケーションをテストし、web2py開発サーバーの実行中にWeb上でアクセスできることを実証しました。
uWSGIのインストールと構成
これでweb2pyアプリケーションが動作するようになったので、uWSGIを構成できます。 uWSGIは、WSGIと呼ばれる標準インターフェイスを介してアプリケーションと通信できるアプリケーションサーバーです。 これについて詳しくは、Ubuntu14.04でのuWSGIとNginxのセットアップに関するガイドのこのセクションをお読みください。
uWSGIのインストール
上記のリンク先のガイドとは異なり、このチュートリアルでは、uWSGIをグローバルにインストールします。 uWSGIをインストールする前に、pip
、Pythonパッケージマネージャー、およびuWSGIが依存するPython開発ファイルをインストールする必要があります。 また、実際のバイナリをビルドするためのコンパイラも必要になります。 pip
を取得するには、追加のパッケージを含むEPELリポジトリを使用する必要があります。
次のように入力して、EPELリポジトリをアクティブ化できます。
sudo yum install epel-release
その後、次のように入力して、必要なパッケージをインストールできます。
sudo yum install python-devel python-pip gcc
これで、次のように入力して、pip
を使用してuWSGIをグローバルにインストールできます。
sudo pip install uwsgi
uWSGIアプリケーションコンテナサーバーは、WSGIインターフェイス仕様を使用してPythonアプリケーションとインターフェイスします。 web2pyフレームワークには、handlers
ディレクトリ内にこのインターフェイスを提供するように設計されたファイルが含まれています。 ファイルを使用するには、ファイルをディレクトリからメインプロジェクトディレクトリに移動する必要があります。
mv ~/myapp/handlers/wsgihandler.py ~/myapp
メインプロジェクトディレクトリにあるWSGIハンドラーを使用して、次のように入力することで、uWSGIがアプリケーションを提供できることを確認できます。
uwsgi --http :8000 --chdir ~/myapp -w wsgihandler:application
これにより、ポート8000でアプリケーションが再起動します。 今回はSSL証明書とキーを使用していないため、HTTPSではなくプレーンHTTPで提供されます。 http
プロトコルを使用して、ブラウザでこれを再度テストできます。 暗号化が利用できない場合、web2pyはこれを無効にするため、管理インターフェースをテストすることはできません。
終了したら、ターミナルウィンドウでCTRL-Cを入力して、サーバーを停止します。
uWSGI構成ファイルの作成
uWSGIがアプリケーションにサービスを提供できることがわかったので、アプリケーションの情報を使用してuWSGI構成ファイルを作成できます。
/etc/uwsgi/sites
にディレクトリを作成して構成を保存し、そのディレクトリに移動します。
sudo mkdir -p /etc/uwsgi/sites cd /etc/uwsgi/sites
構成ファイルをmyapp.ini
と呼びます。
sudo nano myapp.ini
構成ファイルでは、すべての構成ディレクティブが配置される[uwsgi]
ヘッダーから開始する必要があります。 ヘッダーの後に、アプリケーションのディレクトリパスを示し、実行するモジュールを指示します。 これは、前にコマンドラインで使用した情報と同じになります。 モジュール行を変更する必要はありません。
[uwsgi] chdir = /home/user/myapp module = wsgihandler:application
次に、uWSGIをマスターモードで動作させるように指定する必要があります。 5つのワーカープロセスを生成します。
[uwsgi] chdir = /home/user/myapp module = wsgihandler:application master = true processes = 5
次に、uWSGIが接続を取得する方法を指定する必要があります。 uWSGIサーバーのテストでは、通常のHTTP接続を受け入れました。 ただし、uWSGIの前でリバースプロキシとしてNginxを構成するため、他のオプションがあります。
ネットワークポートを使用する代わりに、すべてのコンポーネントが単一のサーバーで動作しているため、Unixソケットを使用できます。 これはより安全で、より良いパフォーマンスを提供します。 このソケットはHTTPを使用しませんが、代わりにuWSGIのuwsgi
プロトコルを実装します。これは、他のサーバーと通信するために設計された高速バイナリプロトコルです。 Nginxはuwsgi
プロトコルを使用してネイティブにプロキシできるため、これが最善の選択です。
ファイルを所有しているため、プロセスを実行するユーザーを自分のユーザーに設定する必要があります。 また、Webサーバーに書き込みアクセスを許可するため、ソケットのアクセス許可と所有権も変更します。 ソケット自体は、uWSGIとNginxの両方がアクセスできる/run/uwsgi
ディレクトリ(このディレクトリを少し作成します)内に配置されます。 サービスが停止したときにソケットファイルが自動的にクリーンアップされるように、バキュームオプションを設定します。
[uwsgi] chdir = /home/user/myapp module = wsgihandler:application master = true processes = 5 uid = user socket = /run/uwsgi/myapp.sock chown-socket = user:nginx chmod-socket = 660 vacuum = true
これで、uWSGI構成ファイルが完成しました。 ファイルを保存して閉じます。
uWSGIのSystemdユニットファイルを作成する
uWSGIの構成ファイルを作成しましたが、起動時に自動的に起動するようにアプリケーションサーバーを設定していません。 この機能を実装するために、Systemdユニットファイルを作成できます。
ユーザーが作成したユニットファイルが保存されている/etc/systemd/system
ディレクトリにユニットファイルを作成します。 ファイルをuwsgi.service
と呼びます。
sudo nano /etc/systemd/system/uwsgi.service
メタデータを指定するために使用される[Unit]
セクションから始めます。 ここにサービスの説明を簡単に記載します。
[Unit] Description=uWSGI Emperor service
次に、[サービス]セクションを開きます。 ExecStartPreディレクティブを使用して、サーバーを実行するために必要な部分を設定します。 これにより、/ run / uwsgiディレクトリが作成され、通常のユーザーがNginxグループをグループ所有者として所有していることが確認されます。 -pフラグを指定したmkdirとchownコマンドはどちらも、すでに存在している場合でも正常に戻ります。 これが私たちが望んでいることです。
ExecStartディレクティブで指定された実際のstartコマンドでは、uwsgi実行可能ファイルをポイントします。 「Emperormode」で実行するように指示し、/ etc / uwsgi/sitesにあるファイルを使用して複数のアプリケーションを管理できるようにします。 また、Systemdがプロセスを正しく管理するために必要な要素を追加します。 これらは、uWSGIドキュメントここから取得されます。
[Unit] Description=uWSGI Emperor service [Service] ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi' ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites Restart=always KillSignal=SIGQUIT Type=notify NotifyAccess=all
これで、[インストール]セクションを追加するだけです。 これにより、サービスを自動的に開始するタイミングを指定できます。 サービスをマルチユーザーシステムの状態に結び付けます。 システムが複数のユーザー向けに設定されている場合(通常の動作状態)、当社のサービスがアクティブになります。
[Unit] Description=uWSGI Emperor service [Service] ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi' ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites Restart=always KillSignal=SIGQUIT Type=notify NotifyAccess=all [Install] WantedBy=multi-user.target
これが終了したら、ファイルを保存して閉じます。
nginxユーザーが利用可能であることに依存しているため、この時点でサービスを正常に開始することはできません。 Nginxがインストールされるまで、uWSGIサービスの開始を待つ必要があります。
Nginxをリバースプロキシとしてインストールおよび構成する
uWSGIを構成して準備ができたら、Nginxをリバースプロキシとしてインストールして構成できます。 これは、次のように入力してyum
でダウンロードできます。
sudo yum install nginx
Nginxがインストールされたら、先に進んでサーバーブロック構成を変更できます。 メインのNginx構成ファイルを編集します。
sudo nano /etc/nginx/nginx.conf
web2pyアプリケーションは、プレーンHTTPとSSL暗号化のどちらで接続しているかを検出します。 このため、ファイルには実際にはそれぞれに1つのサーバーブロックが含まれます。 ポート80で動作するように構成されたサーバーブロックから始めます。
server_name
を変更して、サイトにアクセスできるドメイン名またはIPアドレスを参照します。 その後、静的コンテンツのリクエストに一致するlocation {}
ブロックを作成します。 基本的に、正規表現を使用して、/static/
で終わるリクエストを先行するパスコンポーネントと照合します。 これらのリクエストをweb2pyプロジェクト内のapplications
ディレクトリにマッピングします。 ユーザーのホームディレクトリとアプリ名を必ず参照してください。
server { listen 80 default_server; server_name server_domain_or_IP; root /usr/share/nginx/html; include /etc/nginx/default.d/*.conf; location ~* /(\w+)/static/ { root /home/user/myapp/applications/; } . . .
その後、location / {}
ブロックを調整して、リクエストをuWSGIソケットに渡す必要があります。 Nginxにパッケージ化されたuWSGIパラメーターファイルをインクルードし、構成したソケットにリクエストを渡す必要があります(uWSGI .ini
ファイル内)。
server { listen 80 default_server; server_name server_domain_or_IP; root /usr/share/nginx/html; include /etc/nginx/default.d/*.conf; location ~* /(\w+)/static/ { root /home/user/myapp/applications/; } location / { include uwsgi_params; uwsgi_pass unix:/home/user/myapp/myapp.sock; } } . . .
これが、最初のサーバーブロックに必要なすべてです。
ファイルの下部で、閉じているhttp {}
ブロックブラケットの内側に、別のserver {}
ブロックを作成します。 これを使用してSSL接続を構成します。
基本から始めましょう。 このサーバーブロックは、デフォルトのSSLポートであるポート443で接続をリッスンします。 ポート80サーバーブロックの場合と同じように、サーバーのドメイン名またはIPアドレスを設定します。 実際のSSL構成を開始するには、このブロックでSSLをオンにする必要があることを指定し、接続の暗号化に使用する必要があるSSL証明書とキーへのパスを指定します。 ファイルを一時的にそこに移動します。
http { . . . server { listen 80; . . . } server { listen 443; server_name server_domain_or_IP; ssl on; ssl_certificate /etc/nginx/ssl/myapp.crt; ssl_certificate_key /etc/nginx/ssl/myapp.key; } }
受け入れられたプロトコルと暗号を確立することを目的としたSSLボイラープレートを少し続けます。 その後、ポート80サーバーブロックで構成したものと同じlocation / {}
ブロックを設定できます。
http { . . . server { listen 80; . . . } server { listen 443; server_name server_domain_or_IP; ssl on; ssl_certificate /etc/nginx/ssl/myapp.crt; ssl_certificate_key /etc/nginx/ssl/myapp.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; location / { include uwsgi_params; uwsgi_pass unix:/run/uwsgi/myapp.sock; } } }
これで、このファイルに2つのサーバーブロックが構成されているはずです。 終了したら、保存して閉じます。
最終ステップ
次に、SSL証明書を指定したディレクトリに移動する必要があります。 最初にディレクトリを作成します。
sudo mkdir -p /etc/nginx/ssl
次に、作成した証明書とキーをそのディレクトリに移動します。 商用認証局によって署名されたSSL証明書がある場合は、訪問者に対する信頼できないSSL証明書の警告を回避するために、ここで証明書と対応するキーを置き換えることができます。
sudo mv ~/myapp/myapp.crt /etc/nginx/ssl sudo mv ~/myapp/myapp.key /etc/nginx/ssl
ルート以外のユーザーがそのディレクトリにアクセスできないように、アクセス許可を変更します。
sudo chmod 700 /etc/nginx/ssl
nginx
ユーザーは、必要に応じて静的ファイルを直接提供できるように、アプリケーションディレクトリにアクセスできる必要があります。 CentOSは各ユーザーのホームディレクトリを非常に制限的にロックダウンするため、nginx
ユーザーをユーザーのグループに追加して、これを機能させるために必要な最小限のアクセス許可を開くことができるようにします。
これを入力して、nginx
ユーザーをグループに追加します。 以下のコマンドで、user
の代わりにユーザー名を使用してください。
sudo usermod -a -G user nginx
次に、ユーザーグループにディレクトリに対する実行権限を付与します。これにより、Nginxプロセスが次のコンテンツを入力してアクセスできるようになります。
chmod 710 /home/user
次に、Nginx構成ファイルで構文エラーを確認します。
sudo nginx -t
構文エラーが報告されていない場合は、先に進んでNginxを起動できます。
sudo service nginx start
uWSGIサービスを開始することもできます。
sudo service uwsgi start
最後に行う必要があるのは、アプリケーションのパラメータファイルをコピーして、ポート443で接続を提供するときに正しく読み取られるようにすることです。 これには、管理インターフェース用に構成したパスワードが含まれています。 ポート8000ではなくポート443を示す新しい名前にコピーする必要があります。
cp ~/myapp/parameters_8000.py ~/myapp/parameters_443.py
これにより、サーバーのドメイン名またはIPアドレスを使用してサーバーにアクセスできるようになります。 管理インターフェースにサインインする場合は、https
を使用してください。
すべてがうまくいけば、次のように入力して、NginxとuWSGIが起動時に開始できるようにすることができます。
sudo systemctl enable nginx sudo systemctl enable uwsgi
結論
このガイドでは、デプロイを練習するためのサンプルweb2pyプロジェクトを設定しました。 アプリケーションとクライアント要求の間のインターフェースとして機能するようにuWSGIを構成しました。 次に、uWSGIの前にNginxをセットアップして、SSL接続を可能にし、クライアント要求を効率的に処理します。
web2pyプロジェクトは、最初から実行可能なWebインターフェイスを提供することにより、サイトとWebアプリケーションの開発を簡素化します。 この記事で説明する一般的なツールチェーンを活用することで、単一のサーバーから作成したアプリケーションを簡単に提供できます。