Docker教程 · 2024年11月11日

使用容器进行 .NET 开发

使用容器进行 .NET 开发

完成 。

在本部分中,您将了解如何为容器化应用程序设置开发环境。这包括:

  • 添加本地数据库并持久化数据
  • 配置 Compose 以在您编辑和保存代码时自动更新正在运行的 Compose 服务
  • 创建包含 .NET Core SDK 工具和依赖项的开发容器

docker-dotnet-sample本部分使用包含更新的 .NET 应用程序的存储库的不同分支。更新后的应用程序位于 您在add-db中克隆的存储库的分支 上。

要获取更新的代码,您需要签出分支add-db。对于您在中所做的更改 ,在本节中,您可以将它们隐藏。在终端中,在docker-dotnet-sample目录中运行以下命令。

  1. 隐藏以前的任何更改。

    $ git stash -u 
  2. 查看带有更新的应用程序的新分支。

    $ git checkout add-db 

add-db分支中,仅更新了 .NET 应用程序。 Docker 资产尚未更新。

您的目录中现在应该有以下内容docker-dotnet-sample


├── docker-dotnet-sample/ │ ├── .git/ │ ├── src/ │ │ ├── Data/ │ │ ├── Models/ │ │ ├── Pages/ │ │ ├── Properties/ │ │ ├── wwwroot/ │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ ├── myWebApp.csproj │ │ └── Program.cs │ ├── tests/ │ │ ├── tests.csproj │ │ ├── UnitTest1.cs │ │ └── Usings.cs │ ├── .dockerignore │ ├── .gitignore │ ├── compose.yaml │ ├── Dockerfile │ ├── README.Docker.md │ └── README.md

您可以使用容器来设置本地服务,例如数据库。在本部分中,您将更新compose.yaml文件以定义数据库服务和用于保存数据的卷。

compose.yaml在 IDE 或文本编辑器中打开文件。您会注意到它已经包含 PostgreSQL 数据库和卷的注释掉指令。

docker-dotnet-sample/src/appsettings.json在 IDE 或文本编辑器中打开。您会注意到包含所有数据库信息的连接字符串。已 compose.yaml包含此信息,但已被注释掉。取消文件中数据库指令的注释compose.yaml

以下是更新后的compose.yaml文件。


services:  server:  build:  context: .  target: final  ports:  - 8080:80  depends_on:  db:  condition: service_healthy  db:  image: postgres  restart: always  user: postgres  secrets:  - db-password  volumes:  - db-data:/var/lib/postgresql/data  environment:  - POSTGRES_DB=example  - POSTGRES_PASSWORD_FILE=/run/secrets/db-password  expose:  - 5432  healthcheck:  test: [ "CMD", "pg_isready" ]  interval: 10s  timeout: 5s  retries: 5 volumes:  db-data: secrets:  db-password:  file: db/password.txt

笔记

要了解有关 Compose 文件中的说明的更多信息,请参阅 。

在使用 Compose 运行应用程序之前,请注意此 Compose 文件使用 secrets并指定一个password.txt文件来保存数据库的密码。您必须创建此文件,因为它不包含在源存储库中。

在该docker-dotnet-sample目录中,创建一个名为 的新目录db,并在该目录内创建一个名为password.txt.在 IDE 或文本编辑器中打开password.txt并添加以下密码。密码必须位于单行中,文件中不得有任何其他行。


example

保存并关闭password.txt文件。

您的目录中现在应该有以下内容docker-dotnet-sample


├── docker-dotnet-sample/ │ ├── .git/ │ ├── db/ │ │ └── password.txt │ ├── src/ │ ├── tests/ │ ├── .dockerignore │ ├── .gitignore │ ├── compose.yaml │ ├── Dockerfile │ ├── README.Docker.md │ └── README.md

运行以下命令来启动您的应用程序。


$ docker compose up --build 

查看应用程序 。您应该看到一个带有文本的简单 Web 应用程序Student name is

应用程序不显示名称,因为数据库为空。对于此应用程序,您需要访问数据库,然后添加记录。

对于示例应用程序,您必须直接访问数据库才能创建示例记录。

您可以使用命令在数据库容器内运行命令docker exec 。在运行该命令之前,您必须获取数据库容器的 ID。打开一个新的终端窗口并运行以下命令以列出所有正在运行的容器。


$ docker container ls 

您应该看到如下所示的输出。


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb36e310aa7e docker-dotnet-server "dotnet myWebApp.dll" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp docker-dotnet-server-1 39fdcf0aff7b postgres "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 5432/tcp docker-dotnet-db-1 

在前面的示例中,容器 ID 是39fdcf0aff7b。运行以下命令在 postgres 容器中启动 bash shell。将容器 ID 替换为您自己的容器 ID。


$ docker exec -it 39fdcf0aff7b bash 

然后运行以下命令连接数据库。


postgres@39fdcf0aff7b:/$ psql -d example -U postgres 

最后,将一条记录插入数据库。


