如何在 Ubuntu 16.04 上使用 Nginx 部署 Laravel 应用程序
Laravel 是用 PHP 编写的最流行的开源 Web 应用程序框架之一。它旨在通过简化常用的应用程序任务(如缓存和身份验证)来帮助开发人员构建简单和复杂的应用程序。
在本教程中,我们将在生产环境中部署一个简单的 Laravel 应用程序,这需要一些常见的步骤。例如,应用程序应该使用一个专门的数据库用户,其访问权限仅限于必要的数据库。文件权限应该保证只有必要的目录和文件是可写的。应考虑应用程序设置,以确保没有调试信息显示给最终用户,这可能会暴露应用程序配置详细信息。
本教程是关于部署现有应用程序的。相反,如果您想了解如何使用 Laravel 框架本身,那么 Laravel 自己的 Laravel from Scratch 系列是一个很好的起点。
先决条件
要学习本教程,您需要:
- 使用此初始服务器设置教程设置的一台 Ubuntu 16.04 服务器,包括 sudo 非根用户和防火墙。
- 按照 Linux、Nginx、MySQL、PHP(LEMP 堆栈)在 Ubuntu 16.04 教程中安装的 LEMP 堆栈。
- 指向您的服务器的域名,如如何使用 DigitalOcean 设置主机名中所述。本教程将始终使用
example.com
。这是为您的网站获取 SSL 证书所必需的,这样您就可以使用 TLS 加密安全地提供您的应用程序。
第 1 步 — 安装包依赖项
要运行 Laravel 应用程序,除了基本的 LEMP 堆栈之外,您还需要一些 PHP 扩展和一个名为 Composer 的 PHP 依赖管理器。
首先更新包管理器缓存。
- sudo apt-get update
您需要的 PHP 扩展用于多字节字符串支持和 XML 支持。您可以同时安装这些扩展、Composer 和unzip
(允许 Composer 处理 zip 文件)。
- sudo apt-get install php7.0-mbstring php7.0-xml composer unzip
现在已经安装了包依赖项,我们将为该应用程序创建和配置一个 MySQL 数据库和专用用户帐户。
第 2 步 — 配置 MySQL
Laravel 支持多种数据库服务器。因为本教程使用 LEMP 堆栈,所以 MySQL 将为应用程序存储数据。
在默认安装中,MySQL 只创建 root 管理帐户。在网站中使用根数据库用户是一种糟糕的安全做法,因为它在数据库服务器上拥有无限权限。相反,让我们为 Laravel 应用程序创建一个专用的数据库用户,以及一个允许 Laravel 用户访问的新数据库。
登录到 MySQL root
管理帐户。
- mysql -u root -p
系统将提示您输入在安装期间为 MySQL root 帐户设置的密码。
首先创建一个名为 laravel
的新数据库,这是我们将用于该网站的数据库。您可以选择不同的名称,但请务必记住它,因为您稍后会需要它。
- CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
接下来,创建一个将被允许访问该数据库的新用户。这里我们使用 laraveluser
作为用户名,但你也可以自定义它。请记住将以下行中的 password
替换为强而安全的密码。
- GRANT ALL ON laravel.* TO 'laraveluser'@'localhost' IDENTIFIED BY 'password';
刷新权限以将更改通知 MySQL 服务器。
- FLUSH PRIVILEGES;
并退出 MySQL。
- EXIT;
您现在已经为 Laravel 配置了一个专用数据库和用户帐户。数据库组件已准备就绪,接下来,我们将设置演示应用程序。
第 3 步 — 设置演示应用程序
由 Laravel 在 GitHub 上发布的演示 quickstart
应用程序是一个简单的任务列表。它允许您添加和删除待办事项并将其任务存储在 MySQL 数据库中。
首先,在 Nginx Web 根目录中创建一个目录来存放应用程序。因为演示应用程序名为 quickstart
,所以我们使用 /var/www/html/quickstart
。
- sudo mkdir -p /var/www/html/quickstart
接下来,将新创建的目录的所有权更改为您的用户,这样您就可以在不使用 sudo
的情况下使用其中的文件。
- sudo chown sammy:sammy /var/www/html/quickstart
移动到新目录并使用 Git 克隆演示应用程序。
- cd /var/www/html/quickstart
- git clone https://github.com/laravel/quickstart-basic .
Git 将从演示应用程序存储库下载所有文件。您会看到如下所示的输出:
Git outputCloning into '.'...
remote: Counting objects: 263, done.
remote: Total 263 (delta 0), reused 0 (delta 0), pack-reused 263
Receiving objects: 100% (263/263), 92.75 KiB | 0 bytes/s, done.
Resolving deltas: 100% (72/72), done.
Checking connectivity... done.
接下来,我们需要安装项目依赖项。 Laravel 利用 Composer 来处理依赖管理,这使得一次安装必要的包变得容易。
- composer install
有点冗长的输出将显示所有项目依赖项的安装进度:
Composer outputLoading composer repositories with package information
Installing dependencies (including require-dev) from lock file
. . .
Generating autoload files
> php artisan clear-compiled
> php artisan optimize
Generating optimized class loader
应用程序本身已设置,因此下一步是配置应用程序环境。这涉及连接应用程序和数据库以及为生产定制一些设置。
第 4 步 — 配置应用程序环境
在这一步中,我们将修改一些与安全相关的应用程序设置,允许应用程序连接到数据库,并准备数据库以供使用。这些是所有 LEMP 支持的 Laravel 应用程序的必要步骤,而不仅仅是我们在这里使用的演示应用程序。
使用 nano
或您喜欢的文本编辑器打开 Laravel 环境配置文件。
- sudo nano /var/www/html/quickstart/.env
您需要对该文件进行以下更改。确保使用适当的值更新占位符变量,例如 password
和 example.com
。
APP_ENV=production
APP_DEBUG=false
APP_KEY=b809vCwvtawRbsG0BmP1tWgnlXQypSKf
APP_URL=http://example.com
DB_HOST=127.0.0.1
DB_DATABASE=laravel
DB_USERNAME=laraveluser
DB_PASSWORD=password
. . .
保存文件并退出。
让我们更详细地了解这些变化。这里有两个配置块;第一个用于应用程序配置,第二个用于数据库配置。
在应用程序配置部分:
- <李>
APP_ENV
变量表示应用程序运行的系统环境。默认值为 local
,用于本地开发环境。对于生产部署,它应该更改为 production
,就像我们在这里所做的那样。 更改此变量可控制日志详细程度、缓存设置以及错误的显示方式(取决于应用程序)。使用 local
设置,它的设置是为了简化开发和调试,这在开发应用程序时很方便,但不应在生产设置中使用。 <李> APP_DEBUG
变量补充 APP_ENV
并显式启用或禁用调试信息和详细错误显示。在生产设置中,此值应设置为 false
以防止向用户显示调试信息。 <李> APP_URL
变量指定可以访问站点的 IP 地址或域名。我们在这里使用了 example.com
域名,但您应该将其替换为您自己的域名,该网站应该被访问。 数据库配置部分更简单一些:
DB_DATABASE
是数据库的名称。DB_USERNAME
是应用应使用的 MySQL 用户的名称。DB_PASSWORD
是该用户的数据库密码。
接下来,我们必须运行数据库迁移,这将使用演示应用程序正常运行所需的表填充新创建的数据库。
- php artisan migrate
Artisan 将要求确认我们是否打算在生产模式下运行它。对问题回答 y
。之后它将运行必要的数据库任务。
Artisan output**************************************
* Application In Production! *
**************************************
Do you really wish to run this command? [y/N] (yes/no) [no]:
> y
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2015_10_27_141258_create_tasks_table
我们现在已经完全安装和配置了 Laravel。接下来,我们需要配置 Nginx 来为应用程序提供服务。
第 5 步 — 配置 Nginx
应用程序目录由我们的系统用户 sammy 所有,Web 服务器可读但不可写。这对于大多数应用程序文件都是正确的,但只有少数目录需要特殊处理。具体来说,无论 Laravel 在哪里存储上传的媒体和缓存数据,Web 服务器都必须不仅能够访问它们,而且能够向它们写入文件。
让我们将 storage
和 bootstrap/cache
目录的组所有权更改为 www-data。
- sudo chgrp -R www-data storage bootstrap/cache
然后递归授予该组所有权限,包括写入和执行。
- sudo chmod -R ug+rwx storage bootstrap/cache
我们现在拥有所有具有适当权限的演示应用程序文件。接下来,我们需要更改 Nginx 配置以使其正确地与 Laravel 安装一起工作。首先,让我们通过复制默认文件为我们的应用程序创建一个新的服务器块配置文件。
- sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
打开新创建的配置文件。
- sudo nano /etc/nginx/sites-available/example.com
您必须进行一些必要的更改:
- 从
listen
指令中删除default_server
标记, - 通过更改
root
指令更新网络根目录, - 更新
server_name
指令以正确指向服务器的域名, - 通过更改
try_files
指令更新请求 URI 处理。
修改后的 Nginx 配置文件如下所示:
server {
listen 80;
listen [::]:80;
. . .
root /var/www/html/quickstart/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;
}
. . .
}
让我们更详细地解释这些变化。
默认配置文件中的 listen
指令启用了 default_server
选项,它指定如果没有其他服务器块合适,则该服务器块应该为请求提供服务。只有一个启用的服务器块可以启用此选项。因为我们保留了默认服务器块,所以我们将从第二个配置文件中删除 default_server
指定。
root
指令指定应用程序文件的存储位置。 Laravel 应用存放在/var/www/html/quickstart
,但只有/public
子目录应该暴露在互联网上;根本不应通过浏览器访问所有其他应用程序文件。为了遵守这些最佳实践,我们将 Web 根目录设置为 /var/www/html/quickstart/public
。
server_name
指令指定服务器块将响应的域名列表。我们这里使用了example.com
和www.example.com
,但是你应该把它们换成域名你想用于你的网站。
我们还更改了请求 URI 处理。默认设置告诉 Web 服务器先查找现有文件,然后查找现有目录,或者最后抛出 404 Not Found 错误(使用内置的 =404
设置)。为了让 Laravel 正常工作,所有请求都必须路由到 Laravel 本身。这意味着我们移除 Nginx 的默认 404 错误处理程序并将其设置为 /index.php?$query_string
,它将请求查询传递给 index.php
文件,这是一个主要的 Laravel 应用程序文件。
完成上述更改后,您可以保存并关闭文件。我们必须通过创建从该文件到 sites-enabled
目录的符号链接来启用新的配置文件。
- sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
最后重新加载 Nginx 以考虑更改。
- sudo systemctl reload nginx
现在 Nginx 已配置为演示 Laravel 应用程序提供服务,所有组件都已设置。
确保您的部署此时正常运行很容易。只需在您喜欢的浏览器中访问 http://example.com
。您会看到一个带有简单任务应用程序的页面,您可以尝试添加或删除任务。您所做的所有更改都将保存到数据库中,并保留用于以后访问该网站,您可以通过关闭浏览器并再次打开该网站来验证。
在下一步也是最后一步中,我们将配置 TLS 加密以通过安全连接为应用程序提供服务。
第 6 步 — 使用 TLS 保护您的应用程序
要完成生产设置,建议使用 TLS 通过安全 HTTPS 为应用程序提供服务。这将确保应用程序与其访问者之间的所有通信都将被加密,如果应用程序要求提供敏感信息(例如登录名或密码),这一点尤为重要。
如何在 Ubuntu 16.04 教程中使用 Let's Encrypt 保护 Nginx,并进行一些小修改以适应此特定 Laravel 应用程序的设置。
唯一的变化是:
- 使用 Laravel 应用程序的位置 (
/var/www/html/quickstart
) 而不是默认的网络根目录 (/var/www/html
) 请求 SSL 证书时。 - 修改
/etc/nginx/sites-available/example.com
配置文件而不是默认服务器块文件。
具体来说,获取证书的命令将是:
- sudo certbot certonly --webroot --webroot-path=/var/www/html/quickstart -d example.com -d www.example.com
/etc/nginx/sites-available/example.com
配置文件的最终版本将如下所示
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /var/www/html/quickstart/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_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
location ~ /.well-known {
allow all;
}
}
确保检查配置中没有语法错误。
- sudo nginx -t
如果所有更改都成功,您将获得如下所示的结果:
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
如果是这种情况,您可以安全地重启 Nginx 以使更改生效。
- sudo systemctl restart nginx
Let's Encrypt TLS/SSL 证书将完全到位,应用程序将通过安全连接可用。要验证一切是否按预期工作,只需访问 https://example.com
。您应该会看到与之前相同的申请表,但这次连接将完全安全。
结论
您现在已经使用 LEMP 堆栈成功地将 Laravel 附带的演示应用程序部署到生产环境中。对于现实世界的应用程序,配置任务列表可能涉及更多步骤和特定于应用程序的操作。如有疑问,请始终参考您正在部署的应用程序的文档,但您也可以在 Laravel 官方文档中找到很多有用的信息。