平时,如果我们开发好一个laravel项目之后,纯手工部署代码的话,需要经历以下步骤:
如果后续要更新版本,代码变更的时候,实在是一个令人感觉不好的操作,我们可能需要做以下的工作
如果我们使用纯手工的方式部署会有以下问题:
为了解决这个问题,我们可以使用Deployer 这个部署工具,Deployer 可以让我们用 PHP 代码的方式描述部署步骤并执行,对于php开发者来说真的是一个福音咯
我之前练手用的电商系统,就是用deployer部署的,支持单机跟多机部署,可戳shop
Deployer 是一个基于 SSH 协议的无侵入 web 项目部署工具,因为它不需要你在目标服务器上装什么服务之类的东西即可使用,它只需要在你的开发机,或者你的笔记本,就是发起部署动作的一方安装即可。
它的原理就是通过 SSH 到你的机器去创建目录,移动文件,执行指定的动作来完成项目的部署
跟我们shell脚本其实是一样的,只不过,我们不需要去服务器上面进行操作,而且在本地恋用熟悉的php进行编写部署脚本后,通过ssh协议,登录到指定服务器进行一系列操作,所以说还是很友好的。
Deployer的安装与配置都是在本地进行操作
$ composer global require deployer/deployer
安装完成后我们试试看是否安装成功:
$ dep
$ dep init
接下来的操作,选择yes就行了
dep init 命令用来创建一个部署脚本,会询问我们项目类型,我们是 Laravel 项目所以输入 1 然后回车;接下来询问 Repository 也就是我们代码仓库的地址
快速入门可参考官网Deployer
初始化后,会自动生成 deployer.php 文件。 deployer.php 文件包含了基本的部署配置和任务,且有明确的注释,你可以根据注释在适当的地方添加配置以及任务。
可参考我的部署脚本可戳shop
在本地编写部署脚本是最简单写的,最难的就是用户权限的控制问题,刚开始使用的时候经常会遇到permission denied的问题,
以下参考自安正超的配置:
出于安全考虑,我们一般不会使用 root 用户的 SSH 登录,而是使用其它用户,比如 Ubuntu 默认的 ubuntu 用户。
我们 Deployer 是用来部署 web 应用的,所以我们也专门创建一个用户来做这件事情比较好:
$ sudo adduser deployer
# 密码什么的,按提示操作即可
我们的 web 项目通常需要一些上传,或者缓存写入这样的操作,所以 deployer 还需要有权限对目录进行修改,比如 Laravel 的 storage 目录需要可写权限,这里以 nginx 默认的用户组 www-data 举例,如果你修改过用户或者组名请对应修改下面的命令里的 www 用户组:
$ sudo usermod -aG www-data deployer
我们通常需要将deployer 用户权限分别设置为创建文件 644 与目录 755,这样一来,deployer 用户可以读写,但是组与其它用户只能读:
$ su deployer # 切换到 deployer 用户
$ echo "umask 022" >> ~/.bashrc
$ exit # 退出
我们需要将 depoloyer 用户加到 sudoers 中:
$ vim /etc/sudoers
# 在最后加入
deployer ALL=(ALL) NOPASSWD: ALL
# 保存并退出
接下来要对我们的 web 根目录授权,假设我们的 web 服务的根目录在 /var/www/ 下,那么需要将这个目录的用户设置为 deployer ,组设置为 www 用户 www-data:
$ sudo chown deployer:www-data /var/www/html # 最后这里不要加斜线哦
为了让 deployer 用户在 /var/www/html 下创建的文件与目录集成根目录的权限设定(用户:deployer,组:www-data),我们还需要一步操作:
$ sudo chmod g+s /var/www/html
OK,Deployer 的用户操作就结束了,接着你需要检查以下配置:
因为部署脚本需要从git服务器中获取代码,因此我们的部署服务器需要有权限可以拉取代码
如果代码不是公开的仓库,我们通常需要添加 SSH 公钥才可以从代码库 clone 代码,所以接着来创建公钥:
先切换当前登录用户到 deployer:
$ su - deployer
然后创建 SSH 密钥:
$ ssh-keygen -t rsa -b 4096 -C "deployer"
# 这里的 -C 是指定备注
# 一路回车下去即可
然后我们将生成的公钥拷贝出来:
$ cat ~/.ssh/id_rsa.pub # 显示公钥
请完整的复制 cat 出来的结果,然后去你的代码库添加 SSH 公钥。
OK, 现在你的服务器就可以从代码库 clone 代码了,你可以在服务器上 git clone 一下你的代码库测试,如果不成功,请检查你的公钥是否正确完全的复制与粘贴正确,不正确的话再次重复复制粘贴即可。
在部署shop,因为使用的是阿里云服务器,因此带上了,购买时生成的密钥文件,只要在本地登录的时候带上那个密钥文件就可以免密码登录,命令如下:
$ ssh root@{你的服务器公网 IP} -i ~/.ssh/laravel-shop-aliyun.pem #你的密钥文件路径
如果我们没有生成该文件,我们可以手动使用以下的方法来:
在本地(或者开发机)执行部署任务时我们不想每次输入密码,所以我们需要将 deployer 用户设置 SSH 免密码登录:
在本机生成 deployer 专用密钥,然后拷贝公钥:
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/deployerkey
然后将公钥保存到目标服务器(注意,这一步还是在本机操作):
$ ssh-copy-id -i ~/.ssh/deployerkey.pub deployer@{服务器ip} # 请填写服务器 IP
# 应该会让你输入 deployer 在服务器上的登录密码,输入后回车即可
然后你应该就可以直接以 deployer 用户免密码登录到服务器了,测试方式:
$ ssh deployer@{服务器ip} -i ~/.ssh/deployerkey
# 应该就能直接进到服务器上了,然后 exit 退出
OK,这一步搞定了 deployer 免密码登录,接下来我们聊项目的部署。
其实,跟我们上一部差不多,只不过阿里云服务器帮我们省略了
Deployer 部署完成后,在服务器上的结构会是这样子:
drwxr-sr-x 5 deployer www-data 4096 Jun 14 09:53 ./
drwxr-sr-x 6 deployer www-data 4096 Jun 11 14:25 ../
drwxr-sr-x 2 deployer www-data 4096 Jun 14 09:53 .dep/
lrwxrwxrwx 1 deployer www-data 10 Jun 14 09:52 current -> releases/7/
drwxr-sr-x 4 deployer www-data 4096 Jun 14 09:53 releases/
drwxr-sr-x 3 deployer www-data 4096 Jun 10 14:16 shared/
current - 它是指向一个具体的版本的软链接,你的 nginx 配置中 root 应该指向它,比如 laravel 项目的话 root 就指向:/var/www/demo-app/current/public
releases - 部署的历史版本文件夹,里面可能有很多个最近部署的版本,可以根据你的配置来设置保留多少个版本,建议 5 个。保留版本可以让我们在上线出问题时使用 dep rollback 快速回滚项目到上一个版本。
shared - 共享文件夹,它的作用就是存储我们项目中版本间共享的文件,比如 Laravel 项目的 .env 文件,storage 目录,或者你项目的上传文件夹,它会以软链接的形式链接到当前版本中。
因此,在nginx配置的时候,我们可以采用:,例如项目laravel-shop
$ vim /etc/nginx/sites-available/laravel-shop.conf
将站点根目录修改为 /var/www/laravel-shop-deployer/current/public