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. ٕज़తෛ࠴Λฦࡁ͢Δ
    ʢ%FW0QTฤʣ
    ώΧϥϘc

    View full-size slide

  2. ࣗݾ঺հ
    ळࢁݦ࣏ ,FOKJ"LJZBNB

    !
    גࣜձࣾϋ΢ςϨϏδϣϯ
    ΤϯδχΞ
    ೥݄ࢀը
    !
    UXJUUFS!BSUJGBDUTBVDF
    HJUIVC!BSUJGBDUTBVDF
    (,FOKJ"LJZBNB

    View full-size slide

  3. εΩϧηοτ
    ‣ 1FSM
    ‣ 1)1
    ‣ 3VCZ
    ‣ )5.-$44
    ‣ +BWBTDSJQU
    ‣ $P⒎FFTDSJQU
    ‣ -JOVY
    ‣ 4PMBSJT
    ‣ .Z42-
    ‣ 1PTUHSF42-
    ‣ ֤छ8"'
    ‣ FUDʜ

    View full-size slide

  4. ࢓ࣄ΋ϓϥΠϕʔτ΋
    ஍ຯͳ໾ׂ͕େ޷͖

    View full-size slide

  5. ҎલͷΩϟϦΞ
    ཧֶ̋ݚڀॴʹ೥΄Ͳ
    !
    w ੜ෺σʔλͷղੳ
    w σʔλϕʔεߏங
    w 8FCΞϓϦ։ൃ
    !
    ίϯϐϡʔλʔपΓͷ͜ͱͳ
    ΒΘΓͱԿͰ΋

    View full-size slide

  6. ࠷ॳʹ·ͱΊ
    ‣ σϓϩΠ͕ഒߴ଎ʹͳΓ·ͨ͠ɻ
    ‣ αʔόʔߏங͕ഒߴ଎ʹͳΓ·ͨ͠ɻ
    ஫ʣ౰ࣾൺ

    View full-size slide

  7. ΞδΣϯμ
    ‣ ര଎։ൃͷ੒ΕͷՌͯ
    ‣ σϓϩΠ͕ഒ଎$BQJTUSBOP
    ‣ αʔόʔߏங͕ഒ଎$IFG

    View full-size slide

  8. ര଎։ൃͷ੒ΕͷՌͯ

    View full-size slide

  9. ര଎։ൃͷ੒ΕͷՌͯ
    ٕज़తෛ࠴͕ཷ·ͬ
    ͪ·ͬͨΑʔ

    View full-size slide

  10. ྫʣίʔυ
    ‣ ཧղෆೳͳม਺໊
    ‣ DPOEͱDPOEͬͯԿ͕ҧ͏ͷʁ
    ‣ ཧղෆೳͳϝιου໊
    ‣ IBT3FDPSEͷฦΓ஋͕഑ྻʁ
    ‣ ॏෳͨ͠ϝιου
    ‣ ༵೔Λฦ͢ϝιου͕ͭ༗Γ·͚͢Ͳ

    View full-size slide

  11. ྫʣΦϖϨʔγϣϯ
    ‣ ϢʔβʔΞΧ΢ϯτ͕ڞ༗
    ‣ ͝ʜ͝৑ஊͰ͢ΑͶʁ
    ‣ ຊ൪؀ڥͱ։ൃ؀ڥͰϑΝΠϧʹ͕ࠩ͋Δ
    ‣ ͑ʜʁ͝৑ஊͰ͢ΑͶʁ
    ‣ ։ൃऀݸਓͷಠࣗσϓϩΠखॱ
    ‣ ͝৑ஊͰ͢ΑͶʁ͝৑ஊͰ͢ΑͶʁ
    ‣ υΩϡϝϯτෆ଍
    ‣ ͦΕͬͯυΩϡϝϯτɺ͋Γ·͔͢ʁ

    View full-size slide

  12. ͳͥ͜͏ͳͬͨʁ
    ‣ ͕࣌ؒແ͍
    ‣ ίʔυͷ඼࣭ͳͲʹ࣌ؒΛ͔͚͍ͯΔ༨༟͸
    ແ͍ɻ
    ‣ γεςϜͷޮ཰ԽͳͲʹ࣌ؒΛ͔͚͍ͯΔ༨
    ༟͸ແ͍ɻ
    ‣ খن໛Ώ͑ͷશೳײ
    ‣ ΄ͱΜͲࣗ෼͕࡞ͬͨͷͰ͍͍ͩͨΘ͔ͬͯ
    ͍Δɻ

    View full-size slide

  13. ͔͠͠ɺͦΕͰ͍͍
    ‣ རӹΛੜΉલʹαʔϏεͷ࠷దԽΛ࢝Ίͯ
    Ͳ͏͢Δʁ
    ‣ ઌԆ͹͠Ͱ͖Δ͏ͪ͸ઌԆ͹ͯ͠͠ྑ͍ɻ

    View full-size slide

  14. ͔͠͠ɺͦͷ··Ͱ͸͍͚ͳ͍
    ‣ ͍ͭ΍Δ͔ʁ

    View full-size slide

  15. ͔͠͠ɺͦͷ··Ͱ͸͍͚ͳ͍
    ‣ ͍ͭ΍Δ͔ʁ

    View full-size slide

  16. ʮࠓͰ͠ΐʂʁʯ͸͍ͭʁ
    ‣ αʔϏε͔Βऩӹ͕ग़ͯҰଉ͚ͭͨ
    ‣ ։ൃऀ͕ਓΛ௒͑ͨ
    ‣ όά͕සൃ͖ͯͨ͠

    View full-size slide

  17. ٕज़తෛ࠴Λ
    ฦࡁ͍ͯ͜͠͏

    View full-size slide

  18. ༏ઌॱҐ
    ‣ ։ൃͷఀ଺ʹಛʹڧ͍ӨڹΛٴ΅͍ͯ͠Δ
    ΋ͷ
    ‣ ೾ٴޮՌ͕ߴ͍΋ͷ
    ‣ ࡞ۀίετ͕ॆ෼ʹ௿͍΋ͷ

    View full-size slide

  19. ։ൃʗӡ༻ϓϩηεͷվળ
    ‣ ࣗಈԽ
    ‣ ΞϓϦέʔγϣϯͷ
    σϓϩΠ
    ‣ αʔόʔߏஙʗӡ༻

    View full-size slide

  20. جຊํ਑
    ‣ γϯϓϧͰ͋Δ͜ͱ

    View full-size slide

  21. ΞϓϦέʔγϣϯͷ
    σϓϩΠͷࣗಈԽ

    View full-size slide

  22. ͔ͭͯͷσϓϩΠखॱ
    (JUͷ։ൃϒϥϯν͔ΒANBTUFSAϒϥϯν΁Ϛʔδ͢Δ
    ࡞ۀͷ։࢝Λ4MBDLͰશһʹ௨஌͢Δ
    લճͷσϓϩΠ͔Βมߋͷ͋ͬͨϑΝΠϧ͚ͩΛαʔόʔʹίϐʔ͢Δ
    ݱߦόʔδϣϯͷσΟϨΫτϦΛ৽ͨͳόʔδϣϯ໊Λ෇͚ͯίϐʔ͢
    Δ
    αʔόʔʹίϐʔͨ͠ϑΝΠϧͰ৽όʔδϣϯσΟϨΫτϦͷϑΝΠϧ
    Λ্ॻ͖͢Δ
    ݱߦόʔδϣϯͷσΟϨΫτϦΛࢦ͢4ZNMJOLΛɺ৽όʔδϣϯσΟϨ
    ΫτϦΛࢦ͢Α͏ʹ࡞੒͠௚͢
    $BDIFϑΝΠϧΛ࡟আ͢Δ
    QIQGQNΛ࠶ىಈ͢Δ
    ࡞ۀͷऴྃΛ4MBDLͰશһʹ௨஌͢Δ

    View full-size slide

  23. ͔ͭͯͷσϓϩΠखॱ
    # 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

    View full-size slide

  24. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  25. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  26. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  27. ࣗಈԽͷԸܙ
    ࣌ؒ
    UBLFOCZIJQQPOPUJ[FE

    View full-size slide

  28. ࣗಈԽͷԸܙ
    ࣌ؒ
    UBLFOCZIJQQPOPUJ[FE

    UBLFOCZQIPUPOT

    View full-size slide

  29. ࣗಈԽͷԸܙ
    ࣌ؒ
    UBLFOCZIJQQPOPUJ[FE

    UBLFOCZQIPUPOT

    View full-size slide

  30. $BQJTUSBOPEFQMPZ
    Current
    "QQ4FSWFS (JU4FSWFS
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  31. $BQJTUSBOPEFQMPZ
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  32. $BQJTUSBOPEFQMPZ
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  33. $BQJTUSBOPEFQMPZ
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  34. $BQJTUSBOPEFQMPZ
    New
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  35. $BQJTUSBOPEFQMPZ
    New
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  36. $BQJTUSBOPEFQMPZ
    New
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  37. $BQJTUSBOPEFQMPZ
    New
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  38. $BQJTUSBOPEFQMPZ
    New
    Current
    "QQ4FSWFS (JU4FSWFS
    $ cap production deploy
    σϑΥϧτͰ༻ҙ͞Ε͍ͯΔEFQMPZλεΫ

    View full-size slide

  39. 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ͷσϓϩΠϑϨʔϜϫʔΫͷ࢖͍ํ
    աڈܗͰه͞Ε͍ͯΔλεΫ͸ۭͷλεΫ
    ͳͷͰ͜ΕΒΛඞཁʹԠ্ͯ͡ॻ͖͢Δ

    View full-size slide

  40. ͲΜͳίʔυʁ
    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

    View full-size slide

  41. ͲΜͳίʔυʁ
    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ϥΠϒϥϦ΁
    ϦϯΫΛுΔ

    View full-size slide

  42. ͲΜͳίʔυʁ
    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ͰϓϥάΠϯ
    ΛΠϯετʔϧ͢Δ

    View full-size slide

  43. ͲΜͳίʔυʁ
    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ͰϓϥάΠϯ
    ΛΠϯετʔϧ͢Δ
    σʔλϕʔεϚΠάϨʔ
    γϣϯΛ࣮ߦ͢Δ

    View full-size slide

  44. ͲΜͳίʔυʁ
    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ϑΝΠϧ
    ΛίϯύΠϧ͢Δ
    σʔλϕʔεϚΠάϨʔ
    γϣϯΛ࣮ߦ͢Δ

    View full-size slide

  45. ͲΜͳίʔυʁ
    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ϑΝΠϧ
    ΛίϯύΠϧ͢Δ
    σʔλϕʔεϚΠάϨʔ
    γϣϯΛ࣮ߦ͢Δ
    ΞϓϦέʔγϣϯಛҟతͳλεΫΛ௥
    ه͍ͯ͘͠

    View full-size slide

  46. ͲΜͳίʔυʁ
    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

    View full-size slide

  47. ͲΜͳίʔυʁ
    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ΛϦελʔτ͢Δ

    View full-size slide

  48. ͲΜͳίʔυʁ
    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λεΫͷޙ
    ʹ࣮ߦͯ͠Ͷὑ

    View full-size slide

  49. ͲΜͳίʔυʁ
    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λεΫͷޙ
    ʹ࣮ߦͯ͠Ͷὑ
    Ϧελʔτ͢ΔલʹΩϟο
    γϡΛফ͠ͱ͍ͯͶὑ

    View full-size slide

  50. ͲΜͳίʔυʁ
    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͢Δ

    View full-size slide

  51. ͲΜͳίʔυʁ
    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௨஌͢Δํ๏

    View full-size slide

  52. ͲΜͳίʔυʁ
    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௨஌͢Δํ๏

    View full-size slide

  53. ͲΜͳίʔυʁ
    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ͷؔ਺
    Λݺͼग़͢

    View full-size slide

  54. ͲΜͳίʔυʁ
    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Ͱ֦ு͢Δ

    View full-size slide

  55. σϓϩΠࣗಈԽͷԸܙ
    ‣ ϛε͕֨ஈʹݮΓɺ։ൃ଎౓্͕͕ͬͨ
    ‣ σϓϩΠʹର͢Δ৺ཧతোน͕Լ͕ͬͨ
    ‣ ίʔυԽ͞ΕΔ͜ͱͰ࡞ۀ͕໌֬ʹͳͬͨ

    View full-size slide

  56. ͢΂͕ͯ͏·͍ͬͨ͘
    ΋͏೰ΈͳΜͯແ͍

    View full-size slide

  57. ͦΜͳΘ͚ͳ͍
    ͢΂͕ͯ͏·͍ͬͨ͘
    ΋͏೰ΈͳΜͯແ͍

    View full-size slide

  58. ಋೖίετ
    ‣ ଍ֻ͚̏ϲ݄Ґʢ̏ਓ݄ʣ
    ‣ ίετʹӨڹΛ༩͑Δཁૉ
    ‣ ΞϓϦͷن໛
    ‣ ΞϓϦͷෳࡶ͞
    ‣ ։ൃऀͷ஌ࣝྔ

    View full-size slide

  59. ࣗಈԽͰ͖ͳ͔ͬͨ͜ͱ
    ‣ 8PSE1SFTTͷσϓϩΠ
    ‣ ϓϥάΠϯͷ໰୊ͳͲ
    ‣ 8FCΞϓϦ֎ͷ͜ͱ
    ‣ DSPOUBC
    ‣ ϦόʔεϓϩΩγͷઃఆ
    ‣ 8"'ʢ$BLF1)1ʣͷΞοϓάϨʔυ

    View full-size slide

  60. αʔόʔߏஙʗӡ༻
    ͷࣗಈԽ

    View full-size slide

  61. αʔόʔɹͦΕ͸ɹ࠷΋ҋ͕ਂ͘ɺ࠷΋ೖΓࠐΈͮΒ͍৔ॴ

    View full-size slide

  62. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ

    View full-size slide

  63. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ

    View full-size slide

  64. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    Θ͔ΒΜ

    View full-size slide

  65. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    Θ͔ΒΜ

    View full-size slide

  66. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ

    View full-size slide

  67. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,

    View full-size slide

  68. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,
    ͋ͷɺTVEPͰ͖ͳ͍ΜͰ͚͢Ͳʜ

    View full-size slide

  69. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,
    ͋ͷɺTVEPͰ͖ͳ͍ΜͰ͚͢Ͳʜ
    ͋ɺ͝ΊΜ๨Εͯͨ

    View full-size slide

  70. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    ͋Εʁຊ൪αʔόʔͷ04ͬͯʜɻ͜ͷόʔδϣϯɺ΋͏αϙʔτ੾ΕͯΜ͡ΌΜɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,
    ͋ͷɺTVEPͰ͖ͳ͍ΜͰ͚͢Ͳʜ
    ͋ɺ͝ΊΜ๨Εͯͨ

    View full-size slide

  71. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    ͋Εʁຊ൪αʔόʔͷ04ͬͯʜɻ͜ͷόʔδϣϯɺ΋͏αϙʔτ੾ΕͯΜ͡ΌΜɻ
    ͳΜͱ͔ύοέʔδͷΠϯετʔϧͰ͖͚ͨͲόʔδϣϯݹ͍Θʔɻ
    ιʔε͔ΒΠϯετʔϧ͠ͳ͖Ό͍͚ͳ͍ͷ͔ʔɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,
    ͋ͷɺTVEPͰ͖ͳ͍ΜͰ͚͢Ͳʜ
    ͋ɺ͝ΊΜ๨Εͯͨ

    View full-size slide

  72. ΞϓϦͷσϓϩΠ͢ΔͨΊʹ͸"ΛΠϯετʔϧ͠ͳ͖Όɻ
    ͢Έ·ͤΜɺ"ͬͯΠϯετʔϧ͞Εͯ·͔͢ʁ
    ͠ΐ͏͕͍ͳ͍ࣗ෼Ͱ͔֬ΊΔ͔ɻ·ͣ͸ΞΧ΢ϯτ࡞Βͳ͖Όɻ
    ͋Εʁຊ൪αʔόʔͷ04ͬͯʜɻ͜ͷόʔδϣϯɺ΋͏αϙʔτ੾ΕͯΜ͡ΌΜɻ
    ͳΜͱ͔ύοέʔδͷΠϯετʔϧͰ͖͚ͨͲόʔδϣϯݹ͍Θʔɻ
    ιʔε͔ΒΠϯετʔϧ͠ͳ͖Ό͍͚ͳ͍ͷ͔ʔɻ
    ͏͛ʔɺϥΠϒϥϦ͕ݹ͍ͬͯݴΘΕͨΘʔɻίϯύΠϧ௨ΒͶʔɻ
    Θ͔ΒΜ
    ΞΧ΢ϯτ࡞ͬͯ͘Ε·͔͢ʁ
    0,
    ͋ͷɺTVEPͰ͖ͳ͍ΜͰ͚͢Ͳʜ
    ͋ɺ͝ΊΜ๨Εͯͨ

    View full-size slide

  73. ໰୊఺
    ‣ Ͳ͜ͷαʔόʔʹԿ͕Πϯετʔϧ͞Εͯ
    ͍Δͷ͔൑વͱ͠ͳ͍ɻ
    ‣ ఆܕԽ͞Ε͍ͯͳ͍ΦϖϨʔγϣϯ͕ϛε
    Λ༠͍ͬͯΔɻ
    ‣ ҠߦͷࣦഊΛڪΕͯαʔόʔΛ৐Γ׵͑Δ
    ͜ͱ͕Ͱ͖ͳ͍ɻ

    View full-size slide

  74. ࣗಈԽͷԸܙ

    UBLFOCZHMJOETBZ

    View full-size slide

  75. ࣗಈԽͷԸܙ

    UBLFOCZHMJOETBZ
    ࣌ؒ
    UBLFOCZEFOOJT

    View full-size slide

  76. ࣗಈԽͷԸܙ

    UBLFOCZHMJOETBZ
    ࣌ؒ
    UBLFOCZEFOOJT

    View full-size slide

  77. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  78. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  79. ࣗಈԽͷԸܙ
    # 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

    View full-size slide

  80. $IFG
    ‣ #FSLTpMF
    ‣ DPPLCPPLT
    ‣ EBUB@CBHT
    ‣ FOWJSPONFOUT
    ‣ OPEFT
    ‣ SPMFT
    ‣ TJUFDPPLCPPLT

    View full-size slide

  81. ͲΜͳίʔυʁ
    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

    View full-size slide

  82. ͲΜͳίʔυʁ
    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
    σΟϨΫτϦΛ࡞੒͢Δ

    View full-size slide

  83. ͲΜͳίʔυʁ
    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
    σΟϨΫτϦΛ࡞੒͢Δ
    ϦϞʔτ͔ΒϑΝΠϧΛ
    औͬͯ͘Δ

    View full-size slide

  84. ͲΜͳίʔυʁ
    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
    σΟϨΫτϦΛ࡞੒͢Δ
    ϦϞʔτ͔ΒϑΝΠϧΛ
    औͬͯ͘Δ
    ର৅σΟϨΫτϦʹղౚ͢Δ

    View full-size slide

  85. ͲΜͳίʔυʁ
    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-ʹͳ͍ͬͯΔ

    View full-size slide

  86. ͲΜͳίʔυʁ
    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

    View full-size slide

  87. ͲΜͳίʔυʁ
    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
    ઃఆ஋Λ্ॻ͖͢Δ͜ͱͰ
    ࠶ར༻Ͱ͖Δ

    View full-size slide

  88. ࣗಈԽͷԸܙ
    ‣ ϛε͕֨ஈʹݮΓɺ࡞ۀ͕࣌ؒݮͬͨɻ
    ‣ αʔόʔΛ૿΍͢৺ཧతোน͕Լ͕ͬͨɻ
    ‣ ίʔυԽ͞ΕΔ͜ͱͰ࡞ۀ͕໌֬ʹͳͬͨɻ

    View full-size slide

  89. ࣗಈԽͷԸܙ
    ‣ ϛε͕֨ஈʹݮΓɺ࡞ۀ͕࣌ؒݮͬͨɻ
    ‣ αʔόʔΛ૿΍͢৺ཧతোน͕Լ͕ͬͨɻ
    ‣ ίʔυԽ͞ΕΔ͜ͱͰ࡞ۀ͕໌֬ʹͳͬͨɻ
    ΞϓϦέʔγϣϯσϓϩΠͷ
    ࣗಈԽͷࡍͱಉ͡

    View full-size slide

  90. ͢΂͕ͯ͏·͍ͬͨ͘
    ΋͏೰ΈͳΜͯແ͍

    View full-size slide

  91. ͦΜͳΘ͚ͳ͍
    ͢΂͕ͯ͏·͍ͬͨ͘
    ΋͏೰ΈͳΜͯແ͍

    View full-size slide

  92. ಋೖίετ
    ‣ ଍ֻ͚िؒҐʢਓ݄ʣ
    ‣ ίετʹӨڹΛ༩͑Δཁૉ
    ‣ ߏ੒ͷෳࡶ͞
    ‣ ։ൃऀͷ஌ࣝྔ
    ‣ ʢϗετͷن໛ʹ͸ΑΒͳ͍ʣ

    View full-size slide

  93. ࣗಈԽͰ͖ͳ͔ͬͨ͜ͱ
    ‣ 04ͷΠϯετʔϧΛࣗಈԽ͢Δɻ
    ‣ ,JDLTUBSUPS1SFTFFEʹΑΔࣗಈ࡞੒
    ‣ 04ΠϝʔδϑΝΠϧ͔Βੜ੒

    View full-size slide

  94. ࣗಈԽͰ͖ͳ͔ͬͨ͜ͱ
    ‣ 04ͷΠϯετʔϧΛࣗಈԽ͢Δɻ
    ‣ ,JDLTUBSUPS1SFTFFEʹΑΔࣗಈ࡞੒
    ‣ 04ΠϝʔδϑΝΠϧ͔Βੜ੒
    ͢΂ͯͷαʔόʔ͕
    ࣗಈ؅ཧͷର৅ʹͳ͍ͬͯΔ
    Θ͚Ͱ͸ͳ͍

    View full-size slide

  95. ΋͏Ұ౓·ͱΊ
    ‣ σϓϩΠ͕ഒߴ଎ʹͳΓ·ͨ͠ɻ
    ‣ αʔόʔߏங͕ഒߴ଎ʹͳΓ·ͨ͠ɻ
    ஫ʣ౰ࣾൺ

    View full-size slide

  96. ໨ࢦ͢ͱ͜Ζ
    ‣ ܧଓతσϦόϦʔʁ
    ‣ #MVF(SFFO%FQMPZNFOUʁ
    ‣ *NNVUBCMF*OGSBTUSVDUVSFʁ

    View full-size slide

  97. ͍ͣΕʹ͠Ζɺ
    ͕͜͜௨ա఺

    View full-size slide

  98. ׬
    ࣍͸ฐࣾ૆ࢁΑΓʮٕज़తෛ࠴Λղফ͢ΔʢΞδϟΠϧฤʣʯ

    View full-size slide