如何将ASP.NET Core app 部署到容器中

假设自己已经开发了一个ASP.NET Core 应用,如何将其放到Windows或者Linux 的container中跑起来呢?

(Dockerize an ASP.NET Core application/ Running a .NET Core Web Application in Docker container using Docker Desktop for Windows)

 

前提

  • 假设你已经安装了.net6 的SDK, 最新版的Docker Desktop for Windows
  • 假设你已经创建好一个名字叫“MyWebApp” 的ASP.NET Core 应用 参照simple tutorial

 

 把大象放冰箱分三步

我们开发机之所以能够Run起来,是因为本机有:

1. ASP.NET  Core Web app 程序代码

2. 可以将代码编译成可执行程序( .net6 的SDK/ Visual Studio IDE)

3. ASP.NET Core runtime(可以通过命令行运行dotnet --version 确认你所安装的版本)以及Web服务器 IIS(或IIS Express)

 

我们需要将app 部署到一个docker container 里运行,那么:

→我们需要一个包含ASP.NET Core runtime 的image

→这个image中还需要包含我们的app

→ 我们需要编译app

→ 我们一个Dockerfile 来指导如何完成上面的步骤

 

step1.创建Dockerfile

基于上面的分析,我们创建如下Dockerfile(和C#工程文件同一目录):

复制代码
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
    
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
    
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
    
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MyWebApp.dll"]
View Code
复制代码

 

以及一个.dockerignore 用于配置在build 镜像时,哪些内容可以不用copy进去,以保证产生的image size 最小。

bin/
obj/
View Code

 

step2.构建镜像

接下来运行docker build 构建镜像:

docker build -t aspnetapp .

其中,-t aspnetapp 指定生成的镜像名为”aspnetapp"

注意 命令末尾还有一个参数“ .", 表示dockerfile所在当前目录,如果Dockerfile在C:\Lei\projects\MyWebApp,

那么上面的命令等效于:

docker build -t aspnetapp ”C:\Lei\projects\MyWebApp“

 

结合docker build命令产生的log,我们再回回顾每一行Dockerfile指令的意思:

  1. Step 1/10: FROM microsoft/dotnet:sdk AS build-env FROM microsoft/dotnet:sdk AS build-env Pulls the image with tag “sdk” from Microsoft/dotnet registry on docker hub – https://hub.docker.com/r/microsoft/dotnet/tags , “build-env” name can be given to the new build stage. This will be used to copy file in the later steps.
  2. Step 2/10: WORKDIR /app The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
  3. Step 3/10: COPY *.csproj ./ Copies ( from local dev machine) all CS Project files to the working directory inside the container.
  4. Step 4/10: RUN dotnet restore This is the .NET command line which restores all the required Nuget packages to build the project.
  5. Step 5/10: COPY . ./ This copies all the content of Visual Studio project into the working directory.
  6. Step 6/10: RUN dotnet publish -c Release -o out  uses .NET CLI to create a release build with output directory as “out”
  7. Step 7/10: FROM mcr.microsoft.com/dotnet/aspnet:6.0  Pulls the image with tag “aspnetcore-runtime” from Microsoft/dotnet registry on docker hub – https://hub.docker.com/r/microsoft/dotnet/tags which provides the minimum components to run an ASP.NET Core Web Application.
  8. Step 8/10: WORKDIR /app Same as Step 2 above.
  9. Step 9/10: COPY –from=build-env /app/out . This copies the content of /app/out folder from the “build-env” to this net container,注意末尾有个参数”.",表示copy到step8指定的/app当前目录.
  10. Step 10/10: ENTRYPOINT [“dotnet”, “aspnetapp.dll”] This allows the container to run as an executable.

 

step3.运行镜像

docker run -d -p 8080:80 -name mywebapp aspnetapp

 上面的命令基于上一步创建的aspnetapp的镜像,创建并运行名叫”mywebapp“的Container,这样,通过http://localhost:8080就可以访问应用了。

参数解释:

  • -p 8080:80 指定将Container的80端口,映射到本机(宿主机)的8080端口。
  • -d  容器启动后,在后台运行
  • -name mywebapp 新运行的容器名为mywebapp

 

IDE support -- “Enable Docker Support” 

上面我们是手动创建Dockerfile 和.dockerignore 文件,

Dockerfile 包含如何build container 镜像的指令。

.dockerignore 则用于配置,在build 镜像时,哪些内容可以不用放进去,进而保证image size 最小。

如果在通过Visual Studio创建一个web application的时,勾选 “Enable Docker Support” ,那么Visual Studio就直接在Project 目录自动创建这两个文件。

 

在容器之外编译/Build app outside Docker container

上面Dockerfile 先用一个单独的image(FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env) 编译app,然后再打包到包含ASP.NET Core runtime的image中。

这会带来一些disadvantages:

  • docker build的时间会相对较长,产生的image size也较大。
  • 不能充分利用CI build pipeline编译生成的artifacts直接部署。

所以,可以做如下优化:

1.先在开发环境用dotnet publish cli生成published version的artifacts到bin/Release/net6.0/publish/,

2.再修改Dockerfile直接copy到包含ASP.NET Core runtime 的docker镜像:

 

  

参考

 

posted @   鱼羊雨田  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示