Ubuntu16.04でGunicornとNginxを使用してFalconWebアプリケーションをデプロイする方法
序章
Falcon は、Webアプリケーションを構築するための最小限のPythonフレームワークです。 RESTアーキテクチャスタイルに従うAPIの構築に最適です。 これは、開発速度を犠牲にすることなく、できる限り少ないことを試みる、低レベルで高性能のフレームワークです。
このチュートリアルでは、FalconWebアプリケーションをビルドしてデプロイします。 FalconはWSGIフレームワークであるため、WSGIアプリケーションサーバーである Gunicorn をインストールして使用し、アプリを提供します。 次に、Nginxをリバースプロキシサーバーとして使用して本番環境に対応した環境を作成し、着信リクエストがGunicornに到達する前に処理します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu16.04初期サーバーセットアップガイドに従ってセットアップされた1つのUbuntu16.04サーバー。これには、sudo非rootユーザーとファイアウォールが含まれます。
ステップ1—Python仮想環境を作成する
コードの記述やサービスの設定に取り掛かる前に、サーバー上にアプリケーション用のPython仮想環境を作成します。
root以外のユーザーとしてサーバーに接続します。
- ssh sammy@your_server_ip
FalconはPython2.xとPython3.xの両方で動作しますが、Ubuntu16.04で利用可能な最新バージョンのPythonであるPython3.5を使用します。
pipとvirtualenvを使用してFalconアプリケーションをセットアップします。 これらのツールの詳細については、一般的なPythonツールに関するチュートリアルをお読みください。
まず、virtualenvをインストールします。
- sudo apt-get install virtualenv
次に、アプリケーションのソースコードと仮想環境を保持するディレクトリを作成し、そのディレクトリに移動します。
- mkdir falcon_app
- cd falcon_app
次に、仮想環境を作成します。
- virtualenv venv -p /usr/bin/python3
このコマンドは、ディレクトリvenv
内に仮想環境を作成します。 -p
フラグは、仮想環境で使用されるPythonのバージョンを指定します。
次の出力が表示されます。
OutputAlready using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/sammy/falcon_app/venv/bin/python3
Also creating executable in /home/sammy/falcon_app/venv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
次に、仮想環境をアクティブ化します。
- . venv/bin/activate
システム全体のPythonインタープリターに戻すには、次のコマンドを発行して仮想環境を非アクティブ化します。
- deactivate
Python仮想環境をセットアップしたので、必要なPythonパッケージをインストールしましょう。
ステップ2—pipを使用してFalconとGunicornをインストールする
falcon
パッケージをインストールする必要があります。また、Gunicornを使用してアプリを提供しているため、それもインストールする必要があります。 これらは両方ともpip
から入手できます。
Falconは2つの方法のいずれかでインストールできます。 Falconには、pip install falcon
でインストールできるバイナリがありますが、 Cython でコンパイルすると、Falconの速度がさらに向上します。 次のコマンドを発行してCythonをインストールし、Falconに通知して、Cythonを検出し、システムのCコンパイラを使用してコンパイルします。
- sudo apt-get install build-essential python3-dev
- pip install cython
- pip install --no-binary :all: falcon
次に、Gunicornをインストールします。
- pip install gunicorn
簡単なFalconアプリケーションの作成に移りましょう。
ステップ3—Falconを使用して簡単なWebアプリケーションを作成する
簡単な単一ファイルのFalconアプリケーションを作成しましょう。 falcon_app
ディレクトリにファイルmain.py
を作成します。
- nano main.py
ファイルに次のコンテンツを入力します。これにより、ユーザーが/test
ルートにアクセスしたときに簡単なテストメッセージを表示するFalconアプリケーションが作成されます。
import falcon
class TestResource(object):
def on_get(self, req, res):
"""Handles all GET requests."""
res.status = falcon.HTTP_200 # This is the default status
res.body = ('This is me, Falcon, serving a resource!')
# Create the Falcon application object
app = falcon.API()
# Instantiate the TestResource class
test_resource = TestResource()
# Add a route to serve the resource
app.add_route('/test', test_resource)
このファイルでは、TestResource
というクラスを作成します。 このクラスには、送信する応答を定義するon_get
メソッドが含まれています。 次に、FalconAPIとTestResource
のインスタンスを作成します。 次に、ルート/test
をAPIに追加し、リソースオブジェクトtest_resource
をAPIにアタッチします。
GET
リクエストが/test
URLに送信されるたびに、TestResource
のon_get()
メソッドが呼び出されます。 応答ステータスと本文は、それぞれ変数res.status
とres.body
を使用して設定されます。
ファイルを保存して、エディターを閉じます。 アプリケーションをテストしてみましょう。
ステップ4—GunicornでFalconアプリケーションを提供する
Nginxを使用してアプリケーションを本番環境に対応させる作業を行う前に、Gunicornでアプリケーションを提供してアプリケーションが機能することを確認しましょう。
falcon_app
ディレクトリにいることを確認してください。 次のコマンドでGunicornを起動します。
- gunicorn -b 0.0.0.0:5000 main:app --reload
これにより、Gunicornが起動し、出力からわかるように、ポート5000
の0.0.0.0
でWebアプリケーションが提供されます。
Output[2016-11-14 16:33:41 +0000] [9428] [INFO] Starting gunicorn 19.6.0
[2016-11-14 16:33:41 +0000] [9428] [INFO] Listening at: http://0.0.0.0:5000 (9428)
[2016-11-14 16:33:41 +0000] [9428] [INFO] Using worker: sync
[2016-11-14 16:33:41 +0000] [9431] [INFO] Booting worker with pid: 9431
任意のポート番号を使用できますが、1024
より上であり、他のプログラムで使用されていないことを確認してください。
main:app
オプションは、ファイルmain.py
で使用可能なアプリケーションオブジェクトapp
を呼び出すようにGunicornに指示します。
Gunicornは、オプションの--reload
スイッチを提供し、Gunicornにコードの変更をその場で検出するように指示します。 このようにして、Gunicornを再起動せずにコードを変更できます。
ローカルコンピューターでWebブラウザーを開き、ブラウザーでhttp://your_server_ip:5000/test
にアクセスして、アプリケーションをテストします。 Webアプリケーションから次の出力が表示されます。
CTRL+C
を押してGunicornを停止します。 これをより本番環境に対応した方法で設定しましょう。
ステップ5—Nginxを使用してリクエストをGunicornにプロキシする
Gunicornに外部からのリクエストを直接提供させるのではなく、すべてのWebリクエストをGunicornにプロキシするようにNginxを設定および構成します。 そうすることで、Webアプリケーションのすべてのリクエストが最初にNginxによって検出され、次にアプリケーションサーバーにルーティングされます。
まず、次のコマンドを実行してNginxをインストールします。
- sudo apt-get install nginx
次に、/etc/nginx/sites-available
ディレクトリにfalcon_app.conf
という新しい構成ファイルを作成します。 このファイルは、サーバーのIPアドレスに送信されるすべてのリクエストをFalconアプリケーションのGunicornサーバーにプロキシするようにNginxを構成します。
- sudo nano /etc/nginx/sites-available/falcon_app.conf
次の内容をファイルに追加します。
server {
listen 80;
server_name your_server_ip_or_domain;
location / {
include proxy_params;
proxy_pass http://localhost:5000;
}
}
この構成は、Nginxにポート80
でリッスンし、すべてのHTTPリクエストをhttp://localhost:5000
にプロキシするように指示します。ここで、Gunicornがリッスンします。
/etc/nginx/sites-enabled
ディレクトリにこのファイルへのシンボリックリンクを作成して、この構成をアクティブにします。
- sudo ln -s /etc/nginx/sites-available/falcon_app.conf /etc/nginx/sites-enabled/falcon_app.conf
次に、/etc/nginx/sites-enabled
ディレクトリからシンボリックリンクを削除して、デフォルトのNginx構成ファイルを無効にします。
- sudo rm /etc/nginx/sites-enabled/default
Nginxファイルのいずれにも構文エラーがないことを確認してください。
- sudo nginx -t
構成が機能している場合は、次のメッセージが表示されます。
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
エラーが表示された場合は、エラーを修正して再度テストしてください。
新しい構成を有効にするには、Nginxを再起動します。
- sudo systemctl restart nginx
ここでGunicornを再起動しますが、リスニングアドレスを0.0.0.0
からlocalhost
に変更して、Gunicornへのパブリックアクセスを防止します。
- gunicorn -b localhost:5000 main:app --reload
有効にしている場合は、サーバーのファイアウォールを介したポート80
へのアクセスを許可します。
- sudo ufw allow 80
注:https
を使用してWebアプリケーションを提供している場合は、ufw
を使用してポート443
を許可してください。 また、Let’sEncryptを使用してNginxを保護する方法に関する記事も必ずお読みください。
最後に、http://your_server_ip/test
にアクセスしてアプリをテストすると、以前と同じ出力が表示されます。
リクエストは現在、デフォルトのHTTPポートであるポート80
で実行されるNginxを経由しているため、URLのポート番号は不要になっていることに注意してください。 ブラウザに次の出力が表示されます。
CTRL+C
を押してアプリサーバーを停止します。 他のサービスと同様に、バックグラウンドで自動的に起動するようにFalconアプリケーションを構成しましょう。
ステップ7—SystemdでGunicornを管理する
Nginxと同様に、サーバーが起動するたびにアプリケーションが自動的に起動することを確認する必要があります。 サーバーが誤って再起動された場合、または何らかの理由で再起動する必要があった場合は、Gunicornを手動で起動する必要はありません。
これを構成するには、Gunicornアプリケーション用に Systemdユニットファイルを作成して、管理できるようにします。
まず、/etc/systemd/system
ディレクトリ内に.service
拡張子の付いたアプリケーション用のファイルを作成します。
- sudo nano /etc/systemd/system/falcon_app.service
ユニットファイルはセクションで構成されています。 [Unit]
セクションは、サービスの説明やサービスの開始時期など、サービスのメタデータと依存関係を指定するために使用されます。
この構成をファイルに追加します。
[Unit]
Description=Gunicorn instance to serve the falcon application
After=network.target
ネットワークターゲットに到達した後にサービスを開始するように指定します。 つまり、このサービスは、ネットワークサービスの準備ができてから開始します。
[Unit]
セクションの後に、サービスの開始方法を指定する[Service]
セクションを定義します。 これを構成ファイルに追加します。
[Service]
User=sammy
Group=www-data
PIDFile=/tmp/gunicorn.pid
Environment="PATH=/home/sammy/falcon_app/venv/bin"
WorkingDirectory=/home/sammy/falcon_app
ExecStart=/home/sammy/falcon_app/venv/bin/gunicorn --workers 3 -b localhost:5000 main:app
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
まず、サービスを実行するユーザーとグループを定義します。 次に、サービスのPID(プロセスID)を格納するファイルを定義します。 このPIDは、サービスを停止またはリロードするために使用されます。
また、アプリケーションの作業ディレクトリであるPython仮想環境を指定します。 およびアプリケーションを起動するために実行するコマンド。 Gunicornを起動するコマンドをExecStart
変数に割り当てます。 --workers
フラグは、Gunicornが開始する必要のあるワーカーの数を定義するために使用されます。 Gunicornのドキュメントでは、ワーカーの数を2n+1
に設定することを推奨しています。ここで、n
はCPUコアの数です。 サーバーに単一のCPUコアがあると仮定すると、番号3
に到達します。
ExecReload
変数とExecStop
変数は、サービスの開始方法と停止方法を定義します。
最後に、[Install]
セクションを追加します。これは次のようになります。
[Install]
WantedBy=multi-user.target
Install
セクションでは、サービスを有効または無効にできます。 WantedBy
ディレクティブは、/etc/systemd/system
内にmulti-user.target
というディレクトリを作成し、このファイルのシンボリックリンクがそこに作成されます。 このサービスを無効にすると、このファイルがディレクトリから削除されます。
ファイルを保存し、エディターを閉じて、新しいサービスを開始します。
- sudo systemctl start falcon_app
次に、このサービスを有効にして、サーバーが起動するたびにGunicornがWebアプリケーションの提供を開始するようにします。
- sudo systemctl enable falcon_app
もう一度、ブラウザをhttp://your_server_ip/test
に向けて、アプリケーションを表示します。 NginxとGunicornの両方がバックグラウンドで実行されています。 Falconアプリケーションを更新する必要がある場合は、falcon_app
サービスを再起動します。
- sudo systemctl restart falcon_app
単位ファイルの詳細については、チュートリアルSystemd単位と単位ファイルについてをお読みください。
結論
このガイドでは、最初のFalconWebアプリケーションを構成してデプロイしました。 Python環境をセットアップし、サーバーにアプリケーションコードを記述してから、Gunicornを使用してWebアプリケーションを提供しました。 次に、WebリクエストをGunicornアプリケーションに渡すようにNginxを構成しました。 最後に、Systemd Unitファイルを作成し、サーバーの起動時にWebアプリケーションが起動するようにサービスを有効にしました。
独自のアプリを本番環境に移行するときは、IPアドレスではなくホスト名を使用してアプリにアクセスする必要があります。 DigitalOcean でホスト名を設定して、ドメイン名をサーバーに向ける方法をご覧ください。