アプリケーションは成長し、より複雑になっています。 それらを展開および更新するために必要な操作の数は増え続けています。
- 同じ繰り返しアクションにはかなりの時間がかかります。
- 一部のアクションを忘れ、他の場所を混乱させる
- 人的要因、軽薄さと先見性
この記事では、エキサイティングな、場合によっては予測不可能な冒険を、予測可能な結果を伴うシンプルで日常的で退屈な操作に変える方法について説明します。
私たちの目標
- 操作をより速く実行します。 複数のサーバーで並行して
- 十分にテストされた手順がある
- アプリケーションで任意のアクションを実行できる使いやすいツールを用意する
ファブリックをインストールする
生地を使用し
ます 。 このセットは、システム管理タスクを自動化するための優れた汎用ツールです。 彼はこの
記事でよく代表されてい
ます 。
したがって、Linuxとpython(2.5-2.7)を備えたワークステーションが既にあると仮定します。 必要なツールをインストールします。
ちょっとした推論
sshを介してサーバーと対話します。 したがって、キーを既に生成し、その使用を〜/ .ssh / configで決定し、パブリック部分をサーバーに配置していると想定しています。 サーバー上でユーザーを管理しやすくするために、各展開エンジニアに個人アカウントを作成します。このアカウントは、プロセスでプロジェクトユーザーからのコマンドを実行したり、プロジェクトユーザーになったりできます。
最も単純な展開プロジェクトは次のもので構成されます。
myapp_deploy/ fabfile.py
1つのサーバーにある最も単純なサービスを展開します。 このサービスでは、その特異性を決定する一連のパラメーターを定義します。 このようなアプローチにより、アプリケーションを論理的にモジュールに分割し、各モジュールを個別にデプロイできます。
スクリプトを書く
from fabric.api import env, run, sudo, local, put, settings import fabtools def production(): """Defines production environment""" env.hosts = ['192.168.1.2']
次に、機能を直接扱いましょう。 まず、サーバーの初期設定を行う必要があります。 システムの設定を変更する必要がある場合にのみ、この操作を実行します。 関数呼び出しは、システム内のすべての特権を持つシステム管理者に委任するのが最適です。
def permissions(): """Set proper permissions for release""" sudo("chown -R %(project_user)s:%(project_user)s %(domain_path)s" % { 'domain_path':env.domain_path, 'project_user':env.sudo_user }) def setup(): """Prepares one or more servers for deployment""" with settings(sudo_user='root'): sudo("mkdir -p %(domain_path)s/releases" % { 'domain_path':env.domain_path }) sudo("mkdir -p %(base_dir)s/logs/" % { 'base_dir':env.base_dir }) permissions() put("sudoers/devel_sudo", "/tmp/devel_sudo") sudo("chown root:root /tmp/devel_sudo") sudo("chmod 0440 /tmp/devel_sudo") sudo("mv /tmp/devel_sudo /etc/sudoers.d/devel_sudo")
次に、サーバー上のリリースのストレージを決定します。 ディレクトリ構造は次のようになります。
/apps myapp.example.com/ current
タイムスタンプを使用してリリースインデックスを決定します。 したがって、最新のリリースと最後から2番目のリリース(ロールバックする場合)およびそれらへのパスを見つける必要があります。
def releases(): """List a releases made""" env.releases = sorted(sudo('ls -x %(releases_path)s' % { 'releases_path':env.releases_path }).split()) if len(env.releases) >= 1: env.current_revision = env.releases[-1] env.current_release = "%(releases_path)s/%(current_revision)s" % { 'releases_path':env.releases_path, 'current_revision':env.current_revision } if len(env.releases) > 1: env.previous_revision = env.releases[-2] env.previous_release = "%(releases_path)s/%(previous_revision)s" % { 'releases_path':env.releases_path, 'previous_revision':env.previous_revision }
頻繁に接続される展開では、一部のサービスの再起動が必要です。 最も単純なプロジェクトがあるにもかかわらず、既知の
問題を回避するにはphp-fpmをリロードする必要があり
ます 。
def restart(): """Restarts your application services""" with settings(sudo_user='root',use_shell=False): sudo("/etc/init.d/php5-fpm reload")
ここで、何らかの方法でリポジトリからコードを取得する必要があります。 gitリポジトリから最新バージョンのファイルを複製します。
def checkout(): """Checkout code to the remote servers""" env.timestamp = run("/bin/date +%s") env.current_release = "%(releases_path)s/%(timestamp)s" % { 'releases_path':env.releases_path, 'timestamp':env.timestamp } sudo("cd %(releases_path)s; git clone -q -b master --depth 1 %(git_clone)s %(current_release)s" % { 'releases_path':env.releases_path, 'git_clone':env.git_clone, 'current_release':env.current_release })
構成ファイルをリリースディレクトリにコピーします。
def copy_config(): """Copy custom config to the remote servers""" if not env.has_key('releases'):
シンボリックリンクを使用して、最新リリースを適切なものにします
def symlink(): """Updates the symlink to the most recently deployed version""" if not env.has_key('current_release'): releases() sudo("ln -nfs %(current_release)s %(current_path)s" % { 'current_release':env.current_release, 'current_path':env.current_path })
展開手順全体を単一の全体にまとめます
def deploy(): """Deploys your project. This calls 'checkout','copy_config','migration','symlink','restart','cleanup'""" checkout() copy_config() symlink() restart()
リリースをクリーンアップする必要性を考慮してください。
def cleanup(): """Clean up old releases""" if not env.has_key('releases'): releases() if len(env.releases) > 10: directories = env.releases directories.reverse() del directories[:10] env.directories = ' '.join([ "%(releases_path)s/%(release)s" % { 'releases_path':env.releases_path, 'release':release } for release in directories ]) sudo("rm -rf %(directories)s" % { 'directories':env.directories })
リリース後に問題が発生した場合、以前のバージョンにすばやくロールバックする機能が必要です。
def rollback_code(): """Rolls back to the previously deployed version""" if not env.has_key('releases'): releases() if env.has_key('previous_release'): sudo("ln -nfs %(previous_release)s %(current_path)s && rm -rf %(current_release)s" % { 'current_release':env.current_release, 'previous_release':env.previous_release, 'current_path':env.current_path }) else: print "no releases older then current" sys.exit(1) def rollback(): """Rolls back to a previous version and restarts""" rollback_code() restart()
今日はすばらしい、十分なpython。
使用する
次のようにして、スクリプトで実行できるすべてのリストを取得できます。
$ fab --list Available commands: checkout Checkout code to the remote servers cleanup Clean up old releases copy_config Copy custom config to the remote servers deploy Deploys your project. This calls 'checkout','copy_config','migration','symlink','restart','cleanup' permissions Set proper permissions for release production Defines production environment releases List a releases made restart Restarts your application services rollback Rolls back to a previous version and restarts rollback_code Rolls back to the previously deployed version setup Prepares one or more servers for deployment symlink Updates the symlink to the most recently deployed version
さあ、サーバーにデプロイしましょう
$ fab production deploy [192.168.1.2] Executing task 'deploy' [192.168.1.2] run: /bin/date +%s [192.168.1.2] out: 1431941361 [192.168.1.2] out: [192.168.1.2] sudo: cd /apps/myapp.example.com/releases; git clone -q -b master --depth 1 git@git.example.com:myapp.git /apps/myapp.example.com/releases/1431941361 [192.168.1.2] sudo: ls -x /apps/myapp.example.com/releases [192.168.1.2] out: 1431940514 1431940525 1431940537 1431940547 1431940558 1431940568 1431940578 1431940589 1431940599 1431941361 [192.168.1.2] out: [192.168.1.2] put: config/config-production.php -> /tmp/config.php [192.168.1.2] sudo: cp /tmp/config.php /apps/myapp.example.com/releases/1431941361/config/ [192.168.1.2] run: rm /tmp/config.php [192.168.1.2] sudo: ln -nfs /apps/myapp.example.com/releases/1431941361 /apps/myapp.example.com/current [192.168.1.2] sudo: /etc/init.d/php-fpm reload [192.168.1.2] out: Reloading php-fpm: [18-May-2015 05:29:29] NOTICE: configuration file /etc/php-fpm.conf test is successful [192.168.1.2] out: [192.168.1.2] out: [ OK ] [192.168.1.2] out: [192.168.1.2] out: Done. Disconnecting from 192.168.1.2... done.
その結果、優れたツールが得られました。このツールは、わずかな変更を加えるだけで、さまざまな仕様を持つ多数のプロジェクトで使用できます。