如何在Ubuntu18.04上使用Nginx部署带有MySQL服务器的ASP.NETCore应用程序
作为 Write for DOnations 计划的一部分,作者选择了 Open Source Initiative 来接受捐赠。
介绍
ASP.NET Core 是用于构建现代 Web 应用程序的高性能开源框架,旨在成为 Microsoft 的 ASP.NET Framework 的更加模块化的版本。 它于 2016 年发布,可以在 Linux 和 macOS 等多种操作系统上运行。 这使开发人员能够根据设计要求针对特定的操作系统进行开发。 使用 ASP.NET Core,开发人员可以构建任何类型的 Web 应用程序或服务,无论其复杂性和大小如何。 开发人员还可以利用 Razor pages 在传统的 Model-View-Controller (MVC) 模式之上创建以页面为中心的设计。
ASP.NET Core 提供了与任何前端框架集成以处理客户端逻辑或使用 Web 服务的灵活性。 例如,您可以使用 ASP.NET Core 构建一个 RESTful API,并通过 Angular、React 和 Vue.js 等 JavaScript 框架轻松使用它。
在本教程中,您将使用 Nginx 在 Ubuntu 18.04 上设置和部署具有 MySQL 服务器的生产就绪 ASP.NET 核心应用程序。 您将部署一个演示 ASP.NET 核心应用程序,该应用程序类似于 Microsoft 文档中的应用程序,并托管在 GitHub 上。 部署后,演示应用程序将允许您创建电影列表并将其存储在数据库中。 您将能够从数据库中创建、读取、更新和删除记录。 您可以使用本教程来部署您自己的 ASP.NET Core 应用程序; 您可能必须实施额外的步骤,包括为您的数据库生成新的迁移文件。
先决条件
本教程将需要以下内容:
- 按照 Ubuntu 18.04 初始服务器设置指南 设置一台 Ubuntu 18.04 服务器,包括具有
sudo
访问权限和防火墙的非 root 用户。 - 按照 How To Install Nginx on Ubuntu 18.04 安装 Nginx。
- 一个安全的 Nginx Web 服务器。 您可以在 How To Secure Nginx with Let's Encrypt on Ubuntu 18.04 上学习本教程。
- 为您的服务器设置了以下两个 DNS 记录。 您可以按照此 DigitalOcean DNS 介绍了解如何添加它们的详细信息。 您的域指向您服务器的公共 IP 地址的 A 记录。 带有 www.your-domain 的 A 记录指向您服务器的公共 IP 地址。
- 按照 如何在 Ubuntu 18.04 上安装最新的 MySQL 安装 MySQL。
第 1 步 — 安装 .NET Core 运行时
成功运行 .NET Core 应用程序需要 .NET Core 运行时,因此您首先将其安装到您的计算机上。 首先,您需要注册 Microsoft Key 和产品存储库。 之后,您将安装所需的依赖项。
首先,以新创建的用户身份登录,确保您位于根目录中:
cd ~
接下来,运行以下命令来注册 Microsoft 密钥和产品存储库:
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
使用带有 -i
标志的 dpkg
来安装指定的文件:
sudo dpkg -i packages-microsoft-prod.deb
为了方便安装应用程序所需的其他包,您将使用以下命令安装 universe
存储库:
sudo add-apt-repository universe
接下来安装 apt-transport
软件包以允许使用通过 HTTP 安全协议访问的存储库:
sudo apt install apt-transport-https
现在,运行以下命令从存储库下载包列表并更新它们以获取有关最新版本的包及其依赖项的信息:
sudo apt update
最后,您可以安装 .NET 运行时 SDK:
sudo apt install dotnet-sdk-2.2
系统将提示您有关将安装的其他文件大小的详细信息。 输入 Y
并点击 ENTER
继续。
现在您已在服务器上安装了 .NET Core 运行时 SDK,您几乎可以从 GitHub 下载演示应用程序并设置部署配置了。 但首先,您将为应用程序创建数据库。
第 2 步 — 创建 MySQL 用户和数据库
在本节中,您将创建一个 MySQL 服务器用户,为应用程序创建一个数据库,并授予新用户从应用程序连接到数据库所需的所有必要权限。
首先,您需要使用 MySQL root 帐户访问 MySQL 客户端,如下所示:
mysql -u root -p
系统将提示您输入在先决条件教程中设置的 root 帐户密码。
接下来,为应用程序创建一个 MySQL 数据库:
CREATE DATABASE MovieAppDb;
您将在控制台中看到以下输出:
OutputQuery OK, 1 row affected (0.03 sec)
您现在已成功创建数据库。 接下来,您将创建一个新的 MySQL 用户,将他们与新创建的数据库相关联,并授予他们所有权限。
运行以下命令以创建 MySQL 用户和密码。 请记住将用户名和密码更改为更安全的内容:
CREATE USER 'movie-admin'@'localhost' IDENTIFIED BY 'password';
您将看到以下输出:
OutputQuery OK, 0 rows affected (0.02 sec)
要访问数据库或对其执行特定操作,MySQL 用户需要适当的权限。 目前 movie-admin 对应用程序数据库没有适当的权限。
您将通过运行以下命令来更改它以授予对 MovieAppDb
上的 movie-admin 的访问权限:
GRANT ALL PRIVILEGES ON MovieAppDb.* TO 'movie-admin'@'localhost';
您将看到以下输出:
OutputQuery OK, 0 rows affected (0.01 sec)
现在,您可以通过运行以下命令来重新加载授权表,以应用您刚刚使用 flush 语句所做的更改:
FLUSH PRIVILEGES;
您将看到以下输出:
OutputQuery OK, 0 rows affected (0.00 sec)
您已完成创建新用户并授予权限。 要测试您是否正常,请退出 MySQL 客户端:
quit;
使用您刚刚创建的 MySQL 用户的凭据再次登录,并在出现提示时输入适当的密码:
mysql -u movie-admin -p
检查以确保用户 movie-admin 可以访问创建的数据库,检查:
SHOW DATABASES;
您将看到输出中列出的 MovieAppDb
表:
Output+--------------------+ | Database | +--------------------+ | MovieAppDb | | information_schema | +--------------------+ 2 rows in set (0.01 sec)
现在,退出 MySQL 客户端:
quit;
您已经创建了一个数据库,为演示应用程序创建了一个新的 MySQL 用户,并授予新创建的用户访问数据库的权限。 在下一部分中,您将开始设置演示应用程序。
第 3 步 — 设置演示应用程序和数据库凭据
如前所述,您将部署现有的 ASP.NET Core 应用程序。 此应用程序旨在创建电影列表,它使用模型-视图-控制器设计模式来确保正确的结构和关注点分离。 要创建新电影或将新电影添加到列表中,用户将使用适当的详细信息填充表单字段,然后单击 Create 按钮将详细信息发布到控制器。 此时控制器将收到一个带有提交详细信息的 POST HTTP 请求,并通过模型将数据持久化到数据库中。
您将使用 Git 从 GitHub 中提取此演示应用程序的源代码并将其保存在新目录中。 如果您要部署不同的应用程序,也可以在此处下载备用应用程序。
首先,使用以下命令从终端创建一个名为 movie-app
的新目录:
sudo mkdir -p /var/www/movie-app
这将作为您的应用程序的根目录。 接下来,更改文件夹所有者和组,以允许非 root 用户帐户使用项目文件:
sudo chown sammy:sammy /var/www/movie-app
将 sammy 替换为您的 sudo 非 root 用户名。
现在,您可以进入父目录并在 GitHub 上克隆应用程序:
cd /var/www git clone https://github.com/do-community/movie-app-list.git movie-app
您将看到以下输出:
OutputCloning into 'movie-app'... remote: Enumerating objects: 91, done. remote: Counting objects: 100% (91/91), done. remote: Compressing objects: 100% (73/73), done. remote: Total 91 (delta 13), reused 91 (delta 13), pack-reused 0 Unpacking objects: 100% (91/91), done.
您已成功从 GitHub 克隆了演示应用程序,因此下一步将是创建与应用程序数据库的成功连接。 您将通过编辑 appsettings.json
文件中的 ConnectionStrings
属性并添加数据库的详细信息来完成此操作。
将目录更改为应用程序:
cd movie-app
现在打开文件进行编辑:
sudo nano appsettings.json
添加您的数据库凭据:
应用设置.json
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MovieContext": "Server=localhost;User Id=movie-admin;Password=password;Database=MovieAppDb" } }
有了这个,您就成功地创建了与数据库的连接。 现在按 CTRL+X
将更改保存到文件并键入 Y
进行确认。 然后点击ENTER
退出页面。
ASP.NET Core 应用程序使用名为 Entity Framework (EF) Core 的 .NET 标准库来管理与数据库的交互。 Entity Framework Core 是流行的 Entity Framework 数据访问技术的轻量级、跨平台版本。 它是一个对象关系映射器 (ORM),使 .NET 开发人员能够使用任何数据库提供程序(例如 MySQL)来处理数据库。
您现在可以使用克隆的演示应用程序中的表更新您的数据库。 为此目的运行以下命令:
dotnet ef database update
这将对数据库应用更新并创建适当的模式。
现在,要构建项目及其所有依赖项,请运行以下命令:
dotnet build
您将看到类似于以下内容的输出:
OutputMicrosoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 95.09 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:01.91
这将构建项目并安装 project.assets.json
文件中列出的任何第三方依赖项,但应用程序尚未准备好投入生产。 要使应用程序准备好部署,请运行以下命令:
dotnet publish
您将看到以下内容:
OutputMicrosoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 89.62 ms for /var/www/movie-app/MvcMovie.csproj. MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll MvcMovie -> /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/
这将打包和编译应用程序,读取其依赖项,将生成的文件集发布到一个文件夹中进行部署,并生成一个跨平台的 .dll
文件,该文件使用已安装的 .NET Core 运行时运行应用程序.
通过安装依赖项、创建与数据库的连接、使用必要的表更新数据库并将其发布到生产环境,您已经完成了此演示应用程序的设置。 在下一步中,您将配置 Web 服务器以使应用程序在您的域中可访问且安全。
第 4 步 — 配置 Web 服务器
现在,按照 How To Secure Nginx with Let's Encrypt 教程 ,您将在 /etc/nginx/sites-available/your_domain
处为您的域提供一个服务器块,其中 server_name
指令已经正确设置. 在此步骤中,您将编辑此服务器块以将 Nginx 配置为您的应用程序的反向代理。 反向代理是位于 Web 服务器前面的服务器,它将每个 Web 浏览器的请求转发到这些 Web 服务器。 它接收来自网络的所有请求并将它们转发到不同的 Web 服务器。
对于 ASP.NET Core 应用程序,Kestrel 是默认包含的首选 Web 服务器。 它非常适合从 ASP.NET 核心应用程序提供动态内容,因为它提供了更好的请求处理性能,并且旨在使 ASP.NET 尽可能快。 但是,Kestrel 不被认为是功能齐全的 Web 服务器,因为它无法管理安全性和提供静态文件,这就是为什么建议始终在 Web 服务器后面运行它的原因。
首先,确保您位于服务器的根目录中:
cd ~
打开服务器块进行编辑:
sudo nano /etc/nginx/sites-available/your_domain
如 How To Secure Nginx with Let's Encrypt 教程 的 Step 4 中详述,如果您选择选项 2,Certbot 将自动配置此服务器块以将 HTTP 流量重定向到 HTTPS只需进行一些修改。
通过编辑文件中的前两个块来继续配置以反映以下内容:
/etc/nginx/sites-available/你的域
server { server_name your-domain www.your-domain; location / { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } ...
此服务器块中的配置将指示 Nginx 侦听端口 443
,这是使用 SSL 的网站的标准端口。 此外,Nginx 将接受端口 443
上的公共流量,并将每个匹配的请求转发到 http://localhost:5000
的内置 Kestrel 服务器。
最后,在您刚刚在文件中编辑的服务器块之后,确保第二个服务器块看起来像这样:
/etc/nginx/sites-available/你的域
... server { if ($host = www.your-domain) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = your-domain) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name your-domain www.your-domain; return 404; # managed by Certbot }
此服务器块会将所有对 https://your-domain
和 https://www.your-domain
的请求重定向到安全的 HTTPS 访问。
接下来,强制 Nginx 通过运行以下命令获取您对服务器块所做的更改:
sudo nginx -s reload
成功完成 Nginx 配置后,服务器已完全设置为将向 https://your-domain
发出的所有 HTTPS 请求转发到在 http://localhost:5000
的 Kestrel 上运行的 ASP.NET 核心应用程序. 但是,Nginx 并未设置为管理 Kestrel 服务器进程。 要处理此问题并确保 Kestrel 进程继续在后台运行,您将使用 systemd
功能。
Systemd 文件将允许您在创建称为单元的工作流程后通过提供启动、停止、重新启动和日志功能来管理流程。
移动到 systemd
目录:
cd /etc/systemd/systems
创建一个新文件进行编辑:
sudo nano movie.service
向其中添加以下内容:
电影服务
[Unit] Description=Movie app [Service] WorkingDirectory=/var/www/movie-app ExecStart=/usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll Restart=always RestartSec=10 SyslogIdentifier=movie User=sammy Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
配置文件使用 WorkingDirectory
指定项目文件夹的位置,并在 ExecStart
中指定在进程开始时要执行的命令。 此外,您已使用 RestartSec
指令指定在 .NET 运行时服务崩溃时何时重新启动 systemd
服务。
现在保存文件并启用使用以下命令创建的新电影服务:
sudo systemctl enable movie.service
之后,继续启动服务并通过启动服务来验证它是否正在运行:
sudo systemctl start movie.service
然后检查它的状态:
sudo systemctl status movie.service
您将看到以下输出:
Outputmovie.service - Movie app Loaded: loaded (/etc/systemd/system/movie.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2019-06-23 04:51:28 UTC; 11s ago Main PID: 6038 (dotnet) Tasks: 16 (limit: 1152) CGroup: /system.slice/movie.service └─6038 /usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll
此输出为您提供了为保持您的应用程序运行而创建的 movie.service
的当前状态的概览。 它表示该服务已启用且当前处于活动状态。
从浏览器导航到 https://your-domain
以运行并测试应用程序。
您将看到演示应用程序的主页——电影列表应用程序。
通过 systemd 配置反向代理和 Kestrel 管理后,Web 应用程序已完全配置并且可以从浏览器访问。
结论
在本教程中,您将 ASP.NET Core 应用程序部署到 Ubuntu 服务器。 为了持久化和管理数据,您安装并使用了 MySQL 服务器,并使用 Nginx Web 服务器作为反向代理来为您的应用程序提供服务。
除了本教程之外,如果您对使用 C# 而不是 Javascript 构建交互式 Web 应用程序感兴趣,您可以尝试 Microsoft 的称为 Blazor 的 Web UI 框架。 它是一个事件驱动的基于组件的 Web UI,用于在 ASP.NET Core 应用程序的客户端实现逻辑。
如果您希望部署自己的应用程序,则需要考虑部署应用程序所需的其他程序。 可以在 GitHub 上的 此处找到此演示应用程序的完整源代码。