这篇文章介绍deployer工具.

它支持并行部署,版本回退,可以很方便的编写命令并设置执行时机,并且支持很多主流的php框架提供开箱可用的一些方案.

使用deployer的情况下:

circleCI配置文件中的deployment模块需要修改,其中dep -v deploy staging命令会执行当前目录中的deploy.php文件

deployment:

staging:

branch: develop

commands:

- curl -LO https://deployer.org/deployer.phar

- sudo mv deployer.phar /usr/local/bin/dep

- chmod +x /usr/local/bin/dep

- dep -v deploy test

- dep -v deploy staging

production:

branch: master

commands:

- curl -LO https://deployer.org/deployer.phar

- sudo mv deployer.phar /usr/local/bin/dep

- chmod +x /usr/local/bin/dep

- dep -v deploy production

我使用的deployer的一个例子:

要说明一下脚本中的几个host,其实是有三组host,里面的stage分别是test/staging/production对应不同的环境,这个不是这篇文章的重点所以不介绍.

并且host配置的这么奇怪是因为host不能重名...所以我就各种办法...

namespace Deployer;

require 'recipe/laravel.php';

use Symfony\Component\Console\Input\InputOption;

//dep -vv deploy --first true --branch develop -- test

option('first', null, InputOption::VALUE_OPTIONAL, 'If first deploy.');

// Configuration

set('repository', 'git@github.com:never615/easy-admin.git');

set('allow_anonymous_stats', false);

// Hosts

host('server-1.xxx.com', 'server-2.xxx.com')

->stage('production')

->set("branch", "master")

->user("user")

->port("88888")

->set('deploy_path', '/app/xxx/easy_admin/production')

->forwardAgent(true)

->multiplexing(true)

->addSshOption('UserKnownHostsFile', '/dev/null')

->addSshOption('StrictHostKeyChecking', 'no');

host('119.23.111.111', '120.76.111.112')

->stage('staging')

->set("branch", "develop")

->user("user")

->port("88888")

->set('deploy_path', '/app/xxx/easy_admin/staging')

->forwardAgent(true)

->multiplexing(true)

->addSshOption('UserKnownHostsFile', '/dev/null')

->addSshOption('StrictHostKeyChecking', 'no');

host('test')

->hostname('119.23.111.111')

->stage('test')

->set("branch", "develop")

->user("user")

->port("88888")

->set('deploy_path', '/app/xxx/easy_admin/test')

->forwardAgent(true)

->addSshOption('UserKnownHostsFile', '/dev/null')

->addSshOption('StrictHostKeyChecking', 'no');

// Tasks

desc('first deploy');

task('deploy:first', function () {

if (input()->hasOption('first')) {

$first = input()->getOption('first');

if ($first) {

run('{{bin/php}} {{release_path}}/artisan tool:install');

run('{{bin/php}} {{release_path}}/artisan admin:install');

run('{{bin/php}} {{release_path}}/artisan user:install');

run('{{bin/php}} {{release_path}}/artisan mall:install');

run('{{bin/php}} {{release_path}}/artisan activity:install');

//生成的key需要各个地方一样

// run('{{bin/php}} {{release_path}}/artisan passport:install');

// run('{{bin/php}} {{release_path}}/artisan passport:keys');

run('{{bin/php}} {{release_path}}/artisan passport:client --personal');

}

}

});

desc('update');

task('deploy:update',function(){

run('yes|{{bin/php}} {{release_path}}/artisan tool:update');

run('yes|{{bin/php}} {{release_path}}/artisan admin:update');

run('yes|{{bin/php}} {{release_path}}/artisan user:update');

run('yes|{{bin/php}} {{release_path}}/artisan mall:update');

run('yes|{{bin/php}} {{release_path}}/artisan activity:update');

});

task('deploy:chown_chgrp',function(){

run('sudo chown -R nginx {{release_path}}');

run('sudo chgrp -R www {{release_path}}');

run('sudo chmod -R 775 {{release_path}}');

});

desc('copy env');

task('deploy:cp_env', 'cp .env.{{stage}} .env');

desc('copy composer');

task('deploy:cp_composer', 'cp composer.json.circle composer.json');

desc('Restart PHP-FPM service');

task('php-fpm:restart', function () {

// The user must have rights for restart service

// /etc/sudoers: username ALL=NOPASSWD:/bin/systemctl restart php-fpm.service

run('sudo systemctl restart php-fpm.service');

});

