如何在Ubuntu16.04上使用Nginx部署Laravel应用程序
Laravel 是用 PHP 编写的最流行的开源 Web 应用程序框架之一。 它旨在通过简化常用的应用程序任务(如缓存和身份验证)来帮助开发人员构建简单和复杂的应用程序。
在本教程中,我们将部署一个简单的 Laravel 应用程序,并考虑到生产环境,这需要一些常见的步骤。 例如,应用程序应使用专用数据库用户,其访问权限仅限于必要的数据库。 文件权限应该保证只有必要的目录和文件是可写的。 应考虑应用程序设置,以确保不会向最终用户显示调试信息,这可能会暴露应用程序配置详细信息。
本教程是关于部署现有应用程序的。 相反,如果您想了解如何使用 Laravel 框架本身,Laravel 自己的 Laravel from Scratch 系列是一个不错的起点。
先决条件
要遵循本教程,您将需要:
- 使用 this initial server setup tutorial 设置一台 Ubuntu 16.04 服务器,包括 sudo 非 root 用户和防火墙。
- 按照Linux, Nginx, MySQL, PHP (LEMP stack) on 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 管理帐户。 在网站中使用 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
。
/var/www/html/quickstart/.env
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
是该用户的数据库密码。
接下来,我们必须运行 database migrations,它将使用演示应用程序正常运行所需的表填充新创建的数据库。
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
指令来更新 Web 根目录, - 更新
server_name
指令以正确指向服务器的域名, - 通过更改
try_files
指令来更新请求 URI 处理。
修改后的 Nginx 配置文件将如下所示:
/etc/nginx/sites-enabled/example.com
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
,它将请求查询传递给 Laravel 主应用程序文件 index.php
文件。
完成上述更改后,您可以保存并关闭文件。 我们必须通过创建从该文件到 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 为应用程序提供服务。 这将确保应用程序与其访问者之间的所有通信都将被加密,如果应用程序要求提供登录或密码等敏感信息,这一点尤其重要。
Let's Encrypt 是一个免费的证书颁发机构,可让您轻松地将 TLS 添加到您的网站。 为了为新部署的应用程序启用 HTTPS,我们将遵循 如何在 Ubuntu 16.04 上使用 Let's Encrypt 保护 Nginx 教程,并进行一些小的修改以适应这个特定的 Laravel 应用程序的设置。
唯一的变化将是:
- 请求 SSL 证书时使用 Laravel 应用程序的位置 (
/var/www/html/quickstart
) 而不是默认的 Web 根目录 (/var/www/html
)。 - 修改
/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
配置文件的最终版本将如下所示
/etc/nginx/sites-enabled/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
。 您应该会看到与以前相同的申请表,但这次连接将完全安全。
结论
您现在已经成功地将 Laravel 附带的演示应用程序部署到使用 LEMP 堆栈的生产环境中。 对于现实世界的应用程序,配置任务列表可能涉及更多步骤和特定于应用程序的操作。 如有疑问,请始终参考您正在部署的应用程序的文档,但您也可以在 官方 Laravel 文档 中找到许多有用的信息。