将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器

目录

项目设置

设置SQL Server容器

设置API容器

设置UI容器


在本项目中,我将向您展示如何将现有的ASP.NET Core UIAPISQL Server部署到Docker容器,以及有关故障排除非常耗时的常见陷阱的信息。您可以在此处查看源文章和此项目的最新更新。

在这篇文章中,我们将介绍:

  • 使用Docker数据卷设置SQL Server容器以实现数据持久性,并使用SQL Server Management Studio连接到SQL Server容器
  • 设置Docker网络,以便SQL Server、API和UI容器可以相互通信
  • 为Linux .NET环境设置自签名证书,以便UI容器信任API容器而不会出错
  • 设置API和UI容器,以便可以从浏览器测试应用程序

您可以在GitHub存储库中下载此项目的代码

项目设置

此项目的起点是使用分页和排序项目创建的,该项目具有连接到SQL Server数据库的ASP.NET前端和API。您可以下载它并确保它首先在您的计算机上运行。

要在Windows机器上运行Docker,首先需要安装WSLLinuxWindows子系统),它依赖于Hyper-V。转到Windows中的打开或关闭Windows功能功能并启用Hyper-V平台,如下所示:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第1张图片

完成后,您可以安装 WSL(Windows Subsystem for Linux)Linux内核更新包。可以在Powershell中设置WSL的默认版本:

wsl --set-default-version 2

下载Docker桌面。在继续之前,Docker桌面应已启动并运行,如下所示:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第2张图片

设置SQL Server容器

我们首先需要设置一个Docker网络,这是必要的,以便SQL ServerAPIUI容器可以放置在同一个网络中,以便它们可以找到彼此。

创建在命令提示符下命名为network-name的网络:

docker network create network-name

然后在命令提示符下运行以下docker pull命令以获取 SQL Server 镜像:

docker pull mcr.microsoft.com/mssql/server:2022-latest

然后,您可以使用以下docker run命令创建SQL Server容器,方法是提供:

  • sql-server-password——SA(系统管理员)密码长度必须至少为10个字符,并且包含以下四组中的三组字符:大写字母、小写字母、进制数字和符号。如果密码不合格,它将不起作用。
  • sql-server-volume-name——用于数据持久性的Docker数据卷的名称
  • sql-server-container-name——容器的名称
  • network-name——运行SQL Server容器的Docker网络的名称。
  • sql-server-name——SQL Server的名称,以便API容器可以找到它
  • 将容器中的 /https 位置映射到计算机位置%USERPROFILE%\.aspnet\https,映射到我的驱动器位置C:\Users\Kendall\.aspnet\https。原因是我们将使用SQL Server容器在Linux中创建要在API容器中使用的自签名证书。稍后会详细介绍这一点。

docker run -e "ACCEPT_EULA=Y" ^ 
   -e "MSSQL_SA_PASSWORD=sql-server-password" ^
   -p 1433:1433 ^
   -v sql-server-volume-name:/var/opt/mssql ^
   -v %USERPROFILE%\.aspnet\https:/https/ ^
   --name sql-server-container-name ^
   --network network-name ^
   --network-alias sql-server-name ^
   -d mcr.microsoft.com/mssql/server:2022-latest

运行该命令后,您应该会在Docker桌面中看到Docker数据卷:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第3张图片

现在,您可以通过提供SA(系统管理员)密码,在端口127上使用服务器名称为0.0.1.1433SQL Server Management Studio连接到SQL Server、容器:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第4张图片

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第5张图片

建立连接后,在应用设置中更改连接字符串 API项目中指向容器数据库的Development.json文件:

"StarterConn": "Data Source=127.0.0.1;Initial Catalog=Starter;
                User Id=sa;Password=sql-server-password"

在命令提示符下,导航到项目的 Data 文件夹并运行以下dotnet ef命令,该命令将在容器中设置数据库的结构:

dotnet ef database update -s ..\Api\Api.csproj

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第6张图片

您可以运行位于“Data文件夹中的文件 insertCustomer.sql 来填充一些示例数据:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第7张图片

设置API容器

API容器的设置需要:

  • 创建与API容器具有相同域名的自签名证书。如果使用dotnet dev-certs命令生成证书,则在UI调用证书时将生成RemoteCertificateNameMismatch错误,因为域名不同。相反,您需要在Linux中使用openssl命令来生成我将向您展示的证书。
  • 创建包含API代码的Docker镜像。您可以将API项目发布到目录,然后通过将已发布的API项目复制到镜像中来构建Docker镜像。

若要为API创建自签名证书,请转到Docker Desktop中的SQL Server容器并导航到/https位置,该位置映射到计算机的C:\Users\[UserName]\.aspnet\https位置,然后运行以下openssl命令以生成证书:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第8张图片

openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout api-server.key \
  -addext "subjectAltName = DNS:api-server-name" \
  -x509 -days 365 -out api-server.crt

