部署工具

如果你为你的项目代码在使用一个版本控制系统,例如Git,将发布包推到远程库,你可以使用Git中的git pull命令来部署代码到你的生产服务器上,而不用手动上传文件。此外,你可以给自己写一个shell脚本来拉取新的库提交,更新vendors,应用migration等等。

但是,有很多工具可以用来做自动化部署。在本小节中,我们来看一些名叫Deployer的工具。

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的yii2-app-basic应用。

如何做…

如果你有一个共享的远程库,你可以使用它用来部署源。

第一步:准备远程host

  1. 到你的远程host,安装Composer以及asset-plugin
  1. global require 'fxp/composer-asset-plugin:~1.1.1'
  1. 使用ssh-kengen生成SSH秘钥。
  2. 添加~/.ssh/id_rsa.pub文件内容到你的库设置页面中(部署SSH秘钥页面),例如Github、Bitbucket或者其它库存储。
  3. 尝试游动克隆的库:
  1. git clone git@github.com:user/repo.git
  1. 添加Github地址,以及已知的host列表(如果你的系统问你要的话)。

第二步:准备localhost

  1. 在本地全局安装deploy.phar
  1. sudo wget http://deployer.org/deployer.phar
  2. sudo mv deployer.phar /usr/local/bin/dep
  3. sudo chmod +x /usr/local/bin/dep
  1. 使用部署配置添加deploy.php文件:
  1. <?php
  2. require 'recipe/yii2-app-basic.php';
  3. set('shared_files', [
  4. 'config/db.php',
  5. 'config/params.php',
  6. 'web/index.php',
  7. 'yii',
  8. ]);
  9. server('prod', 'site.com', 22) // SSH access to remote server
  10. ->user('user')
  11. // ->password(password) // uncomment for authentication by
  12. password
  13. // ->identityFile() // uncomment for authentication by SSH key
  14. ->stage('production')
  15. ->env('deploy_path', '/var/www/project');
  16. set('repository', 'git@github.com:user/repo.git');
  1. 尝试准备远程项目目录结构:
  1. dep deploy:prepare prod

第三步:添加远程配置

  1. 打开服务器的/var/www/project目录。初始化后它有两个子目录:
  1. project
  2. ├── releases
  3. └── shared
  1. shared文件中创建带有私有配置的原始文件:
  1. project
  2. ├── releases
  3. └── shared
  4. ├── config
  5. ├── db.php
  6. └── params.php
  7. ├── web
  8. └── index.php
  9. └── yii

Deployer工具将会在每一个发布的子目录中通过软连接的方式包含这些文件:

share/config/db.php文件中指定你的私有配置:

  1. <?php
  2. return [
  3. 'class' => 'yii\db\Connection',
  4. 'dsn' => 'mysql:host=localhost;dbname=catalog',
  5. 'username' => 'root',
  6. 'password' => 'root',
  7. 'charset' => 'utf8',
  8. ];

此外,在share/config/params.php中指定它:

  1. <?php
  2. return [
  3. 'adminEmail' => 'admin@example.com',
  4. ];

设置文件share/web/index.php的内容:

  1. <?php
  2. defined('YII_DEBUG') or define('YII_DEBUG', false);
  3. defined('YII_ENV') or define('YII_ENV', 'prod');
  4. $dir = dirname($_SERVER['SCRIPT_FILENAME']);
  5. require($dir . '/../vendor/autoload.php');
  6. require($dir . '/../vendor/yiisoft/yii2/Yii.php');
  7. $config = require($dir . '/../config/web.php');
  8. (new yii\web\Application($config))->run();

此外,设置share/yii文件的内容:

  1. #!/usr/bin/env php
  2. <?php
  3. defined('YII_DEBUG') or define('YII_DEBUG', false);
  4. defined('YII_ENV') or define('YII_ENV', 'prod');
  5. $dir = dirname($_SERVER['SCRIPT_FILENAME']);
  6. require($dir . '/vendor/autoload.php');
  7. require($dir . '/vendor/yiisoft/yii2/Yii.php');
  8. $config = require($dir. '/config/console.php');
  9. $application = new yii\console\Application($config);
  10. $exitCode = $application->run();
  11. exit($exitCode);

注意:我们故意使用dirname($_SERVER['SCRIPT_FILENAME']),而不是原始的__DIR__常量,因为如果这个文件时软连接的话,__DIR__将会返回不正确的值。

注意:如果你使用yii2-app-advanced模板,你可以只重定义config/main-local.phpconfig/params-local.php文件(backend、frontend、console和common),因为web/index.phpyii将会自动通过init命令生成。

第四步:尝试部署

  1. 回到本地,使用deploy.php文件,并运行部署命令:
  1. dep deploy prod

部署工具 - 图1

  1. 如果成功,你将会看到部署报告:
  2. Deployer在你的远程服务器上,创建一个新的发布子目录,并从你的项目到共享的items,以及从current目录到当前发布添加软连接:
  1. project
  2. ├── current -> releases/20160412140556
  3. ├── releases
  4. └── 20160412140556
  5. ├── ...
  6. ├── runtime -> /../../shared/runtime
  7. ├── web
  8. ├── vendor
  9. ├── ...
  10. └── yii -> /../../shared/yii
  11. └── shared
  12. ├── config
  13. ├── db.php
  14. └── params.php
  15. ├── runtime
  16. ├── web
  17. └── index.php
  18. └── yii
  1. 所有这些完成以后,你必须在project/current/web目录中设置你的服务器DocumentRoot
  2. 如果在部署过程中,发生了一些错误,你可以回滚到先前的发布上:
  1. dep rollback prod

current目录将会定向到你先前的发布文件上。

工作原理…

大部分的部署工具都做了同样的任务:

  • 创建一个新的发布子目录
  • 克隆库文件
  • 从项目中制作软连接到共享的目录上,以及到本地配置文件上
  • 安装Composer包
  • 应用项目migration
  • 从服务器的DocumentRoot路径上切换软链接到当前发布目录上

Deployer工具为流行的框架都做了预定义。你可以扩展任何已有的例子,或者为你的特殊的例子制作新的。

参考