介绍
Laravel 是一个开源的 PHP Web 框架,旨在简化常见的 Web 开发任务,例如身份验证、路由和缓存。 Deployer 是一个开源的 PHP 部署工具,开箱即用地支持许多流行的框架,包括 Laravel、CodeIgniter、Symfony 和 Zend Framework。
Deployer 通过将应用程序从 Git 存储库克隆到服务器、使用 Composer 安装依赖项以及配置应用程序来自动化部署,因此您不必手动执行此操作。 这使您可以将更多时间花在开发上,而不是上传和配置上,并让您更频繁地部署。
在本教程中,您将自动部署 Laravel 应用程序而无需停机。 为此,您将准备用于部署代码的本地开发环境,然后使用 Nginx 和 MySQL 数据库配置生产服务器来为应用程序提供服务。
先决条件
在开始本指南之前,您需要以下内容:
- 一台 Ubuntu 16.04 服务器,非 root 用户具有 sudo 权限,如 使用 Ubuntu 16.04 的初始服务器设置教程中所述。
- 按照 How To Install Linux, Nginx, MySQL, PHP (LEMP stack) in Ubuntu 16.04 教程中所述安装的 LEMP 堆栈。
- 按照 如何在 Ubuntu 16.04 上安装和使用 Composer 的步骤 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 步 — 设置本地开发环境
由于您将从本地计算机创建和部署应用程序,因此首先要配置本地开发环境。 Deployer 将从您的本地计算机控制整个部署过程,因此首先安装它。
注意: 如果您在本地机器上使用 Windows,您应该使用 BASH 模拟器(如 Git bash)来运行所有本地命令。
在您的 本地计算机 上,打开终端并使用 curl
下载 Deployer 安装程序:
curl -LO https://deployer.org/deployer.phar
接下来,运行一个简短的 PHP 脚本来验证安装程序是否与 Deployer - 下载页面 上找到的最新安装程序的 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
使 Deployer 在系统范围内可用。 请注意,如果您在本地计算机上运行 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 存储库
Deployer 旨在使用户能够从任何地方部署代码。 为了实现这一功能,它需要用户将代码推送到 Internet 上的存储库,然后 Deployer 会从该存储库将代码复制到生产服务器。 我们将使用开源版本控制系统 Git 来管理 Laravel 应用程序的源代码。 您可以使用 SSH 协议连接到 Git 服务器,为了安全地执行此操作,您需要生成 SSH 密钥。 这比基于密码的身份验证更安全,让您避免在每次部署之前输入密码。
在您的 本地计算机 上运行以下命令以生成 SSH 密钥。 注意 -f
指定密钥文件的文件名,您可以将 gitkey 替换为自己的文件名。 它将生成一个 SSH 密钥对(名为 gitkey
和 gitkey.pub
)到 ~/.ssh/
文件夹。
ssh-keygen -t rsa -b 4096 -f ~/.ssh/gitkey
您的本地计算机上可能有更多 SSH 密钥,因此配置 SSH 客户端以了解在连接到 Git 服务器时要使用哪个 SSH 私钥。
在本地机器 上创建 SSH 配置文件 :
touch ~/.ssh/config
打开该文件并为您的 Git 服务器添加一个快捷方式。 这应该包含 HostName
指令(指向您的 Git 服务器的主机名)和 IdentityFile
指令(指向您刚刚创建的 SSH 密钥的文件路径:
~/.ssh/config
Host mygitserver.com HostName mygitserver.com 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 步 — 配置 Deployer 用户
Deployer 使用 SSH 协议在服务器上安全地执行命令。 出于这个原因,我们配置生产服务器的第一步将是创建一个用户,Deployer 可以使用该用户通过 SSH 在您的服务器上登录和执行命令。
使用 sudo 非 root 用户登录到您的 LEMP 服务器,并使用以下命令创建一个名为“deployer”的新用户:
sudo adduser deployer
Laravel 需要一些可写的目录来存储缓存文件和上传,所以 deployer 用户创建的目录必须是 Nginx 网络服务器可写的。 将用户添加到 www-data 组以执行此操作:
sudo usermod -aG www-data deployer
deployer 用户创建的文件的默认权限应该是文件的 644
和目录的 755
。 这样,deployer 用户将能够读取和写入文件,而组和其他用户将能够读取它们。
通过将 deployer 的默认 umask 设置为 022
来做到这一点:
sudo chfn -o umask=022 deployer
我们将应用程序存储在 /var/www/html/
目录中,因此将目录的所有权更改为 deployer 用户和 www-data 组。
sudo chown deployer:www-data /var/www/html
deployer 用户需要能够修改 /var/www/html
目录中的文件和文件夹。 鉴于此,在 /var/www/html
目录中创建的所有新文件和子目录都应继承文件夹的组 ID (www-data)。 为此,请使用以下命令在此目录上设置组 ID:
sudo chmod g+s /var/www/html
Deployer 将使用 SSH 将 Git 存储库克隆到生产服务器,因此您要确保 LEMP 服务器和 Git 服务器之间的连接是安全的。 我们将使用与本地计算机相同的方法,并为 deployer 用户生成一个 SSH 密钥。
切换到服务器上的 deployer 用户:
su - deployer
接下来,以 deployer 用户的身份生成一个 SSH 密钥对。 这一次,您可以接受 SSH 密钥的默认文件名:
ssh-keygen -t rsa -b 4096
显示公钥:
cat ~/.ssh/id_rsa.pub
复制公钥并将其添加到您的 Git 服务器,就像您在上一步中所做的那样。
您的本地计算机也将使用 SSH 与服务器通信,因此您应该在本地计算机上为 deployer 用户生成 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 服务器,您可以从本地计算机使用 deployer 用户登录服务器。
以 deployer 用户身份从本地计算机登录到服务器以测试连接:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
以 deployer 身份登录后,同样测试您的服务器和 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
块:
/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; }
顶部的两个 listen
指令告诉 Nginx 监听哪些端口,root
指令定义了安装 Laravel 的文档根目录。 根目录路径中的 current/public
是一个符号链接,指向应用程序的最新版本。 通过添加 index
指令,我们告诉 Nginx 在请求目录位置时先提供任何 index.php
文件,然后再查找对应的 HTML。 server_name
指令后面应该跟您的域及其任何别名。
我们还应该修改 Nginx 处理请求的方式。 这是通过 try_files
指令完成的。 我们希望它首先尝试将请求作为文件提供服务,如果它找不到具有正确名称的文件,它应该尝试为与请求匹配的目录提供默认索引文件。 否则,它应该将请求作为查询参数传递给 index.php
文件。
/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; }
接下来,我们需要创建一个块来处理任何 PHP 文件的实际执行。 这将适用于任何以 .php 结尾的文件。 它将尝试文件本身,然后尝试将其作为参数传递给 index.php
文件。
我们将设置 fastcgi
指令来告诉 Nginx 使用应用程序的实际路径(遵循符号链接后解决),而不是符号链接。 如果不将这些行添加到配置中,符号链接点的路径将被缓存,这意味着部署后将加载旧版本的应用程序。 如果没有这些指令,您将不得不在每次部署后手动清除缓存,并且对应用程序的请求可能会失败。 此外,fastcgi_pass
指令将确保 Nginx 使用 php7-fpm 用于通信的套接字,并且 index.php
文件用作这些操作的索引。
/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.0-fpm.sock; }
最后,我们要确保 Nginx 不允许访问任何隐藏的 .htaccess
文件。 为此,我们将添加一个名为 location ~ /\.ht
的位置块,并在该块中添加一个指定 deny all;
的指令。
添加最后一个位置块后,配置文件将如下所示:
/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.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
,尽管您应该使用您选择的强密码替换密码。
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';
将数据库权限授予用户:
GRANT ALL ON laravel_database.* TO 'laravel_user'@'localhost';
接下来,重新加载权限:
FLUSH PRIVILEGES;
最后,退出 MySQL 控制台:
EXIT;
您的应用程序的数据库和用户现在已配置好,您几乎可以开始运行您的第一个部署了。
第 6 步 — 部署应用程序
到目前为止,您已经配置了 Deployer 运行所需的所有工具和程序。 在运行第一个部署之前,剩下要做的就是完成 Laravel 应用程序和 Deployer 本身的配置,并初始化应用程序并将其推送到远程 Git 存储库。
在您的 本地计算机 上打开终端并使用以下命令将工作目录更改为应用程序的文件夹:
cd /path/to/laravel-app
在此目录中,运行以下命令,在 laravel-app
文件夹中创建一个名为 deploy.php
的文件,其中将包含配置信息和部署任务:
dep init -t Laravel
接下来,使用您喜欢的文本编辑器或 IDE 打开 deploy.php
文件。 第三行包含一个 PHP 脚本,其中包含部署 Laravel 应用程序所需的任务和配置:
部署.php
<?php namespace Deployer; require 'recipe/laravel.php'; . . .
下面是一些您应该编辑以与您的配置保持一致的字段:
- 在
// Project Name
下,添加 Laravel 项目的名称。 - 在
// Project Repository
下,将链接添加到您的 Git 存储库。 - 在
// Hosts
部分,将您的服务器的 IP 地址或域名添加到host()
指令,将您的 Deployer 用户的名称(在我们的示例中为 deployer)添加到 [X172X ] 指令。 您还应该将在第 3 步中创建的 SSH 密钥添加到identifyFile()
指令中。 最后,您应该添加包含您的应用程序的文件夹的文件路径。
完成对这些字段的编辑后,它们应如下所示:
部署.php
... // 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');
。 这一行指示 Deployer 自动运行数据库迁移,并且通过将其注释掉,我们将禁用它。 如果您不将其注释掉,则部署将失败,因为此行需要服务器上存在适当的数据库凭据,只能使用将在第一次部署期间生成的文件添加:
部署.php
... // 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!
:
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 存储库中排除,因为在 Git 存储库中存储密码等敏感数据不是好主意,而且,该应用程序需要在您的服务器上进行不同的设置。 .env
文件也包含数据库连接设置,这就是我们在第一次部署时禁用数据库迁移的原因。
让我们在您的服务器上配置应用程序。
以 deployer 用户身份登录到您的服务器:
ssh deployer@your_server_ip -i ~/.ssh/deployerkey
在您的服务器 上运行以下命令 ,然后将本地 .env
文件复制并粘贴到编辑器中:
nano /var/www/html/laravel-app/shared/.env
在保存之前,您应该进行一些更改。 将 APP_ENV
设置为 production
, APP_DEBUG
设置为 false
, APP_LOG_LEVEL
设置为 error
并且不要忘记更换数据库、数据库用户和您自己的密码。 您也应该将 example.com
替换为您自己的域:
/var/www/html/laravel-app/shared/.env
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
文件的最后一行:
部署.php
... // Migrate database before symlink new release. before('deploy:symlink', 'artisan:migrate');
警告: 这将导致您的数据库迁移在每次部署时自动运行。 这将使您避免手动迁移数据库,但不要忘记在部署之前备份数据库。
要检查此配置是否正常工作,请再次部署应用程序。 在本地机器 上运行以下命令 :
dep deploy
现在,您的应用程序将正常工作。 如果您访问服务器的域名(http://example.com),您将看到以下登录页面:
在所有部署之前,您不必编辑服务器上的 .env
文件。 典型的部署并不像第一次那样复杂,只需几个命令即可完成。
第 7 步 — 运行典型部署
作为最后一步,本节将介绍一个您可以每天使用的简单部署过程。
在再次部署之前先修改应用程序。 例如,您可以在 routes/web.php
文件中添加新路由:
/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 应用程序,并且停机时间为零。 本文只介绍了 Deployer 的基础知识,它有很多有用的功能。 您可以一次部署到更多服务器并创建任务; 例如,您可以指定一个任务来在迁移之前备份数据库。 如果您想了解更多关于 Deployer 的功能,您可以在 Deployer 文档 中找到更多信息。