序章

web2pyフレームワークは、フル機能のPythonWebアプリケーションをすばやく開発するための強力で使いやすいツールです。 web2pyを使用すると、管理用Web UIを使用して、アプリケーションを簡単に開発および管理できます。

このガイドでは、Ubuntu14.04にweb2pyアプリケーションをデプロイする方法を示します。 uWSGIアプリケーションサーバーを使用して、複数のワーカープロセスを使用してアプリケーションとインターフェイスします。 uWSGIの前で、実際のクライアント接続を処理するためにリバースプロキシ構成でNginxをセットアップします。 これは、web2pyサーバーまたはuWSGIを単独で使用するよりもはるかに堅牢なデプロイメント戦略です。

前提条件と目標

このガイドを完了するには、sudo権限が設定されたroot以外のユーザーがいる新しいUbuntu14.04サーバーインスタンスが必要です。 初期サーバーセットアップガイドを実行すると、これをセットアップする方法を学ぶことができます。

web2pyフレームワークをダウンロードしてテストし、デフォルトのアプリケーション環境が正しく機能することを確認します。 その後、リクエストとweb2pyPythonコード間のインターフェイスとして機能するuWSGIアプリケーションコンテナをダウンロードしてインストールします。 この前にNginxを設定して、uWSGIへのクライアント接続とプロキシリクエストを処理できるようにします。 管理者の介入の必要性を最小限に抑えるために、起動時に開始するように各コンポーネントを構成します。

web2pyフレームワークをダウンロードする

最初のステップは、実際のweb2pyフレームワークをダウンロードすることです。 これはGitHubのgitリポジトリに保持されているため、ダウンロードするのに最適な方法はgit自体を使用することです。

次のように入力して、デフォルトのUbuntuリポジトリからgitをダウンロードしてインストールできます。

sudo apt-get update
sudo apt-get 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 SSL warning

これは、独自の証明書に署名したためです。 「詳細」リンクまたはブラウザに表示されるその他のリンクをクリックして、計画どおりにサイトに進みます。 web2pyインターフェースが表示されます。

web2py welcome app

右端の「管理インターフェース」ボタンをクリックすると、サーバーの実行時に選択したパスワードを入力して、管理サイトにアクセスできるようになります。

web2py admin interface

これにより、アプリケーションを実行している実際のコードにアクセスできるようになり、インターフェイス自体からファイルを編集および微調整できるようになります。

見回し終わったら、ターミナルウィンドウにCTRL-Cを入力します。 アプリケーションをテストし、web2py開発サーバーの実行中にWeb上でアクセスできることを実証しました。

uWSGIのインストールと構成

これでweb2pyアプリケーションが動作するようになったので、uWSGIを構成できます。 uWSGIは、WSGIと呼ばれる標準インターフェイスを介してアプリケーションと通信できるアプリケーションサーバーです。 これについて詳しくは、Ubuntu14.04でのuWSGIとNginxのセットアップに関するガイドのこのセクションをお読みください。

uWSGIのインストール

上記のリンク先のガイドとは異なり、このチュートリアルでは、uWSGIをグローバルにインストールします。 uWSGIをインストールする前に、pip、Pythonパッケージマネージャー、およびuWSGIが依存するPython開発ファイルをインストールする必要があります。 これらはUbuntuのリポジトリから直接インストールできます。

sudo apt-get install python-pip python-dev

これで、次のように入力して、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を構成するため、他のオプションがあります。 Nginxは、uwsgiプロトコルを使用してプロキシできます。これは、他のサーバーと通信するためにuWSGIによって設計された高速バイナリプロトコルです。 このプロトコルを使用して通信します。これは、別のプロトコルを指定しない場合のデフォルトです。

uwsgiプロトコルを使用してNginxと通信しているため、ネットワークポートは必要ありません。 代わりに、より安全で高速なUnixソケットを使用します。 これをアプリケーションディレクトリに配置します。 グループがソケットに対して読み取りと書き込みを行えるように、アクセス許可を変更する必要があります。 すぐに、uWSGIとNginxがソケットを介して通信できるように、Nginxプロセスグループにソケットの所有権を付与します。

[uwsgi]
chdir = /home/user/myapp
module = wsgihandler:application

master = true
processes = 5

socket = /home/user/myapp/myapp.sock
chmod-socket = 660
vacuum = true

上記のvacuumディレクティブは、uWSGIプロセスが終了したときにソケットファイルをクリーンアップします。

これで、uWSGI構成ファイルが完成しました。 ファイルを保存して閉じます。

uWSGIアップスタートファイルを作成する

uWSGIの構成ファイルを作成しましたが、起動時に自動的に起動するようにアプリケーションサーバーを設定していません。 この機能を実装するために、単純なUpstartファイルを作成できます。 「Emperorモード」でuWSGIを実行するように指示します。これにより、アプリケーションサーバーは任意の数の構成を読み取り、それぞれに対してサーバーを起動できます。

/etc/initディレクトリにファイルを作成し、Upstartプロセスがその構成ファイルを検索します。

sudo nano /etc/init/uwsgi.conf

まず、サービスファイルに説明を付け、自動的に開始するランレベルを指定します。 従来のマルチユーザーランレベルは2、3、4、および5です。 サーバーが他のランレベルに移行したときに(シャットダウン、再起動、シングルユーザーモードなど)、Upstartでサービスを停止します。

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

