Upgrade to Pro — share decks privately, control downloads, hide ads and more …

技術的負債を返済する(DevOps編)

 技術的負債を返済する(DevOps編)

【 ヒカ☆ラボ 】スタートアップの草創期/成長期に求められる技術とは!? ~年率600%の成長を続けるリクルーティングプラットフォームを開発する企業が実践するDevOpsとスクラム開発を語ります~

http://at-agent.jp/service/event/127/

Kenji Akiyama

October 09, 2014
Tweet

More Decks by Kenji Akiyama

Other Decks in Programming

Transcript

  1. εΩϧηοτ ‣ 1FSM ‣ 1)1 ‣ 3VCZ ‣ )5.-$44 ‣

    +BWBTDSJQU ‣ $P⒎FFTDSJQU ‣ -JOVY ‣ 4PMBSJT ‣ .Z42- ‣ 1PTUHSF42- ‣ ֤छ8"' ‣ FUDʜ
  2. ྫʣΦϖϨʔγϣϯ ‣ ϢʔβʔΞΧ΢ϯτ͕ڞ༗ ‣ ͝ʜ͝৑ஊͰ͢ΑͶʁ ‣ ຊ൪؀ڥͱ։ൃ؀ڥͰϑΝΠϧʹ͕ࠩ͋Δ ‣ ͑ʜʁ͝৑ஊͰ͢ΑͶʁ ‣

    ։ൃऀݸਓͷಠࣗσϓϩΠखॱ ‣ ͝৑ஊͰ͢ΑͶʁ͝৑ஊͰ͢ΑͶʁ ‣ υΩϡϝϯτෆ଍ ‣ ͦΕͬͯυΩϡϝϯτɺ͋Γ·͔͢ʁ
  3. ͔ͭͯͷσϓϩΠखॱ  (JUͷ։ൃϒϥϯν͔ΒANBTUFSAϒϥϯν΁Ϛʔδ͢Δ  ࡞ۀͷ։࢝Λ4MBDLͰશһʹ௨஌͢Δ  લճͷσϓϩΠ͔Βมߋͷ͋ͬͨϑΝΠϧ͚ͩΛαʔόʔʹίϐʔ͢Δ  ݱߦόʔδϣϯͷσΟϨΫτϦΛ৽ͨͳόʔδϣϯ໊Λ෇͚ͯίϐʔ͢ Δ

     αʔόʔʹίϐʔͨ͠ϑΝΠϧͰ৽όʔδϣϯσΟϨΫτϦͷϑΝΠϧ Λ্ॻ͖͢Δ  ݱߦόʔδϣϯͷσΟϨΫτϦΛࢦ͢4ZNMJOLΛɺ৽όʔδϣϯσΟϨ ΫτϦΛࢦ͢Α͏ʹ࡞੒͠௚͢  $BDIFϑΝΠϧΛ࡟আ͢Δ  QIQGQNΛ࠶ىಈ͢Δ  ࡞ۀͷऴྃΛ4MBDLͰશһʹ௨஌͢Δ
  4. ͔ͭͯͷσϓϩΠखॱ # local ! $ git checkout master $ git

    pull $ git merge DEV_BRANCH $ PAGER=cat git diff --name-status LAST_TAG CRRT_TAG \ > > file_diff.txt $ grep '^D' file_diff.txt > file_del.txt $ grep -v '^D' file_diff.txt > file_mod.txt $ grep '\w\s*wordpress' file_diff.txt > file_wdp.txt $ perl -i -ple '/\.scss$/ \ > && s/(sass|scss$)/css/g’ file_mod.txt $ bundle exec compass compile $ mkdir -p DEST_DIR $ perl -ple 's/^\w\s+//' file_mod.txt \ > | xargs -I% rsync -R % DEST_DIR $ cp file_del.txt DEST_DIR $ scp -r DEST_DIR REMOTE_HOST:~/DEST_DIR ! # remote ! $ cd DEPLOY_TO $ sudo -u DEPLOY_USER cp -apr LAST_TAG CRRT_TAG $ sudo -u DEPLOY_USER rsync -av DEST_DIR DEPLOY_TO/ \ > CRRT_TAG $ cd DEPLOY_TO/CRRT_TAG $ perl -ple 's/^D\s+//' file_del.txt | xargs rm $ sudo -u DEPLOY_USER ln -snf DEPLOY_TO/CRRT_TAG WEB_ROOT $ sudo find CAKE1_APP_CACHE -type f -exec rm {} \; $ sudo find CAKE2_APP_CACHE -type f -name 'empty' -prune \ > -o -type f -exec rm {} \; $ sudo service php5-fpm restart
  5. ࣗಈԽͷԸܙ # local ! $ git checkout master $ git

    pull $ git merge DEV_BRANCH $ PAGER=cat git diff --name-status LAST_TAG CRRT_TAG \ > > file_diff.txt $ grep '^D' file_diff.txt > file_del.txt $ grep -v '^D' file_diff.txt > file_mod.txt $ grep '\w\s*wordpress' file_diff.txt > file_wdp.txt $ perl -i -ple '/\.scss$/ \ > && s/(sass|scss$)/css/g’ file_mod.txt $ bundle exec compass compile $ mkdir -p DEST_DIR $ perl -ple 's/^\w\s+//' file_mod.txt \ > | xargs -I% rsync -R % DEST_DIR $ cp file_del.txt DEST_DIR $ scp -r DEST_DIR REMOTE_HOST:~/DEST_DIR ! # remote ! $ cd DEPLOY_TO $ sudo -u DEPLOY_USER cp -apr LAST_TAG CRRT_TAG $ sudo -u DEPLOY_USER rsync -av DEST_DIR DEPLOY_TO/ \ > CRRT_TAG $ cd DEPLOY_TO/CRRT_TAG $ perl -ple 's/^D\s+//' file_del.txt | xargs rm $ sudo -u DEPLOY_USER ln -snf DEPLOY_TO/CRRT_TAG WEB_ROOT $ sudo find CAKE1_APP_CACHE -type f -exec rm {} \; $ sudo find CAKE2_APP_CACHE -type f -name 'empty' -prune \ > -o -type f -exec rm {} \; $ sudo service php5-fpm restart
  6. ࣗಈԽͷԸܙ # local ! $ git checkout master $ git

    pull $ git merge DEV_BRANCH $ PAGER=cat git diff --name-status LAST_TAG CRRT_TAG \ > > file_diff.txt $ grep '^D' file_diff.txt > file_del.txt $ grep -v '^D' file_diff.txt > file_mod.txt $ grep '\w\s*wordpress' file_diff.txt > file_wdp.txt $ perl -i -ple '/\.scss$/ \ > && s/(sass|scss$)/css/g’ file_mod.txt $ bundle exec compass compile $ mkdir -p DEST_DIR $ perl -ple 's/^\w\s+//' file_mod.txt \ > | xargs -I% rsync -R % DEST_DIR $ cp file_del.txt DEST_DIR $ scp -r DEST_DIR REMOTE_HOST:~/DEST_DIR ! # remote ! $ cd DEPLOY_TO $ sudo -u DEPLOY_USER cp -apr LAST_TAG CRRT_TAG $ sudo -u DEPLOY_USER rsync -av DEST_DIR DEPLOY_TO/ \ > CRRT_TAG $ cd DEPLOY_TO/CRRT_TAG $ perl -ple 's/^D\s+//' file_del.txt | xargs rm $ sudo -u DEPLOY_USER ln -snf DEPLOY_TO/CRRT_TAG WEB_ROOT $ sudo find CAKE1_APP_CACHE -type f -exec rm {} \; $ sudo find CAKE2_APP_CACHE -type f -name 'empty' -prune \ > -o -type f -exec rm {} \; $ sudo service php5-fpm restart # local ! $ cap production deploy
  7. ࣗಈԽͷԸܙ # local ! $ git checkout master $ git

    pull $ git merge DEV_BRANCH $ PAGER=cat git diff --name-status LAST_TAG CRRT_TAG \ > > file_diff.txt $ grep '^D' file_diff.txt > file_del.txt $ grep -v '^D' file_diff.txt > file_mod.txt $ grep '\w\s*wordpress' file_diff.txt > file_wdp.txt $ perl -i -ple '/\.scss$/ \ > && s/(sass|scss$)/css/g’ file_mod.txt $ bundle exec compass compile $ mkdir -p DEST_DIR $ perl -ple 's/^\w\s+//' file_mod.txt \ > | xargs -I% rsync -R % DEST_DIR $ cp file_del.txt DEST_DIR $ scp -r DEST_DIR REMOTE_HOST:~/DEST_DIR ! # remote ! $ cd DEPLOY_TO $ sudo -u DEPLOY_USER cp -apr LAST_TAG CRRT_TAG $ sudo -u DEPLOY_USER rsync -av DEST_DIR DEPLOY_TO/ \ > CRRT_TAG $ cd DEPLOY_TO/CRRT_TAG $ perl -ple 's/^D\s+//' file_del.txt | xargs rm $ sudo -u DEPLOY_USER ln -snf DEPLOY_TO/CRRT_TAG WEB_ROOT $ sudo find CAKE1_APP_CACHE -type f -exec rm {} \; $ sudo find CAKE2_APP_CACHE -type f -name 'empty' -prune \ > -o -type f -exec rm {} \; $ sudo service php5-fpm restart # local ! $ cap production deploy UBLFOCZXJFENBJFS
  8. EFQMPZUBTL ‣ EFQMPZTUBSUJOH ‣ EFQMPZDIFDL ‣ HJUDIFDL ‣ EFQMPZDIFDLEJSFDUPSJFT ‣

    EFQMPZDIFDLMJOLFE@EJST ‣ EFQMPZDIFDLNBLF@MJOLFE@EJST ‣ EFQMPZDIFDLMJOLFE@pMFT ‣ EFQMPZTUBSUFE ‣ EFQMPZVQEBUJOH ‣ HJUDSFBUF@SFMFBTF ‣ EFQMPZTZNMJOLTIBSFE ‣ EFQMPZTZNMJOLMJOLFE@pMFT ‣ EFQMPZTZNMJOLMJOLFE@EJST ‣ EFQMPZVQEBUFE ‣ EFQMPZQVCMJTIJOH ‣ EFQMPZTZNMJOLSFMFBTF ‣ EFQMPZQVCMJTIFE ‣ EFQMPZpOJTIJOH ‣ EFQMPZDMFBOVQ ‣ EFQMPZpOJTIFE $BQJTUSBOPͷσϓϩΠϑϨʔϜϫʔΫͷ࢖͍ํ աڈܗͰه͞Ε͍ͯΔλεΫ͸ۭͷλεΫ ͳͷͰ͜ΕΒΛඞཁʹԠ্ͯ͡ॻ͖͢Δ
  9. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end
  10. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end $BLF1)1ϥΠϒϥϦ΁ ϦϯΫΛுΔ
  11. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end $BLF1)1ϥΠϒϥϦ΁ ϦϯΫΛுΔ DPNQPTFSͰϓϥάΠϯ ΛΠϯετʔϧ͢Δ
  12. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end $BLF1)1ϥΠϒϥϦ΁ ϦϯΫΛுΔ DPNQPTFSͰϓϥάΠϯ ΛΠϯετʔϧ͢Δ σʔλϕʔεϚΠάϨʔ γϣϯΛ࣮ߦ͢Δ
  13. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end $BLF1)1ϥΠϒϥϦ΁ ϦϯΫΛுΔ DPNQPTFSͰϓϥάΠϯ ΛΠϯετʔϧ͢Δ DPNQBTTͰTBTTϑΝΠϧ ΛίϯύΠϧ͢Δ σʔλϕʔεϚΠάϨʔ γϣϯΛ࣮ߦ͢Δ
  14. ͲΜͳίʔυʁ task :updated do on roles(:app) do ["cakephp1","cakephp2"].each do |cake_dir|

    ["cake", "lib", "index.php", "plugins", "vendors"].each do |part_dir| part_path = fetch(:deploy_to) + '/' + cake_dir + '/' + part_dir if test "[ -e #{part_path} ]" then execute :ln, '-snf', part_path, "#{fetch(:release_path)}/#{cake_dir}/#{part_dir}" end end end ! within "#{fetch(:release_path)}/cakephp2/app" do composer_path = "#{fetch(:release_path)}/cakephp2/app/composer.phar" if test "[ -f #{composer_path} ]" then execute "./composer.phar", 'install' end ! if fetch(:run_migration) then execute '../lib/Cake/Console/cake', 'Migrations.migration', 'run', 'all' end end ! if fetch(:sass_compile_path) then within "#{fetch(:release_path)}/#{fetch(:sass_compile_path)}" do execute :compass, 'compile', '--boring' end end ! end end $BLF1)1ϥΠϒϥϦ΁ ϦϯΫΛுΔ DPNQPTFSͰϓϥάΠϯ ΛΠϯετʔϧ͢Δ DPNQBTTͰTBTTϑΝΠϧ ΛίϯύΠϧ͢Δ σʔλϕʔεϚΠάϨʔ γϣϯΛ࣮ߦ͢Δ ΞϓϦέʔγϣϯಛҟతͳλεΫΛ௥ ه͍ͯ͘͠
  15. ͲΜͳίʔυʁ task :restart do on roles(:app, :wp) do execute :sudo,

    :service, 'php5-fpm', 'restart' end end ! after :publishing, :restart ! before :restart, :clear_cache do on roles(:app) do if fetch(:app_cache1_path) then execute :sudo, :find, fetch(:app_cache1_path), '-type f -exec rm {} \;' end if fetch(:app_cache2_path) then execute :sudo, :find, fetch(:app_cache2_path), '-type f -name "empty" -prune -o -type f -exec rm {} \;' end end end
  16. ͲΜͳίʔυʁ task :restart do on roles(:app, :wp) do execute :sudo,

    :service, 'php5-fpm', 'restart' end end ! after :publishing, :restart ! before :restart, :clear_cache do on roles(:app) do if fetch(:app_cache1_path) then execute :sudo, :find, fetch(:app_cache1_path), '-type f -exec rm {} \;' end if fetch(:app_cache2_path) then execute :sudo, :find, fetch(:app_cache2_path), '-type f -name "empty" -prune -o -type f -exec rm {} \;' end end end QIQGQNΛϦελʔτ͢Δ
  17. ͲΜͳίʔυʁ task :restart do on roles(:app, :wp) do execute :sudo,

    :service, 'php5-fpm', 'restart' end end ! after :publishing, :restart ! before :restart, :clear_cache do on roles(:app) do if fetch(:app_cache1_path) then execute :sudo, :find, fetch(:app_cache1_path), '-type f -exec rm {} \;' end if fetch(:app_cache2_path) then execute :sudo, :find, fetch(:app_cache2_path), '-type f -name "empty" -prune -o -type f -exec rm {} \;' end end end QIQGQNΛϦελʔτ͢Δ QVCMJTIJOHλεΫͷޙ ʹ࣮ߦͯ͠Ͷὑ
  18. ͲΜͳίʔυʁ task :restart do on roles(:app, :wp) do execute :sudo,

    :service, 'php5-fpm', 'restart' end end ! after :publishing, :restart ! before :restart, :clear_cache do on roles(:app) do if fetch(:app_cache1_path) then execute :sudo, :find, fetch(:app_cache1_path), '-type f -exec rm {} \;' end if fetch(:app_cache2_path) then execute :sudo, :find, fetch(:app_cache2_path), '-type f -name "empty" -prune -o -type f -exec rm {} \;' end end end QIQGQNΛϦελʔτ͢Δ QVCMJTIJOHλεΫͷޙ ʹ࣮ߦͯ͠Ͷὑ Ϧελʔτ͢ΔલʹΩϟο γϡΛফ͠ͱ͍ͯͶὑ
  19. ͲΜͳίʔυʁ task :restart do on roles(:app, :wp) do execute :sudo,

    :service, 'php5-fpm', 'restart' end end ! after :publishing, :restart ! before :restart, :clear_cache do on roles(:app) do if fetch(:app_cache1_path) then execute :sudo, :find, fetch(:app_cache1_path), '-type f -exec rm {} \;' end if fetch(:app_cache2_path) then execute :sudo, :find, fetch(:app_cache2_path), '-type f -name "empty" -prune -o -type f -exec rm {} \;' end end end QIQGQNΛϦελʔτ͢Δ QVCMJTIJOHλεΫͷޙ ʹ࣮ߦͯ͠Ͷὑ Ϧελʔτ͢ΔલʹΩϟο γϡΛফ͠ͱ͍ͯͶὑ طଘͷλεΫͷલޙʹ೚ҙͷλεΫΛ )PPL͢Δ
  20. ͲΜͳίʔυʁ namespace :notify do namespace :update do task :start do

    _send_message("[\`#{fetch(:application)}\`] Deployment has started.") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Deployment has finished. :ok_woman:\n> #{fetch(:commit_message)}") end end ! namespace :rollback do task :start do _send_message("[\`#{fetch(:application)}\`] Rollback has started.\nCurrent Revision is \`#{fetch(:latest_revision)}\`") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Rollback has finished. :ok_woman:\nCurrent revision is \`#{fetch(:current_revision)}\`") end end end ! before 'deploy:starting', 'notify:update:start' after 'deploy:finishing', 'notify:update:finish' before 'deploy:reverting', 'notify:rollback:start' after 'deploy:finishing_rollback', 'notify:rollback:finish' $BQJTUSBOPʹΑΔσϓϩΠͷ࣮ߦ࣌ʹ4MBDL௨஌͢Δํ๏
  21. ͲΜͳίʔυʁ namespace :notify do namespace :update do task :start do

    _send_message("[\`#{fetch(:application)}\`] Deployment has started.") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Deployment has finished. :ok_woman:\n> #{fetch(:commit_message)}") end end ! namespace :rollback do task :start do _send_message("[\`#{fetch(:application)}\`] Rollback has started.\nCurrent Revision is \`#{fetch(:latest_revision)}\`") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Rollback has finished. :ok_woman:\nCurrent revision is \`#{fetch(:current_revision)}\`") end end end ! before 'deploy:starting', 'notify:update:start' after 'deploy:finishing', 'notify:update:finish' before 'deploy:reverting', 'notify:rollback:start' after 'deploy:finishing_rollback', 'notify:rollback:finish' σϓϩΠ΍ϩʔϧόοΫͷ։࢝ऴྃ ͷલޙʹ௨஌ΛૹΔ $BQJTUSBOPʹΑΔσϓϩΠͷ࣮ߦ࣌ʹ4MBDL௨஌͢Δํ๏
  22. ͲΜͳίʔυʁ namespace :notify do namespace :update do task :start do

    _send_message("[\`#{fetch(:application)}\`] Deployment has started.") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Deployment has finished. :ok_woman:\n> #{fetch(:commit_message)}") end end ! namespace :rollback do task :start do _send_message("[\`#{fetch(:application)}\`] Rollback has started.\nCurrent Revision is \`#{fetch(:latest_revision)}\`") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Rollback has finished. :ok_woman:\nCurrent revision is \`#{fetch(:current_revision)}\`") end end end ! before 'deploy:starting', 'notify:update:start' after 'deploy:finishing', 'notify:update:finish' before 'deploy:reverting', 'notify:rollback:start' after 'deploy:finishing_rollback', 'notify:rollback:finish' σϓϩΠ΍ϩʔϧόοΫͷ։࢝ऴྃ ͷલޙʹ௨஌ΛૹΔ $BQJTUSBOPʹΑΔσϓϩΠͷ࣮ߦ࣌ʹ4MBDL௨஌͢Δํ๏ ఆٛͨ͠3VCZͷؔ਺ Λݺͼग़͢
  23. ͲΜͳίʔυʁ namespace :notify do namespace :update do task :start do

    _send_message("[\`#{fetch(:application)}\`] Deployment has started.") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Deployment has finished. :ok_woman:\n> #{fetch(:commit_message)}") end end ! namespace :rollback do task :start do _send_message("[\`#{fetch(:application)}\`] Rollback has started.\nCurrent Revision is \`#{fetch(:latest_revision)}\`") end ! task :finish do _send_message("[\`#{fetch(:application)}\`] Rollback has finished. :ok_woman:\nCurrent revision is \`#{fetch(:current_revision)}\`") end end end ! before 'deploy:starting', 'notify:update:start' after 'deploy:finishing', 'notify:update:finish' before 'deploy:reverting', 'notify:rollback:start' after 'deploy:finishing_rollback', 'notify:rollback:finish' σϓϩΠ΍ϩʔϧόοΫͷ։࢝ऴྃ ͷલޙʹ௨஌ΛૹΔ $BQJTUSBOPʹΑΔσϓϩΠͷ࣮ߦ࣌ʹ4MBDL௨஌͢Δํ๏ ఆٛͨ͠3VCZͷؔ਺ Λݺͼग़͢ 3VCZͰ֦ு͢Δ
  24. ࣗಈԽͷԸܙ # remote ! $ aptitude install nginx php5 php5-fpm

    php5-mysql php5-json php5-curl postfix build-essential tmux vim zsh $ sudo ufw enable $ sudo ufw allow 22 $ sudo ufw allow 80 $ sudo vi /etc/ssh/sshd_config $ sudo vi /etc/php5/fpm/pool.d/www.conf $ git clone https://github.com/sstephenson/rbenv.git \ > /opt/rbenv $ git clone https://github.com/sstephenson/ruby-build.git \ > ~/opt/rbenv/plugins/ruby-build $ export PATH=“/opt/rbenv/bin:$PATH" $ eval "$(rbenv init -)” $ rbenv install 2.1.3 $ gem install bundler … $ export PERLBREW_ROOT=“/opt/perlbrew” $ curl -L http://install.perlbrew.pl | bash $ perlbrew install perl-5.18.2 $ perlbrew switch perl-5.18.2 $ curl -L http://cpanmin.us | perl - —sudo \ > App::cpanminus $ cpanm Carton … $ sudo rm /etc/nginx/site-enabled/default $ sudo vi /etc/nginx/site-available/my-site $ sudo ln -s /etc/nginx/site-available/my-site \ > /etc/nginx/site-enabled/my-site … $ sudo adduser hoge $ sudo adduser fuga …
  25. ࣗಈԽͷԸܙ # remote ! $ aptitude install nginx php5 php5-fpm

    php5-mysql php5-json php5-curl postfix build-essential tmux vim zsh $ sudo ufw enable $ sudo ufw allow 22 $ sudo ufw allow 80 $ sudo vi /etc/ssh/sshd_config $ sudo vi /etc/php5/fpm/pool.d/www.conf $ git clone https://github.com/sstephenson/rbenv.git \ > /opt/rbenv $ git clone https://github.com/sstephenson/ruby-build.git \ > ~/opt/rbenv/plugins/ruby-build $ export PATH=“/opt/rbenv/bin:$PATH" $ eval "$(rbenv init -)” $ rbenv install 2.1.3 $ gem install bundler … $ export PERLBREW_ROOT=“/opt/perlbrew” $ curl -L http://install.perlbrew.pl | bash $ perlbrew install perl-5.18.2 $ perlbrew switch perl-5.18.2 $ curl -L http://cpanmin.us | perl - —sudo \ > App::cpanminus $ cpanm Carton … $ sudo rm /etc/nginx/site-enabled/default $ sudo vi /etc/nginx/site-available/my-site $ sudo ln -s /etc/nginx/site-available/my-site \ > /etc/nginx/site-enabled/my-site … $ sudo adduser hoge $ sudo adduser fuga … # local ! $ knife solo cookbook 192.168.0.1
  26. ࣗಈԽͷԸܙ # remote ! $ aptitude install nginx php5 php5-fpm

    php5-mysql php5-json php5-curl postfix build-essential tmux vim zsh $ sudo ufw enable $ sudo ufw allow 22 $ sudo ufw allow 80 $ sudo vi /etc/ssh/sshd_config $ sudo vi /etc/php5/fpm/pool.d/www.conf $ git clone https://github.com/sstephenson/rbenv.git \ > /opt/rbenv $ git clone https://github.com/sstephenson/ruby-build.git \ > ~/opt/rbenv/plugins/ruby-build $ export PATH=“/opt/rbenv/bin:$PATH" $ eval "$(rbenv init -)” $ rbenv install 2.1.3 $ gem install bundler … $ export PERLBREW_ROOT=“/opt/perlbrew” $ curl -L http://install.perlbrew.pl | bash $ perlbrew install perl-5.18.2 $ perlbrew switch perl-5.18.2 $ curl -L http://cpanmin.us | perl - —sudo \ > App::cpanminus $ cpanm Carton … $ sudo rm /etc/nginx/site-enabled/default $ sudo vi /etc/nginx/site-available/my-site $ sudo ln -s /etc/nginx/site-available/my-site \ > /etc/nginx/site-enabled/my-site … $ sudo adduser hoge $ sudo adduser fuga … # local ! $ knife solo cookbook 192.168.0.1 UBLFOCZXJFENBJFS
  27. ͲΜͳίʔυʁ directory service_dir do owner application_owner group application_owner mode '0755'

    action :create recursive true not_if { ::File.exists?(service_dir) } end ! remote_file "#{source_dir}/cakephp-#{cake_full_version_number}.tar.gz" do source "https://github.com/cakephp/cakephp/archive/#{cake_full_version_number}.tar.gz" mode "0644" action :create_if_missing end ! execute "untar-cakephp" do cwd source_dir command "tar -xzf cakephp-#{cake_full_version_number}.tar.gz" creates "#{source_cake_dir}/index.php" end
  28. ͲΜͳίʔυʁ directory service_dir do owner application_owner group application_owner mode '0755'

    action :create recursive true not_if { ::File.exists?(service_dir) } end ! remote_file "#{source_dir}/cakephp-#{cake_full_version_number}.tar.gz" do source "https://github.com/cakephp/cakephp/archive/#{cake_full_version_number}.tar.gz" mode "0644" action :create_if_missing end ! execute "untar-cakephp" do cwd source_dir command "tar -xzf cakephp-#{cake_full_version_number}.tar.gz" creates "#{source_cake_dir}/index.php" end σΟϨΫτϦΛ࡞੒͢Δ
  29. ͲΜͳίʔυʁ directory service_dir do owner application_owner group application_owner mode '0755'

    action :create recursive true not_if { ::File.exists?(service_dir) } end ! remote_file "#{source_dir}/cakephp-#{cake_full_version_number}.tar.gz" do source "https://github.com/cakephp/cakephp/archive/#{cake_full_version_number}.tar.gz" mode "0644" action :create_if_missing end ! execute "untar-cakephp" do cwd source_dir command "tar -xzf cakephp-#{cake_full_version_number}.tar.gz" creates "#{source_cake_dir}/index.php" end σΟϨΫτϦΛ࡞੒͢Δ ϦϞʔτ͔ΒϑΝΠϧΛ औͬͯ͘Δ
  30. ͲΜͳίʔυʁ directory service_dir do owner application_owner group application_owner mode '0755'

    action :create recursive true not_if { ::File.exists?(service_dir) } end ! remote_file "#{source_dir}/cakephp-#{cake_full_version_number}.tar.gz" do source "https://github.com/cakephp/cakephp/archive/#{cake_full_version_number}.tar.gz" mode "0644" action :create_if_missing end ! execute "untar-cakephp" do cwd source_dir command "tar -xzf cakephp-#{cake_full_version_number}.tar.gz" creates "#{source_cake_dir}/index.php" end σΟϨΫτϦΛ࡞੒͢Δ ϦϞʔτ͔ΒϑΝΠϧΛ औͬͯ͘Δ ର৅σΟϨΫτϦʹղౚ͢Δ
  31. ͲΜͳίʔυʁ directory service_dir do owner application_owner group application_owner mode '0755'

    action :create recursive true not_if { ::File.exists?(service_dir) } end ! remote_file "#{source_dir}/cakephp-#{cake_full_version_number}.tar.gz" do source "https://github.com/cakephp/cakephp/archive/#{cake_full_version_number}.tar.gz" mode "0644" action :create_if_missing end ! execute "untar-cakephp" do cwd source_dir command "tar -xzf cakephp-#{cake_full_version_number}.tar.gz" creates "#{source_cake_dir}/index.php" end σΟϨΫτϦΛ࡞੒͢Δ ϦϞʔτ͔ΒϑΝΠϧΛ औͬͯ͘Δ ର৅σΟϨΫτϦʹղౚ͢Δ 3VCZͷ%4-ʹͳ͍ͬͯΔ
  32. ͲΜͳίʔυʁ default['gsskt-cakephp']['app_name'] = 'hogehoge' ! default['gsskt-cakephp']['http_server_owner'] = 'hoge' default['gsskt-cakephp']['application_owner'] =

    'fuga' default['gsskt-cakephp']['deploy_parent'] = '/home/hoge' ! default['gsskt-cakephp']['cake1']['version'] = "1.3.0" default['gsskt-cakephp']['cake1']['debug_level'] = 0 default['gsskt-cakephp']['cake1']['use_analytics'] = true ! default['gsskt-cakephp']['cake2']['version'] = “2.1.0" default['gsskt-cakephp']['cake2']['debug_level'] = 0 default['gsskt-cakephp']['cake2']['use_analytics'] = true
  33. ͲΜͳίʔυʁ default['gsskt-cakephp']['app_name'] = 'hogehoge' ! default['gsskt-cakephp']['http_server_owner'] = 'hoge' default['gsskt-cakephp']['application_owner'] =

    'fuga' default['gsskt-cakephp']['deploy_parent'] = '/home/hoge' ! default['gsskt-cakephp']['cake1']['version'] = "1.3.0" default['gsskt-cakephp']['cake1']['debug_level'] = 0 default['gsskt-cakephp']['cake1']['use_analytics'] = true ! default['gsskt-cakephp']['cake2']['version'] = “2.1.0" default['gsskt-cakephp']['cake2']['debug_level'] = 0 default['gsskt-cakephp']['cake2']['use_analytics'] = true ઃఆ஋Λ্ॻ͖͢Δ͜ͱͰ ࠶ར༻Ͱ͖Δ