介绍
Laravel是一个开放源码的PHP Web框架,旨在简化认证,路由和缓存等常见Web开发任务。 Deployer是一款开源的PHP部署工具,它为许多流行的框架提供了开箱即用的支持,包括Laravel,CodeIgniter,Symfony和Zend Framework。
部署者通过将应用程序从Git存储库克隆到服务器,安装与Composer的依赖关系以及配置应用程序来自动执行部署,因此您无需手动执行此操作。 这使您可以将更多时间花在开发上,而不是上传和配置,并允许您更频繁地进行部署。
在本教程中,您将自动部署Laravel应用程序,而不会停机。 为此,您将准备本地开发环境,从中部署代码,然后使用Nginx和MySQL数据库配置生产服务器来为应用程序提供服务。
先决条件
在开始本指南之前,您需要以下内容:
一个Ubuntu 16.04服务器,具有sudo权限的非root用户,如初始服务器设置和Ubuntu 16.04教程中所述。
按照如何在Ubuntu 16.04教程中安装Linux,Nginx,MySQL,PHP(LEMP)中所述安装的LEMP 。
按照如何在Ubuntu 16.04上安装和使用编辑器的第1步和2,在服务器上安装PHP,Composer和Git。
安装在您的服务器上的
php-xml
和php-mbstring
包。 通过运行安装这些:sudo apt-get install php7.0-mbstring php7.0-xml
。一个Git服务器。 您可以使用GitLab , Bitbucket或GitHub等服务 。 GitLab和Bitbucket免费提供私人存储库,而GitHub提供私人存储库,每月$ 7起 。 或者,您可以按照教程如何在VPS上设置私有Git服务器来设置私人Git服务器 。
指向您的服务器的域名。 如何使用DigitalOcean教程设置主机名可以帮助您对其进行配置。
Composer和Git也安装在本地机器上。 精确的安装方法取决于您的本地操作系统。 Git项目的下载页面上提供了有关安装Git的说明,您可以直接从Composer项目网站下载Composer。
第1步 - 设置您的本地开发环境
由于您将从本地机器创建和部署您的应用程序,因此首先配置您的本地开发环境。 部署者将从本地机器控制整个部署过程,因此请先安装它。
注意:如果您在本地机器上使用Windows,则应该使用BASH模拟器(如Git bash)来运行所有本地命令。
在本地机器上 ,打开终端并使用curl
下载Deployer安装程序:
curl -LO https://deployer.org/deployer.phar
接下来,运行一个简短的PHP脚本来验证安装程序是否与部署者 - 下载页面上找到的最新安装程序的SHA-1哈希匹配。 将突出显示的值替换为最新的散列值:
php -r "if (hash_file('sha1', 'deployer.phar') === '35e8dcd50cf7186502f603676b972065cb68c129') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('deployer.phar'); } echo PHP_EOL;"
OutputInstaller verified
使部署者可用于系统。 请注意,如果您在本地计算机上运行Windows或MacOS,则可能需要在运行此命令之前创建/usr/local/bin/dep
目录:
sudo mv deployer.phar /usr/local/bin/dep
使其可执行:
sudo chmod +x /usr/local/bin/dep
接下来,在本地机器上创建一个Laravel项目:
composer create-project --prefer-dist laravel/laravel laravel-app "5.5.*"
您已在本地计算机上安装了所有必需的软件。 有了这个,我们将继续为应用程序创建一个Git存储库。
第2步 - 连接到您的远程Git存储库
部署者旨在使用户能够从任何地方部署代码。 为了实现这一功能,它需要用户将代码推送到Internet上的存储库,然后部署人员将代码复制到生产服务器。 我们将使用开源版本控制系统Git来管理Laravel应用程序的源代码。 您可以使用SSH协议连接到Git服务器,为了安全地执行此操作,您需要生成SSH密钥。 这比基于密码的身份验证更安全,让您避免在每次部署前输入密码。
在本地计算机上运行以下命令以生成SSH密钥。 请注意, -f
指定密钥文件的文件名,您可以用您自己的文件名替换gitkey 。 它会为~/.ssh/
文件夹生成一个SSH密钥对(名为gitkey
和gitkey .pub
)。
ssh-keygen -t rsa -b 4096 -f ~/.ssh/gitkey
您可能在本地计算机上拥有更多的SSH密钥,因此请配置SSH客户端以了解在连接到Git服务器时使用哪个SSH私钥。
在本地机器上创建一个SSH配置文件:
touch ~/.ssh/config
打开文件并为你的Git服务器添加一个快捷方式。 这应该包含HostName
指令(指向您的Git服务器的主机名)和IdentityFile
指令(指向刚刚创建的SSH密钥的文件路径:
Host mygitserver.com/username/repository.git
HostName mygitserver.com/username/repository.git
IdentityFile ~/.ssh/gitkey
保存并关闭该文件,然后限制其权限:
chmod 600 ~/.ssh/config
现在您的SSH客户端将知道使用哪个私钥连接到Git服务器。
使用以下命令显示公钥文件的内容:
cat ~/.ssh/gitkey.pub
复制输出并将公钥添加到您的Git服务器。
如果您使用Git托管服务,请参阅有关如何将SSH密钥添加到您的帐户的文档:
现在您可以使用本地机器连接到Git服务器。 使用以下命令测试连接:
ssh -T git@mygitserver.com
如果此命令导致错误,请检查您是否通过引用Git托管服务的文档正确添加了SSH密钥,然后再次尝试连接。
在将应用程序推送到远程Git存储库并进行部署之前,我们首先配置生产服务器。
第3步 - 配置部署者用户
部署者使用SSH协议在服务器上安全地执行命令。 出于这个原因,我们将向配置生产服务器迈出的第一步是创建一个用户,Deployer可以使用该用户登录并通过SSH在您的服务器上执行命令。
使用sudo非root用户登录到LEMP服务器,并使用以下命令创建一个名为“ deployer ”的新用户:
sudo adduser deployer
Laravel需要一些可写的目录来存储缓存的文件和上传文件,因此部署者用户创建的目录必须可由Nginx Web服务器写入。 将用户添加到www-data组中以执行此操作:
sudo usermod -aG www-data deployer
部署者用户创建的文件的默认权限应为644
,文件为755
,目录为755
。 这样, 部署者用户将能够读取和写入文件,而组和其他用户将能够读取它们。
通过将部署者的默认umask设置为022
来做到这一点:
sudo chfn -o umask=022 deployer
我们会将应用程序存储在/var/www/html/
目录中,因此将目录的所有权更改为部署者用户和www-data组。
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克隆到生产服务器,因此您要确保LEMP服务器和Git服务器之间的连接是安全的。 我们将使用我们用于本地计算机的相同方法,并为部署者用户生成一个SSH密钥。
切换到服务器上的部署者用户:
su - deployer
接下来,生成一个SSH密钥对作为部署者用户。 这一次,您可以接受SSH密钥的默认文件名:
ssh-keygen -t rsa -b 4096
显示公钥:
cat ~/.ssh/id_rsa.pub
像上一步那样复制公钥并将其添加到Git服务器。
您的本地计算机也将使用SSH与服务器进行通信,因此您应该在本地计算机上为部署者用户生成SSH密钥并将公钥添加到服务器。
在本地机器上运行以下命令。 随意用您选择的文件名替换deployerkey :
ssh-keygen -t rsa -b 4096 -f ~/.ssh/deployerkey
复制包含公钥的以下命令的输出:
cat ~/.ssh/deployerkey.pub
在您的服务器上,作为部署者用户运行以下命令:
nano ~/.ssh/authorized_keys
将公钥粘贴到编辑器,然后按CTRL-X
, Y
,然后按ENTER
保存并退出。
限制文件的权限:
chmod 600 ~/.ssh/authorized_keys
现在切换回sudo用户:
exit
现在您的服务器可以连接到Git服务器,并且可以使用本地计算机上的部署者用户登录到服务器。
作为部署者用户,从本地计算机登录到服务器以测试连接:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
在以部署者身份登录后,测试服务器和Git服务器之间的连接:
ssh -T git@mygitserver.com
最后,退出服务器:
exit
从这里开始,我们可以继续在我们的Web服务器上配置Nginx和MySQL。
第4步 - 配置Nginx
我们现在准备配置将为该应用程序提供服务的Web服务器。 这将涉及配置我们将用来保存Laravel文件的文档根目录结构。 我们将设置Nginx来从/var/www/laravel
目录中提供我们的文件。
首先,我们需要为新站点创建一个服务器块配置文件 。
以sudo用户身份登录到服务器并创建一个新的配置文件。 请记住用您自己的域名替换example.com :
sudo nano /etc/nginx/sites-available/example.com
将server
块添加到配置文件的顶部:
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;
}
顶部的两个listen
指令告诉Nginx要监听哪些端口, root
指令定义Laravel将安装在哪里的文档根目录。 根目录路径中的current/public
是指向应用程序最新版本的符号链接。 通过添加index
指令,我们告诉Nginx在请求目录位置时查找其对应的HTML对象时首先会提供任何index.php
文件。 server_name
指令后面应跟随您的域及其任何别名。
我们也应该修改Nginx将处理请求的方式。 这是通过try_files
指令完成的。 我们希望它首先尝试将请求作为文件提供,如果它找不到具有正确名称的文件,它应该尝试为匹配请求的目录提供默认索引文件。 如果失败,它应该将请求作为查询参数传递给index.php
文件。
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;
}
接下来,我们需要创建一个处理任何PHP文件的实际执行的块。 这将适用于任何以.php结尾的文件。 它会尝试文件本身,然后尝试将它作为参数传递给index.php
文件。
我们将设置fastcgi
指令来告诉Nginx使用应用程序的实际路径(在遵循符号链接后解析),而不是符号链接。 如果您不将这些行添加到配置中,那么符号链接点的路径将被缓存,这意味着应用程序的旧版本将在部署之后加载。 如果没有这些指令,您将不得不在每次部署后手动清除缓存,并且可能会失败。 此外, fastcgi_pass
指令将确保Nginx使用php7-fpm用于通信的套接字,并且将index.php
文件用作这些操作的索引。
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.0-fpm.sock;
}
最后,我们要确保Nginx不允许访问任何隐藏的.htaccess
文件。 我们将通过添加一个名为location ~ /\.ht
位置块并在该块内添加一条指定deny all;
的指令来deny all;
。
在添加最后一个位置块后,配置文件将如下所示:
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.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
保存并关闭文件( CTRL-X
, Y
,然后ENTER
),然后通过创建到sites-enabled
目录的符号链接来启用新的服务器块:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
测试你的配置文件的语法错误:
sudo nginx -t
如果您看到任何错误,请返回并重新检查您的文件,然后再继续。
重新启动Nginx以推动必要的更改:
sudo systemctl restart nginx
现在配置Nginx服务器。 接下来,我们将配置应用程序的MySQL数据库。
第5步 - 配置MySQL
安装之后,MySQL默认创建一个root用户。 但是,该用户具有无限制的权限,因此将root用户用于应用程序的数据库是一种不好的安全做法。 相反,我们将使用专用用户为应用程序创建数据库。
以root身份登录到MySQL控制台:
mysql -u root -p
这会提示你输入root密码。
接下来,为应用程序创建一个新的数据库:
CREATE DATABASE laravel_database DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
然后,创建一个新的数据库用户。 为了本教程的目的,我们将使用密码password
将此用户laravel_user
称为password
,但您应该使用您选择的强密码替换密码。
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';
授予用户数据库权限:
GRANT ALL ON laravel_database.* TO 'laravel_user'@'localhost';
接下来,重新加载权限:
FLUSH PRIVILEGES;
最后,退出MySQL控制台:
EXIT;
您的应用程序的数据库和用户现在已配置完毕,您几乎可以开始运行第一次部署。
第6步 - 部署应用程序
到目前为止,您已配置了部署者运行所需的所有工具和程序。 在运行第一个部署之前,剩下的工作就是完成Laravel应用程序和Deployer本身的配置,并初始化并将应用程序推送到远程Git存储库。
打开本地机器上的终端,并使用以下命令将工作目录更改为应用程序的文件夹:
cd /path/to/laravel-app
从该目录运行以下命令,该命令将在laravel-app
文件夹中创建一个名为deploy.php
的文件,该文件夹将包含用于部署的配置信息和任务:
dep init -t Laravel
接下来,用你喜欢的文本编辑器或IDE打开deploy.php
文件。 第三行包含一个PHP脚本,其中包含部署Laravel应用程序所需的任务和配置:
<?php
namespace Deployer;
require 'recipe/laravel.php';
. . .
在这个下面是一些您应该编辑的字段,以便与您的配置保持一致:
- 在
// Project Name
,添加您的Laravel项目的名称。 - 在
// Project Repository
,将链接添加到您的Git存储库。 - 在
// Hosts
部分,将您的服务器的IP地址或域名添加到host()
指令中,您的Deployer用户(我们示例中为部署者user()
指向user()
指令。 您还应该将在第3步中创建的SSH密钥添加到identifyFile()
指令。 最后,你应该添加包含你的应用程序的文件夹的文件路径。
当你完成编辑这些字段时,它们应该看起来像这样:
...
// Project name
set('application', 'laravel-app');
// Project repository
set('repository', 'git@mygitserver.com:username/repository.git');
. . .
// Hosts
host('your_server_ip')
->user('deployer')
->identityFile('~/.ssh/deployerkey')
->set('deploy_path', '/var/www/html/laravel-app');
接下来, before('deploy:symlink', 'artisan:migrate');
注释掉文件的最后一行before('deploy:symlink', 'artisan:migrate');
。 此行指示部署者自动运行数据库迁移,并通过注释将其禁用。 如果不注释它,部署将失败,因为此行需要在服务器上提供适当的数据库凭据,只能使用在首次部署期间生成的文件来添加该文件。
...
// Migrate database before symlink new release.
//before('deploy:symlink', 'artisan:migrate');
在我们部署项目之前,我们必须先将其推送到远程Git存储库。
在本地机器上将工作目录更改为应用程序的文件夹:
cd /path/to/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
如果一切顺利,您应该看到一个像这样Successfully deployed!
的输出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
通过在服务器上运行以下命令来验证该文件,该命令将列出文件夹中的文件和目录:
ls /var/www/html/laravel-app
Outputcurrent .dep releases shared
以下是这些文件和目录中包含的内容:
releases
目录包含Laravel应用程序的部署版本。current
是最后一个版本的符号链接。.dep
目录包含Deployer的特殊元数据。shared
目录包含.env
配置文件和将被链接到每个版本的storage
目录。
但是,该应用程序无法工作,因为.env
文件是空的。 该文件用于保存重要的配置,如应用程序密钥 - 用于加密的随机字符串。 如果未设置,您的用户会话和其他加密数据将不安全。 该应用程序在本地机器上有一个.env
文件,但Laravel的.gitignore
文件将其从Git repo中排除,因为将密码等敏感数据存储在Git存储库中并不是一个好主意,而且该应用程序还需要在服务器上进行不同的设置。 .env
文件也包含数据库连接设置,这就是为什么我们禁用第一次部署的数据库迁移的原因。
让我们在你的服务器上配置应用程序。
以部署者用户身份登录到您的服务器:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
在您的服务器上运行以下命令,并将您的本地.env
文件复制并粘贴到编辑器中:
nano /var/www/html/laravel-app/shared/.env
在您保存之前,您应该进行一些更改。 将APP_ENV
设置为production
,将APP_ENV
设置为false
,将APP_LOG_LEVEL
设为error
并且不要忘记用自己的数据库,数据库用户和密码替换。 您应该将example.com
替换为您自己的域:
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:cA1hATAgR4BjdHJqI8aOj8jEjaaOM8gMNHXIP8d5IQg=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_database
DB_USERNAME=laravel_user
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
保存该文件并关闭编辑器。
现在取消注释本地计算机上deploy.php
文件的最后一行:
...
// Migrate database before symlink new release.
before('deploy:symlink', 'artisan:migrate');
警告:这会导致您的数据库迁移在每个部署中自动运行。 这样可以避免手动迁移数据库,但在部署之前不要忘记备份数据库。
要检查此配置是否正常,请再次部署该应用程序。 在本地机器上运行以下命令:
dep deploy
现在,您的应用程序将正常工作。 如果您访问服务器的域名( http://example.com ),您将看到以下登录页面:
在所有部署之前,您.env
在服务器上编辑.env
文件。 典型的部署不像第一部分那么复杂,只需要几条命令即可完成。
第7步 - 运行典型部署
作为最后一步,本节将介绍您可以每天使用的简单部署过程。
在再次部署之前,先修改应用程序。 例如,您可以在routes/web.php
文件中添加新路线:
<?php
. . .
Route::get('/', function () {
return view('welcome');
});
Route::get('/greeting', function(){
return 'Welcome!';
});
提交这些更改:
git commit -am 'Your commit message.'
将更改推送到远程Git存储库:
git push origin master
最后,部署应用程序:
dep deploy
您已成功将应用程序部署到您的服务器。
结论
您已配置本地计算机和服务器,以零宕机时间轻松部署Laravel应用程序。 本文仅涵盖部署者的基本知识,并且具有许多有用的功能。 您可以一次部署到更多服务器并创建任务; 例如,您可以指定一个任务来在迁移之前备份数据库。 如果您想了解关于部署者功能的更多信息,可以在部署者文档中找到更多信息。