它会询问您一系列问题,您可以对所有问题采取默认值,但在询问公用名(CN)时必须指定API的服务器名称。在这种情况下,我只用api-server-name作为我的API服务器的名称。现在,您应该拥有 .crt 证书文件和.key私钥文件。然后,可以发出下面的另一个openssl命令来生成运行ASP.NET容器所需的.NET兼容.pfx 证书文件:

openssl pkcs12 -export -out api-server.pfx -inkey api-server.key -in api-server.crt

它会询问您将用于 .pfx 证书的密码,只需创建一个密码并记住它。

现在,您应该在C:\Users\[UserName]\.aspnet\https中显示以下文件,如下所示:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第9张图片

请注意:

  • 需要将.crt.key文件作为受信任证书安装到UI容器中
  • 需要.pfx及其密码才能运行API容器

现在,让我们为API创建一个镜像。首先复制应用设置。Development.json 配置文件并将其命名为 appsettings.Container.json,它将是容器的配置文件:

应用程序appsettings.Container.json 文件中,使用SQL Server的名称和SA(系统管理员)密码更新SQL Server连接字符串:

"StarterConn": "Data Source=sql-server-name;
                Initial Catalog=Starter;User Id=sa;Password=sql-server-password"

API项目发布到 bin 目录,然后选择如下所示的linux-x64目标运行时:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第10张图片

下一步是生成将包含APIDocker镜像。这是通过创建包含构建新镜像的说明的 Dockerfile 来完成的。

API项目中,创建一个名为 Dockerfile 的文本文件(该文件必须这样命名,docker命令才能找到它),并将下面的构建说明粘贴到其中:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 
COPY bin/Release/net6.0/publish App/
WORKDIR /App
ENTRYPOINT ["dotnet", "Api.dll"]

Dockerfile 指定将按照以下步骤创建新镜像:

  • 它使用Docker存储库中的aspnet镜像作为基础镜像。
  • 它将API项目的已发布输出从计算机复制到容器中的/App文件夹。
  • 它使用/App文件夹作为启动应用程序的位置。
  • 它使用 Api.dll 运行dotnet命令以启动应用程序。

现在,在 API 文件夹内的命令提示符下运行docker build命令,以生成将包含API的新镜像:

docker build -t api .

现在,您应该在Docker Desktop中看到API的新镜像:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第11张图片

镜像就位后,现在可以使用具有以下参数的docker run命令运行API容器:

docker run -d -p 7000:80 -p 7001:443 ^ 
   -e ASPNETCORE_URLS="https://+;http://+" ^ 
   -e ASPNETCORE_HTTPS_PORT=7001 ^ 
   -e ASPNETCORE_Kestrel__Certificates__Default__Password="" ^  
   -e ASPNETCORE_ENVIRONMENT=Container ^ 
   -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/api-server.pfx ^ 
   -v %USERPROFILE%\.aspnet\https:/https/ ^
   --network network-name ^ 
   --network-alias api-server-name ^ 
   --name api-container-name ^ 
   api

参数指定:

  • 计算机上的端口7000和7001分别映射到容器的端口80和443
  • 计算机上的API端口为7001
  • ASPNETCORE_Kestrel__Certificates__Default__Password参数指定API证书的密码,请确保在双引号内添加密码
  • ASPNETCORE_ENVIRONMENT参数指定它将使用您之前创建的appsettings.Container.json配置文件
  • ASPNETCORE_Kestrel__Certificates__Default__Path参数指定API证书的位置
  • -v参数将容器中的/https/位置映射到计算机上具有API证书的%USERPROFILE%\.aspnet\https位置
  • –network参数指定网络的名称,以便SQL服务器和UI容器可以找到API
  • –network-alias参数指定API服务器的名称,这是UI容器可以找到API所必需的
  • –name参数指定API容器的名称

现在,您应该看到在端口7001上运行的API容器:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第12张图片

您可以通过转到如下所示的 https://localhost:7001/api/customer 并注意到证书对您的浏览器不安全来查看API正在运行,这没关系,因为您的浏览器用localhost作为服务器的名称而不是证书中指定的API服务器的名称:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第13张图片

设置UI容器

对于UI容器,我们可以使用该dotnet dev-certs命令为localhost域生成证书,以便在您的浏览器上信任它。首先,通过运行以下命令清理计算机上可能已存在的现有证书:

dotnet dev-certs https --clean

然后运行以下命令,通过为其提供密码来生成新证书。密码必须是字母数字,否则将不起作用。

dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\ui.pfx -p password-here

通过转到用户配置文件位置下的目录来检查证书是否已生成:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第14张图片

然后运行以下命令以信任证书:

dotnet dev-certs https --trust

现在,让我们为UI创建一个镜像。首先,复制应用程序appsettings.Development.json 配置文件并将其命名为appsettings.Container.json,它将是容器的配置文件:

应用程序设appsettings.Container.json文件,更新APIurl位置:

"APIurl": "https://api-server-name/api/"

UI项目发布到 bin 目录,然后选择如下所示的linux-x64目标运行时:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第15张图片

我们需要UI容器信任API证书,否则会出现错误由于证书链中的错误,远程证书无效:不受信任的根。我们可以将API证书添加到UI容器中并信任它。转到发布UI项目的 bin 目录,创建一个名为 cert 的文件夹,并将API证书(位于计算机上的%USERPROFILE%\.aspnet\https 中)复制到其中:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第16张图片

