文档章节

少年,是时候换种更优雅的方式部署你的php代码了

码王信息
 码王信息
发布于 2017/04/22 20:45
字数 2657
阅读 1718
收藏 68
点赞 4
评论 13

让我们来回忆下上次你是怎么发布你的代码的:

1. 先把线上的代码用ftp备份下来

2. 上传修改了的文件

3. 测试一下功能是否正常

4. 网站500了,赶紧用备份替换回去

5. 替换错了/替换漏了

6. 一台服务器发布成功

7. 登录每一台执行一遍发布操作

8. 加班搞定

9. 老板发飙

...

尤其现在的互联网行业,讲究快速迭代,小步快跑。像bug修复或者小功能的修改几乎每天都发版本,大功能的版本迭代每周也差不多会有一次。相信不少同行们像我上面说的这样发布自己的代码吧。或者可能先进一点,直接去服务器上执行一条类似git pull的命令拖下仓库中的代码,但是如果你的代码运行在集群中呢?每台机器登录一次执行一次git pull吗?如果发现代码有问题需要回滚呢?

如果你还在像我上面说的这种方式部署自己的代码的话,那么我希望你能耐心看完这篇文章,从此摆脱代码部署之痛。

 

其实绕了这么一圈今天是想向大家介绍一下用php写的代码发布工具:deployer。

deployer具有以下吸引人的特性:

- 快速      采用了比如并发发布、ssh通道复用、缓存可用情况下使用缓存等技术加速代码部署

- 原子部署   在新发布的版本内执行所有定义的操作,诸如下载依赖、设置文件访问权限等都不会直接影响线上,只有全部成功后,最后一步设置软链才会真正替换线上代码

- 快速回滚   由于采用了原子部署,所以回滚也只是重新设置一下软链指向

- 并发部署   集群环境下,并发在所有机器上执行相同的部署流程

- 一致性     集群环境下,只有所有机器都执行成功才算成功,一台失败则全部失败

- 内置多个框架发布模板   比如Laravel、Yii、Symfony、CodeIgniter、Zend Framework等

- 易扩展     很容易可以依据自己的项目用Common模板编写发布流程

安装: 

composer global require deployer/deployer

安装完成后,切换到自己的项目目录,执行dep init,按照自己项目使用的框架选择生成的部署模板:

➜  tb dep init
Please select your project type (defaults to common):
  [0] Common
  [1] Laravel
  [2] Symfony
  [3] Yii
  [4] Zend Framework
  [5] CakePHP
  [6] CodeIgniter
  [7] Drupal
 > 0

如果你的框架未使用上面列出的任何一个框架,则选择0,然后回车,就会生成通用的发布模板。

执行完这一步应该会在你的项目根目录生成一个deploy.php文件,你所需要的做的一切就是编辑这个脚本,填写一些自己的服务器和项目配置,然后定制一些task。

下面我将用一个具体的配置文件来介绍deployer的使用,配置文件如下:

<?php
namespace Deployer;

use Symfony\Component\Console\Input\InputOption;

require 'recipe/common.php';

option('tag', null, InputOption::VALUE_OPTIONAL, '发布的tag');

// 全局配置文件   
set('ssh_type', 'native');    // 登录远程主机使用的方式,有三种:phpseclib(默认方式)、native、ext-ssh2
set('ssh_multiplexing', true);  // 是否开启ssh通道复用技术(开启可以降低服务器和本地负载,并提升速度)
set('keep_releases', 10); //    报错10个之前版本,设置为-1表示一直保存历史版本
set('repository', 'git@xxxxxxx.com:loc/loc-api.git');    // 代码仓库的地址,只支持git
set('branch', 'master');    // 发布代码时候默认使用的分支
set('shared_files', []);    // 共享文件列表   这里面列出的文件会被移动到项目根目录的shared目录下,并做软链
set('shared_dirs', []);     // 共享目录    同上
set('writable_mode', 'chmod');  // 采用哪种方式控制可写权限,有4中:chown、chgrp、chmod、acl(默认方式)
set('writable_chmod_mode', '0755'); // 当使用chmod控制可写权限的时候,赋予的可写权限值
set('writable_dirs', []);   // 可写目录   规定那些目录是需要可以被web server写入的
set('clear_path', []);  // 设置在代码发布的时候需要被删除的目录
set('http_user', 'nginx');  // web server的用户,一般不用设置,deployer会自动判断
set('release_name', function () {   // 设置发布版名称,这里优先使用tag作为名称,不传的话会使用日期+时间表示发布时间
    if (input()->hasOption('tag')) {
        return input()->getOption('tag');
    }
    return date('Ymd-H:i');
});