example=# INSERT INTO "Students" ("ID", "LastName", "FirstMidName", "EnrollmentDate") VALUES (DEFAULT, 'Whale', 'Moby', '2013-03-20'); 

您应该看到如下所示的输出。


INSERT 0 1 

exit通过运行两次关闭数据库连接并退出容器 shell 。


example=# exit postgres@39fdcf0aff7b:/$ exit 

查看应用程序 。您应该看到一个带有文本的简单 Web 应用程序Student name is Whale Moby

ctrl+c终端停止您的应用程序。

在终端中,运行docker compose rm以删除容器,然后运行docker compose up以再次运行应用程序。


$ docker compose rm $ docker compose up --build 

在浏览器中刷新 并验证学生姓名是否仍然存在,即使在容器被删除并再次运行之后也是如此。

ctrl+c终端停止您的应用程序。

使用 Compose Watch 在您编辑和保存代码时自动更新正在运行的 Compose 服务。有关 Compose Watch 的更多详细信息,请参阅 。

compose.yaml在 IDE 或文本编辑器中打开文件,然后添加 Compose Watch 指令。以下是更新后的compose.yaml文件。


services:  server:  build:  context: .  target: final  ports:  - 8080:80  depends_on:  db:  condition: service_healthy  develop:  watch:  - action: rebuild  path: .  db:  image: postgres  restart: always  user: postgres  secrets:  - db-password  volumes:  - db-data:/var/lib/postgresql/data  environment:  - POSTGRES_DB=example  - POSTGRES_PASSWORD_FILE=/run/secrets/db-password  expose:  - 5432  healthcheck:  test: [ "CMD", "pg_isready" ]  interval: 10s  timeout: 5s  retries: 5 volumes:  db-data: secrets:  db-password:  file: db/password.txt

运行以下命令以使用 Compose Watch 运行您的应用程序。


$ docker compose watch 

打开浏览器并验证应用程序是否正在 运行。

对本地计算机上应用程序源文件的任何更改现在都将立即反映在正在运行的容器中。

docker-dotnet-sample/src/Pages/Index.cshtml在 IDE 或文本编辑器中打开,并将第 13 行的学生姓名文本从 更新Student name isStudent name:


- <p>Student Name is @Model.StudentName</p> + <p>Student name: @Model.StudentName</p> 

保存更改Index.cshmtl,然后等待几秒钟以重建应用程序。在浏览器中刷新 并验证是否显示更新的文本。

ctrl+c终端停止您的应用程序。

此时,当您运行容器化应用程序时,它正在使用 .NET 运行时映像。虽然这个小映像非常适合生产,但它缺少开发时可能需要的 SDK 工具和依赖项。此外,在开发过程中,您可能不需要运行dotnet publish.您可以使用多阶段构建在同一个 Dockerfile 中构建开发和生产阶段。有关更多详细信息,请参阅 。

将新的开发阶段添加到您的 Dockerfile 并更新您的compose.yaml文件以使用此阶段进行本地开发。

以下是更新后的 Dockerfile。


# syntax=docker/dockerfile:1  FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build ARG TARGETARCH COPY . /source WORKDIR /source/src RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \  dotnet publish -a ${TARGETARCH/amd64/x64} --use-current-runtime --self-contained false -o /app  FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS development COPY . /source WORKDIR /source/src CMD dotnet run --no-launch-profile  FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS final WORKDIR /app COPY --from=build /app . ARG UID=10001 RUN adduser \  --disabled-password \  --gecos "" \  --home "/nonexistent" \  --shell "/sbin/nologin" \  --no-create-home \  --uid "${UID}" \  appuser USER appuser ENTRYPOINT ["dotnet", "myWebApp.dll"]

以下是更新后的compose.yaml文件。


services:  server:  build:  context: .  target: development  ports:  - 8080:80  depends_on:  db:  condition: service_healthy  develop:  watch:  - action: rebuild  path: .  environment:  - ASPNETCORE_ENVIRONMENT=Development  - ASPNETCORE_URLS=http://+:80'  db:  image: postgres  restart: always  user: postgres  secrets:  - db-password  volumes:  - db-data:/var/lib/postgresql/data  environment:  - POSTGRES_DB=example  - POSTGRES_PASSWORD_FILE=/run/secrets/db-password  expose:  - 5432  healthcheck:  test: [ "CMD", "pg_isready" ]  interval: 10s  timeout: 5s  retries: 5 volumes:  db-data: secrets:  db-password:  file: db/password.txt

您的容器化应用程序现在将使用该mcr.microsoft.com/dotnet/sdk:6.0-alpine映像,其中包括dotnet test.继续阅读下一部分,了解如何运行dotnet test

在本部分中,您了解了如何设置 Compose 文件以添加本地数据库并保留数据。您还了解了如何在更新代码时使用 Compose Watch 自动重建和运行容器。最后,您学习了如何创建包含开发所需的 SDK 工具和依赖项的开发容器。

相关信息:

在下一节中,您将学习如何使用 Docker 运行单元测试。