如何在Ubuntu上使用Deployer自动部署Laravel应用程序
Laravel是一个开放源代码的PHP Web框架,旨在简化认证,路由和缓存等常见Web开发任务。Deployer 是一款开源的PHP部署工具,它为许多流行的框架提供了开箱即用的支持,包括Laravel
,CodeIgniter
,Symfony
和Zend Framework
等等。
部署者通过将应用程序从Git存储库克隆到服务器,安装与Composer 的依赖关系以及配置应用程序来自动执行部署,因此您不必手动执行此操作。这使开发者可以将更多时间花在开发上,而不是上传和配置,并允许开发者更频繁地进行部署。
开始之前
在开始之前,您需要以下内容:
- 一个
Ubuntu 16.04
服务器,具有sudo
特权的非root用户。 - 按照Ubuntu下快速搭建LNMP环境配置好的LNMP环境
- 一个Git服务器。可以选择使用Gogs、GitLab,Bitbucket 或GitHub等服务。
Gogs
、GitLab
和Bitbucket
免费提供私人仓库,而GitHub
提供私人仓库,每月**$7**起。 - 指向生产服务器的域名。
Composer
和Git
也安装在本地机器上。例如这里的MacOSX系统。
设置本地开发环境
此部分在本地开发环境操作,1. 下载和安装
deployer
2. 初始化一个laravel
项目 3. 使本地开发环境能够免密提交代码到远程git仓库
下载deployer扩展
由于将从本地机器创建和部署应用程序,因此首先配置本地开发环境。部署者将从本地机器控制整个部署过程,因此请先安装它。
在本地机器上,打开终端并使用下载部署器安装程序composer
:
composer global require deployer/deployer -vvv
安装完成你应该可以使用以下命令来查看它的版本信息:
dep --version
# Deployer master
创建一个Laravel项目
接下来,在本地机器上创建一个Laravel项目(假如本地代码放在~/Codes
目录下):
cd ~/Codes && composer create-project --prefer-dist laravel/laravel laravel-app "5.6.*"
现在已经在本地计算机上安装了所有必需的扩展包。有了这个,我们将继续为应用程序创建一个Git仓库。
本地机器连接到您的远程Git仓库
部署旨在使用户能够从任何地方部署代码。为了实现这一功能,它需要用户将代码推送到互联网上的仓库,然后部署人员将代码拷贝到生产服务器。
我们将使用开源版本控制系统Git来管理Laravel应用程序的源代码。可以使用SSH协议连接到Git服务器,为了安全地执行此操作,您需要生成SSH密钥。这比基于密码的身份验证更安全,同时也可以避免在每次部署前输入密码。
编辑SSH密钥
在本地计算机上运行以下命令以生成SSH密钥。请注意,-f
参数指定密钥文件的文件名,并且可以自定义文件名替换gitkey
。它会生成一个SSH密钥对(命名gitkey
和gitkey.pub
)到该~/.ssh/
文件夹。
ssh-keygen -t rsa -b 4096 -f ~/.ssh/gitkey
开发者可能在本地计算机上拥有很多的SSH密钥,因此在配置SSH客户端之前了解在连接到Git服务器时使用哪个SSH专用密钥。当然也可以使用之前已经存在的SSH密钥。
创建一个SSH配置文件
vim ~/.ssh/config
打开文件并为Git服务器添加一个快捷方式。这应该包含HostName
指令(指向Git服务器的主机名)和IdentityFile
指令(指向您刚刚创建的SSH密钥的文件路径):
Host mygitserver.com
HostName mygitserver.com
IdentityFile ~/.ssh/gitkey
这样配置的话,SSH客户端将知道使用哪个私钥连接到Git服务器。
使用以下命令显示公钥文件的内容
cat ~/.ssh/gitkey.pub
复制输出并将公钥添加到您的Git服务器。
如果使用Git托管服务,请参阅有关如何将SSH密钥添加到您的帐户的文档:
添加完成之后,现在可以使用本地机器连接到Git服务器。使用以下命令测试连接
ssh -T git@mygitserver.com
如果此命令导致错误,请检查是否通过引用Git托管服务的文档正确添加了SSH密钥,然后再次尝试连接。
在将应用程序推送到远程Git存储库并进行部署之前,我们先配置生产服务器。
配置生产服务器
此部分在目标服务器即生产服务器上操作 1. 创建一个部署用户用于部署 2. 授权部署用户的相关操作 3. 使生产环境能够免密拉取远程git仓库代码
配置部署者用户
部署者使用SSH协议在服务器上安全地执行命令。出于这个原因,我们将向配置生产服务器创建一个用户,Deployer可以使用该用户通过SSH登录并在您的服务器上执行命令。 使用sudo非root用户登录到生产服务器,并使用以下命令创建一个名为deployer
的新用户:
sudo apt-get install -y unzip git
sudo adduser deployer
创建一个
deployer
部署用户,上面的命令按回车后输入用户密码和重复密码后直接按回车即可。
Laravel需要一些可写的目录来存储缓存的文件和上传文件,因此部署者用户创建的目录必须可由Nginx Web服务器写入。使用下面的命令将用户添加到www-data
组中以执行此操作:
sudo usermod -aG www-data deployer
部署者用户创建的文件的默认权限应该644用于文件和755目录。这样部署者用户将能够读取和写入文件,而组和其他用户将能够读取它们。
通过将部署者的默认umask
设置为022
:
sudo chfn -o umask=022 deployer
我们将应用程序存储在/var/www/html/
目录中,因此将目录的所有权更改为部署者用户和www-data
组。
sudo mkdir -p /var/www/html && sudo chown deployer:www-data /var/www/html # 最后这里不要加斜线哦
该部署的用户需要能够在中修改文件和文件夹/var/www/html
目录。因此目录中创建的所有新文件和子目录/var/www/html
都应该继承该文件夹的组标识(www-data)。要实现这个目标,请使用以下命令在此目录中设置组ID:
sudo chmod g+s /var/www/html
部署者将使用SSH将Git repo克隆到生产服务器,因此您要确保生产服务器和Git服务器之间的连接是安全的。这里将使用与用于本地计算机的相同方法,并为部署者用户生成一个SSH密钥。
项目git仓库授权生产服务器访问
切换到服务器上的部署者用户:
su - deployer
接下来,生成一个SSH密钥对作为部署者用户。这一次,可以接受SSH密钥的默认文件名:
ssh-keygen -t rsa -b 4096
输入完命令后一直按Enter即可。
使用下面的命令显示公钥:
cat ~/.ssh/id_rsa.pub
像上一步那样复制本地公钥文件一样并将其添加到Git服务器,现在服务器就可以从git仓库clone代码了。
此时,可以在服务器使用deployer
用户使用 git clone
命令拷贝git仓库测试。如果不能成功拷贝仓库代码,请检查服务器的公钥是否正确完全的复制与粘贴正确,不正确的话再次重复复制粘贴即可。
开发环境免密码登录生产环境
开发环境生成密匙
此部分在本地开发环境操作 1. 使本地开发环境能够免密登录生产环境
在本地开发机器上运行以下命令。随意用您选择的文件名替换deployerkey
:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/deployerkey
复制包含公钥的以下命令的输出:
cat ~/.ssh/deployerkey.pub
修改开发环境文件内容
此部分在生产环境操作 生产环境修改
~/.ssh/authorized_keys
内容和权限
将上面复制的公钥内容,添加到生产服务器上的~/.ssh/authorized_keys
文件内。
# 使用vi编辑器打开文件
vi ~/.ssh/authorized_keys
# 粘贴下面的内容到文件中
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLjvl3r+Mlk975SW8zJrNrkIqwKe573LcYscq0F0DRPePVOxGcoqNMx/DGLewOf70Ozc3OuHTwkQIuj1mxOJ6w/W8qTgXr4X5szE1DfvHr/0Nnn/rJBTWm6qas0ktNGgYkixS4AJMcnXwuGDU8NSu+lSrkhYmi/+yN/fpyHUGhSLbT7LP1XxaTEDQNjjyGbgJgTEkrL1ZwlXW7CtwFLBKxm60JkQzUk39FPu6tXZGIQDcixL3CNIiHxdSIOroxvYdEVKfv6YyKKR1uizSbE3GjDrn7CDEE1LHmrHXOhbU805rdbyykIaYORMhSRZ869bRRAMhZDqzcdpu4kwVLeIOr xiaoluo@bogon
注意在生产服务器上,使用部署者
deployer
用户修改上面的文件内容。
修改完成后,使用下面的命令修改文件权限:
chmod 600 ~/.ssh/authorized_keys
使用部署用户测试
作为部署者用户,从本地计算机登录到服务器以测试连接:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
再以部署者身份登录后,测试服务器和Git服务器之间的连接:
ssh -T git@mygitserver.com
如果是Gogs代码仓库服务器,大致输出会是这样:
Hi there, You've successfully authenticated, but Gogs does not provide shell access.
If this is unexpected, please log in with password and setup Gogs under another user.
配置Nginx
以下配置在生产服务器配置。
创建一个站点配置文件
以sudo
用户身份登录到服务器并创建一个新的配置文件。将配置中的域名example.com
替换为你当前操作的。
sudo vim /etc/nginx/sites-available/example.com
大致内容如下:
server {
listen 80;
listen [::]:80;
root /var/www/html/laravel-app/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
使nginx配置生效
通过创建符号链接启用新的服务器模块sites-enabled目录:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
测试配置语法
sudo nginx -t
如果您看到任何错误,请返回并重新检查配置文件,然后再继续。
重新启动Nginx
sudo service nginx restart
现在配置Nginx服务器。接下来,我们将配置应用程序的MySQL数据库。
配置MySQL
以下配置在生产服务器配置。
以root身份登录到MySQL控制台:
mysql -u root -p
这会提示你输入root密码,正确输入root密码后。接下来,为应用程序创建一个新的数据库:
CREATE
DATABASE laravel_app DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
然后,创建一个新的数据库用户。这里演示使用用户名:laravel_user
和密码:password
,但实际情况应该使用强密码。
CREATE
USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';
授予用户数据库权限:
GRANT
ALL
ON laravel_app.* TO 'laravel_user'@'localhost';
接下来,重新加载权限:
FLUSH
PRIVILEGES;
最后,exit
退出MySQL控制台。
部署应用程序
配置deployer
到目前为止,已经配置了部署者运行所需的所有工具和程序。在运行第一个部署之前,剩下的工作就是完成Laravel应用程序和Deployer本身的配置,并初始化并将项目代码推送到远程Git存储库。
打开本地开发机器上的终端,并使用以下命令将工作目录更改为应用程序的文件夹:
cd ~/Codes/laravel-app
在该目录中运行以下命令,该命令将创建在项目根目录laravel-app
下创建一个deploy.php
文件,该文件将包含配置信息和部署任务:
dep init -t Laravel
接下来,在文本编辑器或IDE打开deploy.php
文件。第三行包含一个PHP脚本,其中包含部署Laravel应用程序所需的任务和配置:
<?php
namespace Deployer;
require 'recipe/laravel.php';
// Project name
set('application', 'laravel-app');
// Timeout
set('default_timeout', 360);
// Project repository
set('repository', 'git@gogs.curder.com:curder/laravel-app.git');
// [Optional] Allocate tty for git clone. Default value is false.
set('git_tty', true);
// Shared files/dirs between deploys
add('shared_files', []);
add('shared_dirs', []);
// Writable dirs by web server
add('writable_dirs', []);
// Hosts
host('server_ip') // 填写生产服务器IP地址
->user('deployer') // 填写生产服务器部署用户名
->identityFile('~/.ssh/deployerkey') // 秘钥文件
->set('deploy_path', '/var/www/html/laravel-app');
// Tasks
task('build', function () {
run('cd {{release_path}} && build');
});
// 自定义任务:重置 PHP-FPM 进程
// desc('Restart PHP-FPM service');
// task('php-fpm:reload', function () {
// // The user must have rights for reload service
// // /etc/sudoers: deployer ALL=NOPASSWD:/binsystemctls service n relo restartad php7.1-fpm.service
// run('sudo systemctl reload php7.1-fpm.service');
//});
// [Optional] if deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');
// Migrate database before symlink new release.
// before('deploy:symlink', 'artisan:migrate');
// 部署成功后重置 PHP-FPM 缓存
// after('deploy:symlink', 'php-fpm:reload');
修改上面的
servier_ip
相关的指令详见官方文档
接下来,注释掉文件相关行before('deploy:symlink', 'artisan:migrate');
。此行指示部署者自动运行数据库迁移,并通过注释将其禁用。如果不注释它,部署将失败,因为此行需要在服务器上提供项目的数据库配置,只能使用在首次部署期间生成的文件之后来添加该行。
提交项目代码到git
cd ~/Code/laravel-app
在laravel-app
目录中运行以下命令以初始化项目文件夹中的Git存储库
git init
接下来,将所有项目文件添加到存储库中
git add .
提交更改
git commit -m 'Initial commit for first deployment.'
使用以下命令将您的Git服务器添加到本地存储库。请确保使用您自己的远程存储库的URL替换命令中的地址:
git remote add origin git@mygitserver.com:username/repository.git
将更改推送到远程Git存储库:
git push origin master
dep
命令运行部署
使用以下dep deploy
需要查看部署输出的详情可以使用
-vvv
参数。
如果一切顺利,你应该Successfully deployed!在最后看到这样的输出
Deployer's output
✈︎ Deploying master on your_server_ip
✔ Executing task deploy:prepare
✔ Executing task deploy:lock
✔ Executing task deploy:release
➤ Executing task deploy:update_code
✔ Ok
✔ Executing task deploy:shared
✔ Executing task deploy:vendors
✔ Executing task deploy:writable
✔ Executing task artisan:storage:link
✔ Executing task artisan:view:clear
✔ Executing task artisan:cache:clear
✔ Executing task artisan:config:cache
✔ Executing task artisan:optimize
✔ Executing task deploy:symlink
✔ Executing task deploy:unlock
✔ Executing task cleanup
Successfully deployed!
以下结构将在目录内的服务器上创建:/var/www/html/laravel-app
├── .dep
├── current -> releases/1
├── releases
│ └── 1
└── shared
├── .env
└── storage
以下是每个文件和目录包含的内容:
- 该
releases
目录包含Laravel应用程序的部署版本。 current
是最后一个版本的符号链接。- 该
.dep
目录包含Deployer的特殊元数据。 - 该
shared
目录包含.env
配置文件和storage
将被链接到每个版本的目录。
登录服务器
查看项目目录
通过在生产服务器上运行以下命令来验证该文件,该命令将列出文件夹中的文件和目录:
ls /var/www/html/laravel-app
# Output
current .dep releases shared
但是,该应用程序无法工作,因为该.env
文件是空的。该文件用于保存重要配置,如应用程序密钥APP_KEY
用于加密的随机字符串。如果未设置,您的用户会话和其他加密数据将不安全。
该应用程序.env
在本地计算机上有一个文件,但Laravel的.gitignore
文件将其从Git中排除,因为将密码等敏感数据存储在Git存储库中并不是一个最佳实践,而且该应用程序在您的服务器上需要不同的设置。
另外该.env
文件也包含数据库连接设置,这就是为什么我们禁用第一次部署的数据库迁移的原因。
配置项目环境变量
使用下面的命令,从开发机器上以部署者用户身份登录到您的服务器:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
在生产服务器上修改.env
环境配置文件vim /var/www/html/laravel-app/shared/.env
内容:
APP_NAME=laravel-app
APP_ENV=production
APP_KEY=base64:SXYMVQIW2hyl8lc+x0UZw5fxMNoEv0fPzhten9lBjUQ=
APP_DEBUG=false
APP_URL=http://example.com
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=laravel_user
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
保存该文件并关闭编辑器。
现在取消注释deploy.php
本地机器上文件中关于before('deploy:symlink', 'artisan:migrate');
:
这个操作会导致数据库迁移在每个部署中自动运行。这样可以避免手动迁移数据库,但在部署之前不要忘记备份数据库。
要检查此配置是否正常,请再次部署该应用程序。在本地开发机器上运行以下命令:
dep deploy -vvv
现在,您的应用程序将正常工作。如果您访问服务器的域名(http://example.com
),您将看到以下登录页面:
当配置完上面的配置之后,每次开发场景不需要如此复杂的操作。
运行典型部署
在再次部署之前,通过修改应用程序开始。例如,您可以在routes/web.php
文件中添加新的about
路由:
<?php
Route::get('/', function () {
return view('welcome');
});
Route::get('/about', function(){
return 'About Page';
});
保存文件并提交这些更改:
git commit -am 'Your commit message.'
将更改推送到远程Git存储库
git push origin master
部署应用程序
dep deploy
结论
通过配置本地开发机器和生成环境服务器,以零宕机时间轻松部署Laravel应用程序。部署者还可以一次部署到更多服务器并创建任务; 例如,可以指定一个任务来在迁移之前备份数据库。如果想了解关于部署者功能的更多信息,可以在** 部署者**文档中找到更多信息。