// 可以设置多个服务器,发布的时候根据设置会同步发往多个服务器
// 针对每个服务器可以单独设置参数,设置的参数会覆盖全局的参数
server('prod_1', 'xxx.xxx.xxx.xxx')
    ->user('root')
    ->password('xxxxx')
    ->set('deploy_path', '/var/www/tb')   // 代码部署目录,注意:你的webserver,比如nginx,设置的root目录应该是/var/www/tb/current,
                                          // 因为current是一个指向当前线上实际使用的版本的软链
    ->stage('prod');  // 标识该服务器类型,用于服务器分组

server('prod_2', 'xxx.xxx.xxx.xxx')
    ->user('root')
    ->password('xxxxx')
    ->set('deploy_path', '/var/www/tb')
    ->set('branch', 'master')   // 指定发往这个服务器的分支,会覆盖全局设置的branch参数
    ->set('extra_stuff', '...') // 随意指定其他什么参数
    ->stage('prod');
    
server('beta', 'xxx.xxx.xxx.xxx')
    ->user('root')
    ->password('xxxxx')
    ->set('deploy_path', '/var/www/test')
    ->set('branch', 'beta')   // 测试环境使用beta分支
    ->stage('beta');    // 放在beta分组


// 配置的任务
task('success', function () {
    Deployer::setDefault('terminate_message', '<info>发布成功!</info>');
})->once()->setPrivate();   // 增加once调用那么这个任务将会在本地执行,而非远端服务器,并且只执行一次

desc('重启php-fpm');    // 可以给任务增加一个描述,在执行dep list的时候将能看到这个描述
task('php-fpm:restart', function () {
    run('systemctl restart php-fpm.service');  // run函数定义在服务器执行的操作,通常是一个shell命令,可以有返回值,返回命令打印
});     // 聪明如你一定发现了,可以用run函数制作一些批量管理服务器的任务,比如批量重载所有的nginx配置文件、批量执行服务器上的脚本等

after('deploy:symlink', 'php-fpm:restart'); // 钩子函数,表示执行完设置软链任务之后执行php-fpm重启任务

desc('发布项目');
task('deploy', [    // 可以设置复合任务,第二个参数是这个复合任务包括的所有子任务,将会依次执行
    'deploy:prepare',   // 发布前准备,检查一些需要的目录是否存在,不存在将会自动创建
    'deploy:lock',  // 生成锁文件,避免同时在一台服务器上执行两个发布流程,造成状态混乱
    'deploy:release',   // 创建代码存放目录
    'deploy:update_code',   // 更新代码,通常是git,你也可以重写这个task,使用upload方法,采用sftp方式上传
    'deploy:shared',    // 处理共享文件或目录
    'deploy:writable',  // 设置目录可写权限
    'deploy:vendors',   // 根据composer配置,安装依赖
    'deploy:clear_paths',   // 根据设置的clear_path参数,执行删除操作
    'deploy:symlink',   // 设置符号连接到最新更新的代码,线上此时访问的就是本次发布的代码了
    'deploy:unlock',     // 删除锁文件,以便下次发布
    'cleanup',  // 根据keep_releases参数,清楚过老的版本,释放服务器磁盘空间
    'success'   // 执行成功任务,上面自己定义的,一般用来做提示
]);


after('deploy:failed', 'deploy:unlock');    // 如果发布失败,则删除锁文件,以便下次重试

上面就是一个比较完整的自动化部署脚本配置了,是不是感觉到很简单? 因为大部分配置工作在你执行dep init的时候就已经帮你做了!

在接下来还需要做的一件事情就是把你要部署的服务器的ssh-key加入到你的git帐号的认证库里面,你也可以创建一个账户,只拥有仓库的git pull和git clone权限,保持最小权限原则。需要注意的是,加完key之后,首次在服务器上执行git clone可能会需要让你输入yes,所以最稳妥的办法是,去每台要部署的服务器上去执行一遍git clone,把仓库代码拖一份到其他目录。

做完上面的事情之后,所有的准备工作就算完成了。接下来就可以进行部署测试了。

首先检查下配置有没问题:

dep config:dump beta    // 打印beta环境的配置
dep config:dump prod    // 打印生产环境的配置

打印出来的配置没有问题的话,接着执行发布任务:

dep deploy beta // 发布当前beta分支到beta环境
dep --tag=v1.1 deploy prod // 发布v1.1这个tag的代码到生产环境,可以增加-p选项,并发发往所有服务器

一次成功的部署应该会有类似如下输出:

➜  tb git:(master) ✗ dep --tag=v1.1 deploy prod_1
✔ Executing task deploy:prepare
✔ Executing task deploy:lock
✔ Executing task deploy:release
✔ Executing task deploy:update_code
✔ Executing task deploy:shared
✔ Executing task deploy:writable
✔ Executing task deploy:vendors
✔ Executing task deploy:clear_paths
✔ Executing task deploy:symlink
✔ Executing task php-fpm:restart
✔ Executing task deploy:unlock
✔ Executing task cleanup
✔ Executing task success
发布成功!

