ファブリックを使用したデプロイ
Fabric は、Makefilesに似ていますが、リモートサーバーでコマンドを実行する機能を備えたPython用のツールです。 適切にセットアップされたPythonパッケージ( Larger Applications )と構成の優れたコンセプト( Configuration Handling )を組み合わせると、Flaskアプリケーションを外部サーバーにデプロイするのは非常に簡単です。
始める前に、事前に確認する必要がある事項の簡単なチェックリストを以下に示します。
- Fabric1.0はローカルにインストールする必要があります。 このチュートリアルは、Fabricの最新バージョンを想定しています。
- アプリケーションはすでにパッケージである必要があり、動作する
setup.py
ファイル( Setuptools を使用したデプロイ)が必要です。 - 次の例では、リモートサーバーに mod_wsgi を使用しています。 もちろん、ここでお気に入りのサーバーを使用することもできますが、この例では、セットアップが非常に簡単で、ルートアクセスなしでアプリケーションをリロードする簡単な方法があるため、Apache + mod_wsgi を選択しました。
最初のFabfileを作成する
fabfileは、Fabricが実行するものを制御するものです。 fabfile.py
という名前で、 fab コマンドによって実行されます。 そのファイルで定義されているすべての関数は、 fab サブコマンドとして表示されます。 それらは1つ以上のホストで実行されます。 これらのホストは、fabfileまたはコマンドラインで定義できます。 この場合、それらをfabfileに追加します。
これは、現在のソースコードをサーバーにアップロードし、それを既存の仮想環境にインストールする機能を備えた基本的な最初の例です。
from fabric.api import *
# the user to use for the remote commands
env.user = 'appuser'
# the servers where the commands are executed
env.hosts = ['server1.example.com', 'server2.example.com']
def pack():
# build the package
local('python setup.py sdist --formats=gztar', capture=False)
def deploy():
# figure out the package name and version
dist = local('python setup.py --fullname', capture=True).strip()
filename = '%s.tar.gz' % dist
# upload the package to the temporary folder on the server
put('dist/%s' % filename, '/tmp/%s' % filename)
# install the package in the application's virtualenv with pip
run('/var/www/yourapplication/env/bin/pip install /tmp/%s' % filename)
# remove the uploaded package
run('rm -r /tmp/%s' % filename)
# touch the .wsgi file to trigger a reload in mod_wsgi
run('touch /var/www/yourapplication.wsgi')
Fabfilesの実行
では、そのfabfileをどのように実行しますか? fab コマンドを使用します。 現在のバージョンのコードをリモートサーバーに展開するには、次のコマンドを使用します。
$ fab pack deploy
ただし、これには、サーバーに/var/www/yourapplication
フォルダーが既に作成されており、/var/www/yourapplication/env
が仮想環境である必要があります。 さらに、サーバー上に構成または.wsgi
ファイルを作成していません。 では、どのようにして新しいサーバーをインフラストラクチャにブートストラップするのでしょうか。
これは、セットアップするサーバーの数によって異なります。 アプリケーションサーバーが1つしかない場合(ほとんどのアプリケーションにあります)、このためのコマンドをfabfileに作成するのはやり過ぎです。 しかし、明らかにあなたはそれを行うことができます。 その場合、おそらく setup または bootstrap と呼び、コマンドラインでサーバー名を明示的に渡します。
$ fab -H newserver.example.com bootstrap
新しいサーバーをセットアップするには、大まかに次の手順を実行します。
/var/www
にディレクトリ構造を作成します。$ mkdir /var/www/yourapplication $ cd /var/www/yourapplication $ virtualenv --distribute env
新しい
application.wsgi
ファイルをサーバーとアプリケーションの構成ファイルにアップロードします(例:application.cfg
)yourapplication
の新しいApache構成を作成し、アクティブ化します。.wsgi
ファイルの変更の監視をアクティブにして、アプリケーションに触れることで自動的にリロードできるようにしてください。 (詳細については、 mod_wsgi(Apache)を参照してください)
では、問題は、application.wsgi
ファイルとapplication.cfg
ファイルはどこから来たのかということです。
WSGIファイル
WSGIファイルは、アプリケーションをインポートし、環境変数を設定して、アプリケーションが構成を探す場所を認識できるようにする必要があります。 これはまさにそれを行う短い例です:
import os
os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg'
from yourapplication import app
次に、アプリケーション自体を次のように初期化して、その環境変数で構成を探す必要があります。
app = Flask(__name__)
app.config.from_object('yourapplication.default_config')
app.config.from_envvar('YOURAPPLICATION_CONFIG')
このアプローチについては、ドキュメントの構成処理セクションで詳しく説明されています。
構成ファイル
上記のように、アプリケーションはYOURAPPLICATION_CONFIG
環境変数を検索することで正しい構成ファイルを見つけます。 そのため、アプリケーションが検出できる場所に構成を配置する必要があります。 構成ファイルは、すべてのコンピューターで異なるという不親切な品質を持っているため、通常はバージョン管理を行いません。
一般的なアプローチは、さまざまなサーバーの構成ファイルを別のバージョン管理リポジトリに保存し、すべてのサーバーでチェックアウトすることです。 次に、サーバーでアクティブなファイルを、予期される場所にシンボリックリンクします(例:/var/www/yourapplication
)。
いずれにせよ、ここでの私たちのケースでは、1つまたは2つのサーバーしか期待しておらず、事前に手動でアップロードできます。
最初の展開
これで、最初の展開を行うことができます。 仮想環境とアクティブ化されたapache構成を持つようにサーバーをセットアップしました。 これで、アプリケーションをパックしてデプロイできます。
$ fab pack deploy
これで、Fabricはすべてのサーバーに接続し、fabfileに記述されているコマンドを実行します。 最初にパックを実行してtarballの準備を整え、次にデプロイを実行してソースコードをすべてのサーバーにアップロードし、そこにインストールします。 setup.py
ファイルのおかげで、必要なライブラリを仮想環境に自動的に取り込みます。
次のステップ
その時点から、展開を実際に楽しくするためにできることはたくさんあります。
- 新しいサーバーを初期化する bootstrap コマンドを作成します。 新しい仮想環境を初期化したり、Apacheを適切に設定したりすることができます。
- 構成ファイルを別のバージョン管理リポジトリに配置し、アクティブな構成を適切な場所にシンボリックリンクします。
- また、アプリケーションコードをリポジトリに配置し、サーバー上の最新バージョンをチェックアウトしてからインストールすることもできます。 そうすれば、古いバージョンに簡単に戻すこともできます。
- テスト機能をフックして、外部サーバーにデプロイしてテストスイートを実行できるようにします。
Fabricの操作は楽しく、fab deploy
と入力すると、アプリケーションが1つ以上のリモートサーバーに自動的にデプロイされるのを見るのは非常に魔法のようです。