Docker 化 ASP.NET Boilerplate 项目






4.93/5 (20投票s)
使用 redis、haproxy 和 abp module zero core 模板在 Docker 容器中创建 Web Farm
- 从 Github 仓库获取源代码
引言
在本文中,我将一步一步地向您展示如何在 Docker 上运行 ABP module zero core 模板。然后,我们将讨论 Web Farm 的替代方案,例如使用 Redis 和 Haproxy。
您知道,Docker 是最流行的软件容器平台。我不会详细介绍如何在 Windows 上安装/配置 Docker 或使用 Docker 的优点。您可以在此处找到相关文档。还有一个入门指南。
什么是 ABP Module Zero Core 模板?
Module zero core 模板 是使用 ASP.NET Boilerplate Framework 开发的入门项目模板。这是一个 .NET Core 项目,使用 Angular4 作为单页应用程序。同时,也有一个多页 MVC 应用程序。但在本文中,我将解释 Angular4 版本。
在 module zero core 模板项目中,有两个独立的项目,一个是作为 Web UI 的 Angular4 项目,另一个是 Angular UI 使用的宿主项目。在将其运行在 Docker 上之前,我们先来检查一下它,以便更好地理解项目。
入门
从网站创建模板
首先,我将从 https://www.aspnetboilerplate.com/Templates 网站下载 module zero core 模板。
框架:.NET Core2.0 + 单页 Web 应用程序 Angular + 包含 module zero
项目名称:Acme.ProjectName
在准备项目运行在 Docker 上之前,我们先运行一下项目。我打开 ProjectName\aspnet-core 文件夹中的 .sln 文件。
使用 EF Migrations 创建数据库
在运行项目之前,我们应该在程序包管理器控制台中使用 EF migrations 创建数据库。首先,我将 Acme.ProjectName.Web.Host
设置为启动项目。(右键单击 Host 项目并选择设置为启动项目)。然后,打开程序包管理器控制台,将默认项目选择为 EntityFrameworkCore
,然后运行以下命令
update-database
运行此命令后,将以 ProjectNameDb
的名称创建数据库。
运行 Host 项目
现在,Host 项目已准备好运行。在 Visual Studio 中按 Ctrl+F5。它会打开 swagger
方法索引页。
所有这些服务都托管在项目的应用程序层,并由 Angular UI 使用。
运行 Angular 项目
在 Host 已运行的情况下,我们可以运行使用 API 的Angular 项目。要运行Angular 项目,请确保您的计算机上已安装node 和 npm。
首先,在 ProjectName\angular 位置运行 cmd
,然后运行命令 "npm install
" 或直接运行 "yarn
" 来获取客户端包。
在同一目录中运行 npm start
命令来启动 Angular 项目。
最后,您应该在输出屏幕中看到 "webpack: Compiled successfully
" 这行。
我们已成功启动 Angular 项目。在浏览器中打开并导航到 https://:4200/。
请使用以下凭据登录
用户名 | admin |
密码 | 123qwe |
登录后,您将看到以下屏幕
有关更多详细信息,请在此处查看。
总结一下我们为运行 Angular 项目所做的
- 在 ProjectName\angular 位置运行
cmd
。 - 运行
yarn
或npm install
命令(我在上述示例中使用了 yarn)。 - 运行
npm start
命令。 - 访问
localhost:4200
查看 Angular 项目是否正在运行。
一切运行正常。准备在 Docker 上运行...
在 Docker 上运行项目
如果您尚未安装 Angular CLI,则必须安装它。运行以下命令安装 Angular CLI。
npm install -g @angular/cli
确保 Angular CLI 已安装后,让我们查看文件和文件夹以配置 Docker 环境。在 ProjectName/aspnet-core 下有一个名为 docker 的文件夹。
在 docker/ng 文件夹中,有一个 docker-compose.yml 文件和两个用于运行 (up.ps1) 和停止 (down.ps1) docker compose 的 powershell 脚本。还有一个额外的文件夹和一个 powershell 脚本文件。
此脚本文件用于构建和发布宿主项目和 angular 项目。此外,此脚本将 docker 文件夹中的文件复制到 build 文件夹。首先,我将在 ProjectName/aspnet-core/build 位置运行 build-with-ng.ps1 脚本。
运行脚本后,当您查看 build 文件夹时,您会看到 outputs 文件夹。
在运行 up.ps1
命令之前
- 您必须共享驱动器。要共享它,请右键单击 Docker 系统托盘,转到设置,导航到共享文件夹并勾选所有驱动器。
- 数据库托管在本地机器上,而不是在 docker 上。托管在 Docker 上的网站将连接到您的本地数据库。使用受信任的连接字符串,连接将不成功。因此,请设置您的 SQL 数据库用户名和密码。要实现这一点,请修改文件 "...\aspnet-core\src\Acme.ProjectName.Web.Host\appsettings.Staging.json"。更新 Default ConnectionStrings > "Server=10.0.75.1; Database=ProjectNameDb; User=sa; Password=<请填写您的密码>;"
在 ProjectName/aspnet-core/build/outputs 位置运行 up.ps1
脚本,在 docker 上运行这两个项目。
Angular 和宿主项目现在正在运行。访问 https://:9901/ 访问宿主项目,访问 https://:9902/ 访问 Angular UI。
使用 Redis 和 Haproxy 在 Docker 上运行 Module Zero Core 模板 Web Farm
在 Web Farm 中,有多个 Web 服务器,服务器前面有一个负载均衡器,还有一个用于存储共享会话/缓存的服务器。
在我们的示例中,Angular 应用程序将是客户端,haproxy 将是负载均衡器,host app 将是 Web 服务器,redis 将是共享服务器。
在 ProjectName\aspnet-core\docker\ng 位置创建一个名为 haproxy.cfg 的配置文件。
haproxy.cfg
(复制粘贴代码行会导致编码问题,请直接下载文件 => 下载 haproxy.cfg)
global
maxconn 4096
defaults
mode http
timeout connect 5s
timeout client 50s
timeout server 50s
listen http-in
bind *:8080
server web-1 outputs_abp_host_1:80
server web-2 outputs_abp_host_2:80
stats enable
stats uri /haproxy
stats refresh 1s
haproxy.cfg 的重要行是 server web-1
和 server web-2
。我复制了宿主应用程序。这将创建两个宿主应用程序在 docker 容器中。
修改了 docker-compose.yml。
(复制粘贴代码行会导致编码问题,请直接下载文件 => 下载 docker-compose.yml)
version: '2'
services:
abp_redis:
image: redis
ports:
- "6379:6379"
abp_host:
image: abp/host
environment:
- ASPNETCORE_ENVIRONMENT=Staging
volumes:
- "./Host-Logs:/app/App_Data/Logs"
abp_ng:
image: abp/ng
ports:
- "9902:80"
load_balancer:
image: haproxy:1.7.1
volumes:
- "./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg"
ports:
- "9904:8080"
build-with-ng.ps1
替换以下行
(Get-Content $ngConfigPath) -replace "21021", "9901" | Set-Content $ngConfigPath
用这一行
(Get-Content $ngConfigPath) -replace "21021", "9904" | Set-Content $ngConfigPath
现在 Angular UI 将连接到 haproxy。Haproxy 将请求分发到 Web 服务器。
用以下内容覆盖 up.ps1
docker rm $(docker ps -aq)
docker-compose up -d abp_redis
sleep 3
docker-compose up -d abp_host
docker-compose up -d abp_ng
sleep 2
docker-compose scale abp_host=2
sleep 2
docker-compose up -d load_balancer
要使用 redis 缓存,请将 Abp.RedisCache 库安装到 ProjectName.Web.Core
项目。并按以下方式更新 ProjectNameWebCoreModule.cs
[DependsOn(...,
typeof(AbpRedisCacheModule))]
public class ProjectNameWebCoreModule : AbpModule
{
并在 PreInitialize
方法(ProjectNameWebCoreModule.cs)中添加 redis 缓存配置。
public override void PreInitialize()
{
...
Configuration.Caching.UseRedis(options =>
{
var connectionString = _appConfiguration["Abp:RedisCache:ConnectionString"];
if (connectionString != null && connectionString != "localhost")
{
options.ConnectionString = AsyncHelper.RunSync(() =>
Dns.GetHostAddressesAsync(connectionString))[0].ToString();
}
})
...
在 appsettings.staging.json 中添加 redis 配置。
appsettings.staging.json
{
...,
"Abp": {
"RedisCache": {
"ConnectionString": "outputs_abp_redis_1"
}
}
}
outputs_abp_redis_1
是 redis 容器的名称,此名称由 docker 自动定义。更改后,宿主项目将解析部署在其上的机器的 DNS。现在,当我运行 build-with-ng.ps1 和 up.ps1 时,Web Farm 项目将运行。结果是
如您所见,所有容器都在工作。当您访问 https://:9902 时,您可以看到 Angular UI 正在工作。
我将如何知道 Haproxy 和 Redis 是否正常工作?
有工具可以跟踪 haproxy 活动(haproxy Web 界面)并获取 redis 存储的数据(redis cli)。
Haproxy Web 界面
当您访问 https://:9904/haproxy 时,您将看到类似以下内容
当您在 Angular 应用程序的页面之间导航或运行宿主项目 (https://:9904/) 的任何 api 时,您可以看到 haproxy 正在将请求路由到不同的机器。您可以在 Session rate>Cur 选项卡下跟踪哪些机器正在运行,这些选项卡对于 web-1
和 web-2
正在变化。
Redis cli
要了解 redis 是否正常工作,您可以使用 redis-cli
。运行 docker exec -it outputs_abp_redis_1 redis-cli
命令以交互模式运行 redis-cli
来连接运行在 docker 容器中的 redis 服务器。然后,要测试 redis 是否正在运行,请键入 ping
命令,如果正常工作,它将返回 PONG
。现在,当我键入 keys *
命令时,我应该得到应用程序缓存的键。
如您所见,redis 工作正常。缓存键已正确存储在 redis 中。
源代码
您可以在 Github 上的此链接处获取修改后的源代码。
历史
- 2018 年 2 月 22 日:初始版本