查看当前生产环境使用的哪个版本

dep current prod  //这里应该会输出v1.1 

查看当前生产环境使用的哪个版本:

dep current prod  //这里应该会输出v1.1 

如果发布到线上之前之后发现有问题,需要回滚,只需要执行:

dep rollback prod   // 实际上只是修改软链指向,所以很快就能执行完成且基本不可能失败

再次用dep current prod应该就可以看到回滚到之前版本了

再比如之前执行出了问题,被中断,再次执行可能会提示:Deploy locked,那么只用执行:

dep deploy:unlock prod // 删除锁文件

如果线上磁盘空间吃紧了的话(一般不会),可以执行如下命令删除掉太早以前的版本:

dep cleanup

到了这里关于deployer所有你应该都掌握了。虽然第一次配置的确需要花点时间,可能半个小时也可能半天。  不过换来的却是接下来更优雅、快速、安全、易回滚的发布流程,这么想一下是不是还有点小激动呢?

如果在安装使用过程中有什么问题的话可以加群:632109190进行讨论。对php、java、运维感兴趣的同学都可以加进来,我在这等你们 :)

© 著作权归作者所有

共有 人打赏支持
码王信息
粉丝 14
博文 13
码字总数 15837
作品 0
长沙
加载中

评论(13)

码王信息
码王信息

引用来自“systom”的评论

太复杂了。
其实还好,你把我发的配置保存下来,改下你的仓库地址和服务器地址,就可以用了。 而且只用首次配置,以后发布回滚都会很简单 :satisfied:
请叫我小哥哥
请叫我小哥哥
太复杂了。
码王信息
码王信息

引用来自“m19931013”的评论

苟……
m
m19931013
卢勇福
卢勇福
php 不用构建的话,试试:https://github.com/wdfe/ideploy
码王信息
码王信息

引用来自“Geomen”的评论

composer global require deployer/deployer执行完
再执行tb
怎么报tb command not found?
啊 那个tb不是命令 是终端显示的我当前的目录 那条命令应该是dep init 有什么问题可以加群632109190 我回复的会比较及时 :)
Geomen
Geomen
composer global require deployer/deployer执行完
再执行tb
怎么报tb command not found?
r
rockxsj

引用来自“KL博客”的评论

做php的不知道持续集成么
持续集成毕竟还需要搭建一堆服务 整套下来麻烦不少 只是发布带吗的话感觉这个轻量不少
KL博客
KL博客
做php的不知道持续集成么
卧龙大熊猫
卧龙大熊猫
不错哦
Walle 0.8.5 发布,上线部署系统瓦力

Walle - 瓦力 是一个支持svn、git、多用户、多项目、多环境同时部署的上线部署系统。 相比jenkins其项目配置更简单、回滚快速、权限分级、用户分组功能更完善;UI界面更优雅,用户体验更人性...

wushuiyong ⋅ 2015/11/14 ⋅ 11

或许你也患上了开发瘫痪症

亲爱的开发者们:你们是否因为自己只精通于三大设备平台的八种编程语言而惴惴不安?又发现一个JavaScript框架是否会让你不寒而栗、愁眉苦脸?你是否曾经因为无法确定哪个云平台最适合而把业余...

oschina ⋅ 2014/10/22 ⋅ 62

上线部署系统 Walle 0.6.0 发布,完美支持java部署

Walle - 瓦力 上线部署系统v0.6.0版本新增了一系列新功能,已经成为一个中级的上线部署系统,支持多用户、多项目、多环境同时部署。相比jenkins其项目配置更简单、回滚快速、权限分级、用户分...

wushuiyong ⋅ 2015/10/16 ⋅ 23

上线部署系统 Walle 0.7.0 发布,支持svn部署

Walle - 瓦力 上线部署系统v0.7.0版本新增了一系列新功能,支持多用户、多项目、多环境同时部署。相比jenkins其项目配置更简单、回滚快速、权限分级、用户分组功能更完善;好吧至少UI界面更优...

wushuiyong ⋅ 2015/10/20 ⋅ 19

上线部署系统 Walle-瓦力 0.5.0,国产上线部署系统

walle - 瓦力 上线部署系统v0.5.0版本新增了一系列新功能,已经成为一个中级的上线部署系统,支持多用户、多项目、多环境同时部署。相比jenkins其项目配置更简单、回滚快速、权限分级、用户分...

wushuiyong ⋅ 2015/10/11 ⋅ 18

上线部署系统 Walle 0.7.5 发布,全面支持 git, svn 部署