task("artisan:vendor", '

php artisan queue:restart;

');

after('deploy:symlink', 'php-fpm:restart');

after('deploy:update_code', 'deploy:cp_env');

after('deploy:update_code', 'deploy:cp_composer');

// [Optional] if deploy fails automatically unlock.

after('deploy:failed', 'deploy:unlock');

// first deploy run

after('artisan:vendor', 'deploy:first');

// plugin install

after('artisan:vendor', 'deploy:update');

after('deploy:symlink', 'deploy:chown_chgrp');

// publish vendor

before('deploy:symlink', 'artisan:vendor');

// Migrate database before symlink new release.

before('deploy:symlink', 'artisan:migrate');

于是新的部署流程如下:

部署流程

平时在开发环境直接使用文件上传的方式更新代码

每开发完成一个功能,就提交代码到开发分支(github)

提交到github后会触发钩子,CircleCI开始执行测试,然后使用deployer部署代码到各服务器

测试没有问题后,提交代码到master分支,会自动部署到各服务器的正式环境

整个部署流程,不需要人参与,就像平常一样,开发完一个功能提交到github而已.

参考:

php代码部署工具,代码部署(三):使用部署工具deployer并配合github+circle进行部署相关推荐

  1. python自动化工具之pywinauto(三)_自动化工具之三:pywinauto

    Python自动化工具:pywinauto 一.pywinauto的安装 (1)安装命令 pip install -U pywinauto/pip3 install -U pywinauto (2)验 ...

  2. python自动化工具之pywinauto(三)

    python自动化工具之pywinauto(三) python自动化工具之pywinauto三 问题分析 解决方案 选择源文件 配置参数 输出路径选择 等待窗口出现 问题分析 上篇尝试使用脚本进行模拟 ...

  3. Jenkins 在 Tomcat 中的部署及代码静态检查工具集成

    Jenkins 的简单部署 在安装了 Jenkins 运行所需的依赖(主要是 JDK)之后,可以通过如下步骤简单快速地部署 Jenkins: 下载 Jenkins. 打开终端并切换至下载目录. 运行命 ...

  4. 自动化代码部署、代码回滚、命令执行软件之capistrano

    Hi,本周第一天没什么事,所以就先分享一下我研究自动化代码部署与回滚软件的经验.这个软件有什么用途?主要是解决自动进行代码的部署,避免手动部署时出现错误,节省时间,同时在出现问题的时候,能回滚到之前的 ...

  5. 大厂如何开发和部署前端代码?淘宝8年案例解读

    在加入淘宝后,经历了大大小小的开发和部署方式的更迭,同时也有幸在整个的变革潮流中参与过其中的一些能力的建设.今天从一个亲历者的角度,通过自身经历与向同事考究,从"13年石器时代". ...

  6. 基于 Kubernetes 的微服务部署即代码

    在基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以及它的 ...

  7. 大公司里怎样开发和部署前端代码?

    这是一个非常有趣的 非主流前端领域,这个领域要探索的是如何用工程手段解决前端开发和部署优化的综合问题,入行到现在一直在学习和实践中. 在我的印象中,facebook是这个领域的鼻祖,有兴趣.有梯子的同 ...

  8. 微服务开发及部署_基于 Kubernetes 的微服务部署即代码

    在基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以及它的 ...

  9. 阿里云code结合git管理代码,运用webHook同步部署服务器代码(php)

    项目场景: 阿里云code结合git管理代码,运用webHook同步部署服务器代码(php) 问题描述: git生成密钥时linux用户为root,php运行用户是www.结果导致在服务器端git p ...

最新文章

  1. spring 单例 获取多例的位_Spring 获取单例流程(一)
  2. 精益创新之设计思维研磨——《设计改变一切》书评
  3. 框架:Mybatis开发规范及输入输出映射配置时注意事件
  4. Thinking in java第一章对象导论
  5. nosql非关系型数据库_从Datomic出发,革命性的非NoSQL数据库
  6. TVM:使用 Auto-scheduling 来优化算子
  7. 概要设计 英文_JavaScript 中的位运算和权限设计
  8. java session 过期判断_session过期时间是多少?如何查看session是否过期?
  9. c语言中math的作用,C语言常用的math函数
  10. Lab: Username enumeration via subtly different responses 通过细微的差别的响应来甄别用户名靶场复盘
  11. 泰文utf-8转unicode编码实现
  12. 论文查重是怎么查的?有什么规定?
  13. windows7 专业版安装中文语言包
  14. linux(centos)内核升级
  15. c语言模拟计算机指令流程图,家居分布式温度监测报警系统-传感器课程设计报告 带程序及仿真全套资料...
  16. 约瑟夫环问题的几种解法
  17. msp430 abs函数 c语言,实现一个简单的msp430软件
  18. [转]CATT的功能介绍
  19. 计算机文化基础试题集:
  20. 电脑连上网络,但是上不了网,IP变成了169.254.X.X问题解决!!!

热门文章

  1. uniapp自定义导航栏遮住了手机状态栏问题
  2. python制作GIF动图
  3. html 自动返回首页,mui页面跳转,进入子页面后自动回到首页
  4. 未来又一新热点,共享房屋初创公司正在起飞
  5. HAL库 编译错误:XXX.axf: Error: L6218E: Undefined symbol xxx (referred from xxxx.o)的可能原因之一及解决方法
  6. 互联网大厂程序员梦醒时分:攒够400万,到40岁退休
  7. android+解锁图案错误次数多+老人,手贱密码图案解锁错了15次,不做死就不会死~!...
  8. 【服务器数据恢复】OceanStor存储中NAS卷数据丢失的数据恢复案例
  9. 同城两中心自适应同步模式部署
  10. DAX: DIVIDE函数 vs 除法操作符