次に、プロセスを実行するユーザーとグループを指定する必要があります。 すべてのプロジェクトファイルを所有しているため、通常のユーザーアカウントを使用します。 私たちのグループでは、www-dataグループの所有権を許可する必要があります。これは、Nginxが動作するグループです。 これにより、uWSGI構成でソケットグループに読み取りおよび書き込み権限が付与されたため、WebサーバーがuWSGIと自由に通信できるようになります。

その後、uWSGIを起動するために実行するコマンドを指定するだけです。 --emperorフラグを使用して、構成ファイルを含むディレクトリを渡す必要があります。

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid user
setgid www-data

exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

これにより、web2pyサイトを処理するためのuWSGIアプリケーションサーバーが起動します。 Emperorモードでは、他のプロジェクト用にこのディレクトリに構成ファイルを簡単に追加できます。 それらは自動的に処理されます。

これで、Upstartスクリプトが完成しました。 ファイルを保存して閉じます。 この時点では、Nginxをまだインストールしていないため、uWSGIサービスを開始できません。 これは、スクリプトを実行するように指示したグループがまだ利用できないことを意味します。

Nginxをリバースプロキシとしてインストールおよび構成する

uWSGIを構成して準備ができたら、Nginxをリバースプロキシとしてインストールして構成できます。 これは、Ubuntuのデフォルトのリポジトリからダウンロードできます。

sudo apt-get install nginx

Nginxがインストールされたら、先に進んでサーバーブロック構成を変更できます。 必要なもののほとんどが含まれているため、デフォルトのサーバーブロックをベースとして使用します。

sudo nano /etc/nginx/sites-available/default

web2pyアプリケーションは、プレーンHTTPとSSL暗号化のどちらで接続しているかを検出します。 このため、ファイルには実際にはそれぞれに1つのサーバーブロックが含まれます。 ポート80で動作するように構成されたサーバーブロックから始めます。

server_nameを変更して、サイトにアクセスできるドメイン名またはIPアドレスを参照します。 その後、静的コンテンツのリクエストに一致するlocation {}ブロックを作成します。 基本的に、正規表現を使用して、/static/で終わるリクエストを先行するパスコンポーネントと照合します。 これらのリクエストをweb2pyプロジェクト内のapplicationsディレクトリにマッピングします。 ユーザーのホームディレクトリとアプリ名を必ず参照してください。

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name server_domain_or_IP;

    location ~* /(\w+)/static/ {
        root /home/user/myapp/applications/;
    }

    . . .

その後、location / {}ブロックを調整して、リクエストをuWSGIソケットに渡す必要があります。 Nginxにパッケージ化されたuWSGIパラメーターファイルをインクルードし、構成したソケットにリクエストを渡す必要があります(uWSGI .iniファイル内)。

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name server_domain_or_IP;

    location ~* /(\w+)/static/ {
        root /home/user/myapp/applications/;
    }

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

これが、最初のサーバーブロックに必要なすべてです。

ファイルの下部には、SSLを使用してコンテンツを提供するために必要なほとんどのディレクティブを含むコメントアウトされたセクションがあります。 このブロックは、最初のディレクティブとしてlisten 443;を持っているため、識別できます。 このブロックのコメントを解除して、構成を開始します。

開始するには、サーバーのドメイン名またはIPアドレスと一致するようにserver_nameを再度変更します。 次に、ssl_certificateおよびssl_certificate_keyディレクティブにジャンプできます。 生成したSSL証明書を/etc/nginx/sslのディレクトリに一時的に配置するので、その場所にあるファイルへのパスを指定します。

server {
    listen 443;
    server_name server_domain_or_IP;

    root html;
    index index.html index.htm;

    ssl on;
    ssl_certificate /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;

    . . .

ssl_protocolsリストで、プロトコル自体に固有の脆弱性があることがわかっているSSLv3を削除します。

次に、location / {}ブロックにジャンプして、最後のサーバーブロックで行ったのと同じuWSGIプロキシ情報を配置できます。

server {
    listen 443;
    server_name server_domain_or_IP;

    root html;
    index index.html index.htm;

    ssl on;
    ssl_certificate /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;

    ssl_session_timeout 5m;

    #ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    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:/home/user/myapp/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

root以外のユーザーがそのディレクトリにアクセスできないように、権限を変更します。

sudo chmod 700 /etc/nginx/ssl

次に、Nginx構成ファイルで構文エラーを確認します。

sudo nginx -t

構文エラーが報告されていない場合は、先に進んでNginxを再起動できます。

sudo service nginx restart

uWSGIサービスを開始することもできます。

sudo service uwsgi start

最後に行う必要があるのは、アプリケーションのパラメータファイルをコピーして、ポート443で接続を提供するときに正しく読み取られるようにすることです。 これには、管理インターフェース用に構成したパスワードが含まれています。 ポート8000ではなくポート443を示す新しい名前にコピーする必要があります。

cp ~/myapp/parameters_8000.py ~/myapp/parameters_443.py

これにより、サーバーのドメイン名またはIPアドレスを使用してサーバーにアクセスできるようになります。 管理インターフェイスにサインインする場合は、httpsを使用します。

結論

このガイドでは、デプロイを練習するためのサンプルweb2pyプロジェクトを設定しました。 アプリケーションとクライアント要求の間のインターフェースとして機能するようにuWSGIを構成しました。 次に、uWSGIの前にNginxをセットアップして、SSL接続を可能にし、クライアント要求を効率的に処理します。

web2pyプロジェクトは、最初から実行可能なWebインターフェイスを提供することにより、サイトとWebアプリケーションの開発を簡素化します。 この記事で説明する一般的なツールチェーンを活用することで、単一のサーバーから作成したアプリケーションを簡単に提供できます。