Walle - 瓦力 上线部署系统支持多用户、多项目、多环境同时部署。相比jenkins其项目配置更简单、回滚快速、权限分级、用户分组功能更完善;好吧至少UI界面更优雅,用户体验更人性,大大方便了...

wushuiyong ⋅ 2015/10/26 ⋅ 36

轻量级PHP开发框架--CookPHP

CookPHP 开发框架是一个基于PHP7的自由、免费开源、快速、简单的面向对象的轻量级PHP开发框架,并由珠海旭爱科技有限公司团队开发与维护。 CookPHP一直也实践与众筹系统、多用户商城等商业项目...

费尔 ⋅ 2016/09/02 ⋅ 0

轻量级PHP开发框架--SmartPHP

SmartPHP 开发框架是一个基于PHP7的自由、免费开源、快速、简单的面向对象的 轻量级PHP开发框架 SmartPHP 由珠海旭爱科技有限公司技术团队开发与维护,SmartPHP一直也实践与众筹系统、多用户...

smartphpcn ⋅ 2016/07/18 ⋅ 0

Walle 0.8.0 发布,上线部署系统瓦力

Walle - 瓦力 是一个支持多用户、多项目、多环境同时部署的上线部署系统。 相比jenkins其项目配置更简单、回滚快速、权限分级、用户分组功能更完善;好吧至少UI界面更优雅,用户体验更人性,...

wushuiyong ⋅ 2015/11/02 ⋅ 5

Walle 0.9.0 发布,上线部署系统瓦力

Walle - 瓦力 是一个支持svn、git、多用户、多项目、多环境同时部署的上线部署系统。 相比jenkins其项目配置更简单、回滚快速、权限分级、用户分组功能更完善;UI界面更优雅,用户体验更人性...

wushuiyong ⋅ 2015/11/18 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

UI ,前端框架选型

Flat-UI

miaojiangmin ⋅ 3分钟前 ⋅ 0

Istio Service Mesh 教程

Istio Service Mesh 教程 作者 宋净超 | 5400字 | 阅读大约需要11分钟 | 归档于istio | 发表于 2018-05-22 标签 #Istio #教程,来自 https://servicemesher.github.io/blog/istio-service-m...

openthings ⋅ 9分钟前 ⋅ 0

scala swing

scala swing组件的库 https://github.com/scala/scala-swing scala swing的API文档 https://www.scala-lang.org/api/2.9.1/scala/swing/package.html...

whoisliang ⋅ 13分钟前 ⋅ 0

CentOS安装配置Nginx

安装依赖 yum install gcc yum install pcre-devel yum install zlib zlib-devel yum install openssl openssl-devel //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-deve......

临江仙卜算子 ⋅ 19分钟前 ⋅ 0

开源 java CMS - FreeCMS2.8 依申请公开

项目地址:http://www.freeteam.cn/ 依申请公开 1. 转交申请公开 用户可以把申请公开转交给其他人办理,系统会记录此申请公开的转交记录。 注意:同时只能转交一个申请公开。 选择需要转交的...

freeteam ⋅ 24分钟前 ⋅ 0

以太坊 web3.py 签名转账

以太坊 web3.py 签名转账 本文节选自电子书《Netkiller Blockchain 手札》 Netkiller Blockchain 手札 Mr. Neo Chan, 陈景峯(BG7NYT) 中国广东省深圳市龙华新区民治街道溪山美地 518131 +86...

netkiller- ⋅ 29分钟前 ⋅ 0

年薪40W的程序员必会的技术有哪些?

很多人在问我,程序员如何拿高薪,如何做到年薪40W+,其实总结出来还是一句话,你的技术决定你的能力已经薪资。 那么什么样的技术人才才能拿到一份Java行业里面的高薪呢? 下面是我的一个总结...

码代码的小司机 ⋅ 30分钟前 ⋅ 0

jesque-spring使用及源码分析

1.使用 jesque结合spring使用,步骤如下: 1.1 在项目中添加maven依赖 <dependency> <groupId>net.lariverosc</groupId> <artifactId>jesque-spring</artifactId> <version>1.0.0</ve......

Funcy1122 ⋅ 31分钟前 ⋅ 0

OSChina 周二乱弹 —— 加班的代码不要枉费了我的童子功

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《29》- 未完成乐队 《29》- 未完成乐队 手机党少年们想听歌,请使劲儿戳(这里) @FalconChen :#看球提醒# 02:00 巴西v...

小小编辑 ⋅ 57分钟前 ⋅ 16

Docker Swarm的前世今生

概述 在我的《Docker Swarm集群初探》一文中,我们实际体验了Docker Swarm容器集群技术的魅力,与《Kubernetes实践录》一文中提到的Kubernetes集群技术相比,Docker Swarm没有Kubernetes显得...

CodeSheep ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部