现在我们可以在UI项目中创建 Dockerfile,并告诉它信任API证书。下面是 Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY bin/Release/net6.0/publish App/
ADD bin/cert/ /etc/ssl/certs
RUN update-ca-certificates
WORKDIR /App
ENTRYPOINT ["dotnet", "WebApp.dll"]

Dockerfile 指定:

  • 将包含API证书的 bin/cert 内容添加到容器中的/etc/ssl/certs 位置
  • 运行update-ca-certificates命令,该命令将信任/etc/ssl/certs 中添加的新证书

现在,在WebApp文件夹内的命令提示符下运行docker build命令,以生成将包含UI的新镜像:

docker build -t ui .

现在,您应该在Docker Desktop中看到UI的新镜像:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第17张图片

现在,您可以使用具有以下参数的docker run命令运行UI容器:

docker run -d -p 8000:80 -p 8001:443 ^ 
   -e ASPNETCORE_URLS="https://+;http://+" ^ 
   -e ASPNETCORE_HTTPS_PORT=8001 ^ 
   -e ASPNETCORE_Kestrel__Certificates__Default__Password="" ^ 
   -e ASPNETCORE_ENVIRONMENT=Container ^ 
   -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/ui.pfx ^ 
   -v %USERPROFILE%\.aspnet\https:/https/ ^ 
   --network network-name ^ 
   --network-alias ui-server-name ^ 
   --name ui-container-name ^ 
   ui

参数指定:

  • 计算机上的端口8000和8001分别映射到容器的端口80和443
  • 计算机上的UI端口为8001
  • ASPNETCORE_Kestrel__Certificates__Default__Password参数指定UI证书的密码,请确保在双引号内添加密码
  • ASPNETCORE_ENVIRONMENT参数指定它将使用您之前创建的appsettings.Container.json配置文件
  • ASPNETCORE_Kestrel__Certificates__Default__Path参数指定UI证书的位置
  • -v参数将容器中的 /https/ 位置映射到计算机上具有UI证书的%USERPROFILE%\.aspnet\https 位置
  • –network参数指定网络的名称,以便UI容器可以找到API容器
  • –network-alias参数指定UI服务器的名称
  • –name参数指定UI容器的名称

现在应看到在端口8001上运行的UI容器:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第18张图片

并查看在端口8001上运行的UI,其中包含受信任的自签名证书:

将带有API和SQL Server数据库的全栈ASP.NET Core部署到Docker容器_第19张图片

一切启动并运行后,您可以创建一个名为 docker-compose.yml  Docker Compose 文件,其中包含所有docker run命令,以便您可以一次性创建所有三个容器(SQL ServerAPIUI)。下面是此项目的Docker Compose文件,与docker run命令相比,语法应该是不言自明的。

version: "3.9"
services:
  sql-server-container-name:
    image: mcr.microsoft.com/mssql/server:2022-latest
    ports:
      - "1433:1433"
    volumes: 
      - sql-server-volume-name:/var/opt/mssql
      - ${USERPROFILE}\.aspnet\https:/https/
    environment:
      MSSQL_SA_PASSWORD: ""
      ACCEPT_EULA: Y
    networks:
      network-name:
        aliases:
          - sql-server-name

  api-container-name:
    image: api
    ports:
      - "7000:80"
      - "7001:443"
    volumes: 
      - ${USERPROFILE}\.aspnet\https:/https/
    environment:
      ASPNETCORE_URLS: "https://+;http://+"
      ASPNETCORE_HTTPS_PORT: 7001
      ASPNETCORE_Kestrel__Certificates__Default__Password: ""
      ASPNETCORE_ENVIRONMENT: Container 
      ASPNETCORE_Kestrel__Certificates__Default__Path: /https/api-server.pfx
    networks:
      network-name:
        aliases:
          - api-server-name

  ui-container-name:
    image: ui
    ports:
      - "8000:80"
      - "8001:443"
    volumes: 
      - ${USERPROFILE}\.aspnet\https:/https/
    environment:
      ASPNETCORE_URLS: "https://+;http://+"
      ASPNETCORE_HTTPS_PORT: 8001
      ASPNETCORE_Kestrel__Certificates__Default__Password: ""
      ASPNETCORE_ENVIRONMENT: Container 
      ASPNETCORE_Kestrel__Certificates__Default__Path: /https/ui.pfx
    networks:
      network-name:
        aliases:
          - ui-server-name

volumes:
  sql-server-volume-name:

networks:
  network-name: {}

要运行docker compose文件,您可以给出以下命令:

docker compose up -d

本文最初发表于 Deploying full stack ASP .net core with API and Sql Server databases to Docker containers – .NET Lead

https://www.codeproject.com/Articles/5348430/Deploying-Full-Stack-ASP-NET-Core-with-API-and-SQL

你可能感兴趣的:(ASP.NET,CORE,Docker,架构及框架,docker,api,sql,server,asp.net,core)