ããã«ã¡ã¯ï¼ æ±äº¬ãªã®ã«å¨è¾ºã«ãã±ã¹ãããã1ã¤ããªãç°èã«ä½ãã§ãã¾ãã@fortkle ã§ãï¼ä¸ç°è°·å ¬åã®å¾æ©åå ã«å¼ã£è¶ãããã§ãï¼ã
ãã¦ãã¿ãªããã¯PHPã¢ããªã±ã¼ã·ã§ã³ã®ãããã¤ãã¼ã«ã«ä½ã使ã£ã¦ããã§ããããã
ä»åã³ããã㧠Deployer ã¨ããPHPã§æ¸ããããããã¤ãã¼ã«ãæ¡ç¨ããã®ã§ããããªãDeployerãªã®ãã¨ããçç±ã¨ãå®éã«ä½¿ã£ã¦ããããããã®è¨å®ãããã¤ãå
±æãããã¨æãã¾ãã
â» Deployerã®ã¤ã³ã¹ãã¼ã«æ¹æ³ãåºæ¬çãªä½¿ãæ¹ãç¥ãããå ´åã¯æ¢ã«ã¤ã³ã¿ã¼ãããä¸ã«è¯ãè¨äºãããããããã®ã§ãã¡ããåèã«ãã¦ã¿ã¦ãã ããã
ãããã¤ãã¼ã«ãã©ãããï¼
ä»åãæ°ããå°è¦æ¨¡PHPã¢ããªã±ã¼ã·ã§ã³ããããã¤ããæ©ä¼ããã£ãããä¸è¨ã®æ¡ä»¶ã§æ°ãããããã¤ãã¼ã«ã®é¸å®ãè¡ãã¾ããã
- PHPã®ã¢ããªã±ã¼ã·ã§ã³ãªã®ã§ ãããã¤ãã¼ã«ãPHP製ã®ãã® ãæ¡ç¨ããã
- 対象ãã¹ãã1å°ãç¨åº¦ã®å°è¦æ¨¡ã¢ããªã±ã¼ã·ã§ã³ãªã®ã§ ãµãã¨æ軽ã«ããã㤠ããã
- CSSãJavaScriptãªã©ã®ãã«ããã¼ã«ã®çæç© ãGit管çãããã対象ãã¹ãä¸ã§ã³ã³ãã¤ã«ãããããã«ãããã¤ããã
ãã®æ¡ä»¶ãå ã«ããã¤ãã®ãããã¤ãã¼ã«ã試ããæçµçã« Deployer ãæ¡ç¨ãã¾ããã
Deployerã«ãããããã¤ã®å©ç¹
1. PHPã«çµ±ä¸ãããä¸ç
ããã¾ã§ã³ãããã§ã¯ãããã¤ãã¼ã«ã¨ãã¦Ruby製ã®Capistranoãå©ç¨ãã¦ãã¾ãããCapistranoã¯ãããã¤ãã¼ã«ã®ããã¡ã¯ãã¹ã¿ã³ãã¼ãã¨ãªã£ã¦ããåªãããã¼ã«ã§ãããRubyã§æ¸ããã¦ããããPHPã§ãµã¼ãã¹éçºããã¦ããã³ãããã§ã¯ä¸è¨ã®ãããªèª²é¡ãããã¾ããã
- PHPã®ããã¸ã§ã¯ããªã®ã«ãããã¤ããããã ãã«Rubyãgemã®ãã¼ã¸ã§ã³ã«æ°ã使ããªãã¨ãããªã
- æ¡å¼µã»éç¨ããã«ãRubyã§è¨è¿°ããªããã°ãªããªãããããããã¤å¨ãã®å¦çã®éç¨ã»æ¹åããã人ãéããã
PHPã§æ¸ãããDeployerãªãããã®åé¡ã¯ããã¾ããã
2. ãµãã¨æ軽ã«ãããã¤ã§ãã
å°è¦æ¨¡ãªã¢ããªã±ã¼ã·ã§ã³ãªã®ã§ãã¾ãã³ã¹ããæããã«ãã§ããã°Webã¨ã³ã¸ãã¢ã ãã§ãµãã¨æ軽ã«ãããã¤ã§ããããããçæ³ã§ãããã®ããã«ã¯ãããã¤ãã¼ã«èªä½ãã·ã³ãã«ã§ç°¡åã§ãããã¨ãæ±ãããã¾ãã
ãã®ç¹ã«ããã¦ãDeployer ã¯ä»ã®ãããã¤ãã¼ã«ã«æ¯ã¹ã¦å®æ度ã¯é«ããå¦ç¿ã³ã¹ãã¯ä½ãã¨ãã使ãããããã¼ã«ã«ãªã£ã¦ãã¾ããä»åã¯å°è¦æ¨¡ã®ã¢ããªã±ã¼ã·ã§ã³ã§ããã大è¦æ¨¡ãªã¢ããªã±ã¼ã·ã§ã³ã®ãããã¤ã«ãååèãããå®æ度ã ã¨æãã¾ãã
試ãã« å ¬å¼ã®ããã¥ã¡ã³ã ã«è¨è¼ããã¦ããDeployerã®è¨å®ãã¡ã¤ã«ãè¦ã¦ã¿ã¾ãããã ã¡ãªã¿ã«Deployerã®è¨å®ãã¡ã¤ã«ã¯ãã® PHP 1ãã¡ã¤ã«ã ã ã§ãã
<?php // Symfonyã®ã¬ã·ããrequire require 'recipe/symfony.php'; // ãããã¤å ã¨ãªããã¹ããµã¼ãã¼ã®è¨å® server('prod', 'host', 22) ->user('name') ->forwardAgent() // ã¨ã¼ã¸ã§ã³ããã©ã¯ã¼ãã£ã³ã°ãæå¹å ->stage('production') ->env('deploy_path', '/your/project/path'); // ãããã¤ãããã¹ãæå® // ãããã¤ããã³ã¼ãã管çãã¦ãããªãã¸ã㪠set('repository', '[email protected]:org/app.git');
ã©ãã§ããããï¼Deployerã«è§¦ã£ãäºããªã人ã§ãã³ã¼ããè¦ãã ãã§ä½ãè¨å®ãã¦ããã®ãæ³åã§ãããã§ããï¼
Deployer ã¯è¨å®ãã¡ã¤ã«ã ãã§ãªããã¤ã³ã¹ãã¼ã«ãcomposerã®ããã«pharãã¡ã¤ã«ãç½®ãã ãã§ä½¿ããã¨ãã§ãã¾ããããããã¤ã®å®è¡ãç°¡åã§ãã詳細ã«ã¤ãã¦ã¯ å ¬å¼ã®ããã¥ã¡ã³ããèªãã§ã¿ã¦ãã ããã
3. çæç©ã®ãããã¤
å°è¦æ¨¡PHPã¢ããªã±ã¼ã·ã§ã³ããããã¤ããéã«ãCSSãJavaScriptãªã©ã®ãã«ããã¼ã«ã®çæç©ãã©ããããã¤ããããã¨ããè«ç¹ãããã¾ãã
æ¹æ³ã¨ãã¦ã¯çæç©èªä½ãGitãªãã¸ããªã«å«ãããåãã¹ãã§ã³ã³ãã¤ã«ãããããæ¹æ³ãæãæµ®ãã³ã¾ãããGitãªãã¸ããªã«å«ãããã¨ã¯ãªãã¸ããªãè¥å¤§åããåå ã«ãªãã¾ãããåãã¹ãã§ã³ã³ãã¤ã«ãè¡ãã®ããã¹ãæ°ã1å°å¢ãããã³ã«ã³ã³ãã¤ã«ç°å¢ãæ§ç¯ããå¿ è¦ãããã¾ããä½ããå ¨å°ã§åããã¨ãããã®ã¯ãªã½ã¼ã¹ã®ç¡é§ã§ãã
ãã®ç¹ã«ãã㦠Deployer ã¯ã¢ãããã¼ãæ©æ§ãæ¨æºã§ç¨æããã¦ããããããã¼ã«ã«ã§ã³ã³ãã¤ã«ããCSSãJavaScriptãªã©ã®ãã«ããã¼ã«ã®çæç©ãç°¡åã«åãã¹ãã«é å¸ãããã¨ãã§ãã¾ãã
å®éã«ä½¿ã£ã¦ããããããã®è¨å®
ã³ãããã§å®éã«ä½¿ç¨ãã¦ããè¨å®ãããã¤ãå ±æãããã¨æãã¾ãã
ãã¼ã«ã«ã¢ãããã¼ãã¨ç¢ºèª
ã¢ãããã¼ãç¨ã®Taskãè¨å®ããã°ãã¼ã«ã«ã«ãããã¡ã¤ã«ãåãã¹ãã«ã¢ãããã¼ããããã¨ãã§ãã¾ãã
<?php task('deploy:upload', function () { if (askConfirmation('ãã¼ã«ã«ã®CSS, JSããããã¤å ã«ã¢ãããã¼ããã¦ãããããã§ããï¼', true)) { $appFiles = [ 'webroot/css', 'webroot/js', ]; $releasePath = env('release_path'); foreach ($appFiles as $file) { upload("../{$file}", "{$releasePath}/{$file}"); } } else { writeln("<info>ãããã¤ãä¸æ¢ãã¾ããã</info>"); die(); } })->desc('Upload static file');
upload("../{$file}", "{$releasePath}/{$file}");
ã®é¨åãå®éã«ã¢ãããã¼ããã¦ããç®æã§ã$appFiles
ã§å®£è¨ãããã¡ã¤ã«ã¨ãã£ã¬ã¯ããªãã¢ãããã¼ããã¾ãã
ãã¤ã³ãã¯2ç¹ããã¾ãã
1ç¹ç®ã¯ askConfirmation()
ã使ã£ã¦æ¬å½ã«ãã¼ã«ã«ã®ãã¡ã¤ã«ãã¢ãããã¼ãããã確èªãã¦ããç¹ã§ããæå³ãã誤ã£ã¦ãã¼ã«ã«ã®ãã¡ã¤ã«ãã¢ãããã¼ããã¦ãã¾ã£ãããä¸éå端ãªç¶æ
ã®ãã¡ã¤ã«ãã¢ãããã¼ãããããããã¨ãããç¨åº¦é²ããã¨ãã§ãã¾ãï¼CIãªã©ããã§ã¯ãªãæåã§å®è¡ããå ´å100%é²ããã¨ã¯ã§ãã¾ããï¼ã
$ php deployer.phar deploy --tag v0.1.0 production â Executing task deploy:prepare â Executing task deploy:release â Executing task deploy:update_code ⤠Executing task deploy:upload ãã¼ã«ã«ã®CSS, JSããããã¤å ã«ã¢ãããã¼ããã¦ãããããã§ããï¼ [Y/n]
2ç¹ç®ã¯ askConfirmation()
ã®ç¬¬2å¼æ°ã true
ã«ãããã¨ã§ããã©ã«ãã§ã¢ãããã¼ãããããã«ãã¦ãããã¨ã§ãï¼é常ã¯ããã©ã«ãfalseï¼ãããã®ä½ãå¬ãããã¨ããã¨ãDeployerã«ã¯yes/noã®ãããªå¯¾è©±å¼ã®å¦çãç¡è¦ãã¦ããã©ã«ãå¤ã使ã£ã¦ããã --no-interaction
ã¨ãããªãã·ã§ã³ãããã®ã§ãCIãµã¼ãã¼ãªã©èªåã§ãããã¤ã³ãã³ããå©ãéã«ãã®ãªãã·ã§ã³ãä»ããã°å¯¾è©±å¦çãã¹ããããã¦ãããã¤ãå®è¡ã§ãã¾ãã
// é常 $ php deployer.phar deploy --tag v0.0.2 production // 対話ç¡è¦ï¼ããã©ã«ãå¤ã使ãï¼â CIãªã©ã§ã $ php deployer.phar deploy --tag v0.0.2 --no-interaction production
ãã¼ã«ããã¯ã®ãã³ãã表示
ãããã¤ã ãã§ãªããã¼ã«ããã¯ãç°¡åã«å®è¡ã§ãããã¨ãéè¦ã§ãã Deployer ã¯$ php deployer.phar rollback production
ãªã©ã¨æã¦ã°ç°¡åã«ãã¼ã«ããã¯ã§ããæ©æ§ãæåããè¨å®ããã¦ãã¾ãã
ãããããã¼ã«ããã¯ãå¿
è¦ãªæã¨ããã®ã¯ç·æ¥åº¦ã®é«ããã°ãªã©ãçºçãã¦ããç¶æ³ãå¤ãããããæã«éã£ã¦äººã¯ãã¹ãããã¡ã§ããããã§ä¸ãä¸ã®éã«æ
ã¦ãã«ãã¹ãªãç°¡åã«ãã¼ã«ããã¯ã§ããããã«ãã³ãã表示*1ãã¦ã¿ã¾ãããã
<?php task('rollback_hint', function () { $stage = input()->getArgument('stage'); $message = "\nãã³ãï¼ãã¼ã«ããã¯ãããå ´åã¯ä»¥ä¸ã®ã³ãã³ããå®è¡ãã¾ããã\n"; $message .= "<info>$ php deployer.phar rollback {$stage}</info>\n\n"; $message .= "ãã³ãï¼ã¿ã°ãæå®ãã¦ãããã¤ãããå ´åã¯ä»¥ä¸ã®ã³ãã³ããå®è¡ãã¾ããã\n"; $message .= "<info>$ php deployer.phar deploy --tag {TAG_NAME} {$stage}</info>\n"; writeln($message); })->desc('Show rollback hint message');
ä¸è¨ã³ã¼ãã è¨å®ãã¡ã¤ã«deploy.php
ã«è¨è¿°ãã¦ãããã¤ã«æåããå¾ã«è¡¨ç¤ºãã¦ãããã¨ä¸è¨ã®ããã«ãã³ãã表示ããã¾ãã
$ php deployer.phar deploy --tag v0.1.0 production â Executing task deploy:prepare â Executing task deploy:release â Executing task deploy:update_code â Executing task deploy:symlink â Executing task cleanup ⤠Executing task success Successfully deployed! â Ok ⤠Executing task rollback_hint ãã³ãï¼ãã¼ã«ããã¯ãããå ´åã¯ä»¥ä¸ã®ã³ãã³ããå®è¡ãã¾ããã $ php deployer.phar rollback production ãã³ãï¼ã¿ã°ãæå®ãã¦ãããã¤ãããå ´åã¯ä»¥ä¸ã®ã³ãã³ããå®è¡ãã¾ããã $ php deployer.phar deploy --tag {TAG_NAME} production
ãã®ããã«å®è¡ãã¹ãã³ãã³ãããã®ã¾ã¾è¡¨ç¤ºãããã®ã§ã³ããããã ãã§å®å¿ãã¦ãã¼ã«ããã¯ãããã¨ãã§ãã¾ãã
SSHã¨ã¼ã¸ã§ã³ããã©ã¯ã¼ãã£ã³ã°
deployerã¯SSHã¨ã¼ã¸ã§ã³ããã©ã¯ã¼ãã£ã³ã°ããµãã¼ããã¦ãã¾ãã
ãããã¤å
ãµã¼ãã¼ä¸ã§ãã£ã¦ãããã¼ã«ã«ã«ããç§å¯éµã使ã£ã¦Githubã¨ã®èªè¨¼ãã§ããã®ã§é常ã«ä¾¿å©ã§ãã
ï¼äºåã«ãã¼ã«ã«ã§ $ ssh-add
ããã¦ç§å¯éµãç»é²ãã¦ããå¿
è¦ãããã¾ã ï¼
<?php server('prod', 'host', 22) ->user('name') ->forwardAgent() // âãã®1è¡ã追å ãã¦æå¹å ->stage('production') ->env('deploy_path', '/your/project/path');
æå¾ã«
ãããã ã£ãã§ããããï¼ ä»å㯠Deployer ãé¸ãã çç±ã¨ããããã®è¨å®ãããã¤ããç´¹ä»ãã¾ããã
Deployer ã¯æ¬å½ã«ç°¡åã«ãããã¤ãèªååã§ããã®ã§ããã¾ã¾ã§ãããã¤ãã¼ã«ã使ã£ããã¨ããªã人ããããã¾ã§ä»ã®ãã¼ã«ã使ã£ã¦ããæ¹ã¾ã§å
¨å¡ã«ãªã¹ã¹ã¡ã§ãã¾ãã
ã¢ããªã±ã¼ã·ã§ã³ã®è¦æ¨¡ãæ§æã«ãã£ã¦é©ãããããã¤ãã¼ã«ã¯å¤åãã¦ããã¾ãããå°è¦æ¨¡ã¢ããªã±ã¼ã·ã§ã³ã®ãããã¤ã§ Deployer ã試ãã¦ã¿ã¦ãã ããï¼
*1:ãã®ã¢ã¤ãã¢ã¯ 失æããåæã§ãããã¤ãã ã¨ããè¨äºãåèã«ãã¾ãããããã¦ãªã大äºï¼