image.png

目录说明

镜像构建目录

本地已经安装Docker,笔者使用的wsl 安装 Ubuntu22.04,对应Docker 版本为28.4.0,具体细节可以查看笔者的文章Docker在Linux中离线部署,同时保证本地已经包含镜像mcr.microsoft.com/dotnet/aspnet:9.0-alpine3.22,案例项目为.Net9.0 框架版本,官方镜像选择的aspnet:9.0-alpine3.22
镜像构建时,目录如下,主要用于规范构建逻辑。

docker-build/
|--app/ # 后端部署包,其中wwwroot、logs为空文件夹不包含文件
|--.dockerignore# docker忽略文件
|--Dockerfile # 镜像构建配置文件

需要注意的是,项目部署包的发布配置如下:
Pasted image 20251207115241.png

容器运行目录

本地也需要安装docker-compose,并不是docker自带,安装过程同样可以查看笔者的文章Docker在Linux中离线部署Docker-Compose 主要用于简化按照镜像构建目标容器,并实现一键配置网络、数据卷、服务端口等。

docker-compose/
|--config/ # 配置目录
|----appsettings.Development.json # development环境配置
|----appsettings.json # 默认配置
|--logs/ # 用于未来日志输出备用[可选]
|--resources/ # 挂载到wwwroot
|--.env # 环境变量
|--docker-compose.yml # compose配置

容器内外关系

为了方便对镜像、docker-compose配置以及容器不是很熟悉的读者能够更好的理解几者之间的关系,笔者梳理梳理出一个简单的关系图用于说明目录、文件以及网络的关系,运行时,默认情况下,net9.0 中默认运行监听服务端口为8080,这与一些低版本net 容器中为80端口不太一样需要特别注意,如无必要,建议不做修改,默认运行为Production 环境,可通过运行时环境变量进行修改。

部署说明

案例项目说明

案例项目为一个基础的WebApi 模板项目,包含一个天气Apiindex.htmlDevelopment 环境可访问的Swagger 页面,对应依赖如下。

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="9.0.6" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.0.0" />
  </ItemGroup>
</Project>

主类Program代码

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        //注册服务
        builder.Services.AddSwaggerGen();
        builder.Services.AddControllers();
        var app = builder.Build();
        //启动静态文件中间
        app.UseStaticFiles();
        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            #region Swagger中间件相关
            //添加swagger配置,并启动中间件
            app.UseSwagger();
            //启用Swagger-ui中间件,并配置swagger json的请求终节点
            app.UseSwaggerUI();
            #endregion
        }
        app.MapControllers();
        app.Run();
    }
}

运行项目时,浏览器访问http://ip:port/index.html输出如下:

访问http://ip:port/swagger/index.html 输出如下:

部署目录说明

发布包目录如下,执行程序为WebApplication1,也可以直接执行dotnet ./WebApplication1.dll

基础镜像说明

微软官方提供了对应的运行时镜像,可以按照自己的需求去到镜像仓库进行版本查看。当前使用的aspnetcore,查看基础镜像构建Dockerfile 内容可以发现,实际直接使用的 aspnetcore 运行时。

ARG REPO=mcr.microsoft.com/dotnet/runtime
# Installer image
FROM $REPO:9.0.11-alpine3.22-amd64 AS installer
# Retrieve ASP.NET Core
RUN aspnetcore_version=9.0.11 \
    && wget \ https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$aspnetcore_version/aspnetcore-runtime-$aspnetcore_version-linux-musl-x64.tar.gz \
  https://builds.dotnet.microsoft.com/dotnet/checksums/$aspnetcore_version-sha.txt \
    && awk -v file="aspnetcore-runtime-$aspnetcore_version-linux-musl-x64.tar.gz" '{gsub(/\r/, "")} $2 == file' $aspnetcore_version-sha.txt | sha512sum -c \
    && mkdir --parents /dotnet \
    && tar --gzip --extract --no-same-owner --file aspnetcore-runtime-$aspnetcore_version-linux-musl-x64.tar.gz --directory /dotnet ./shared/Microsoft.AspNetCore.App \
    && rm \
        aspnetcore-runtime-$aspnetcore_version-linux-musl-x64.tar.gz \
        $aspnetcore_version-sha.txt
# ASP.NET Core image
FROM $REPO:9.0.11-alpine3.22-amd64
# ASP.NET Core version
ENV ASPNET_VERSION=9.0.11
COPY --from=installer ["/dotnet", "/usr/share/dotnet"]

构建镜像

Docker及配置

.dockerignore 作为构建镜像时,本地docker 客户端进行传输忽略的文件配置清单,内容如下:

.git
Dockerfile
README.md
*.md

构建镜像需要 Dockerfile 文件进行镜像构建配置,对应构建Dockerfile文件内容如下。

# 使用官方的 ASP.NET Core 基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine3.22 AS final
WORKDIR /app
# 将本地发布文件复制到镜像中
COPY ./app ./

ENTRYPOINT ["dotnet","./WebApplication1.dll"]

有了上述前置准备工作和相关文件,就可以进行镜像构建过程。切换会话到docker-build目录,进行构建命令。

sudo docker build . -t [自定义镜像名称]:[版本号]

当前笔者构建命令如下:

sudo docker build . -t webapi:0.0.1

输出结果如下,表示构建成功,可以在镜像中看到对应镜像。

Sending build context to Docker daemon  1.465MB
Step 1/4 : FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine3.22 AS final
 ---> 5786a890a61b
Step 2/4 : WORKDIR /app
 ---> Running in 7f88eca13bfa
 ---> Removed intermediate container 7f88eca13bfa
 ---> 44155dfbe259
Step 3/4 : COPY ./app ./
 ---> 32fac1b9a69e
Step 4/4 : ENTRYPOINT ["dotnet","./WebApplication1.dll"]
 ---> Running in 764a683c2895
 ---> Removed intermediate container 764a683c2895
 ---> a77b6be59a17
Successfully built a77b6be59a17
Successfully tagged webapi:0.0.1

查看镜像。

$ sudo docker images |grep webapi
webapi                                          0.0.1             a77b6be59a17   50 seconds ago   116MB

构建容器

Docker-Compose及配置

.env 可以存储作为docker-compose.yml 使用的自定义环境变量,docker-compose.yml 使用时为${APP_ROOT},当前表示容器数据卷所在宿主物理路径。

APP_ROOT=/home/ggcy/docker_data/webapi/docker-compose

对应docker-compose.yml 内容如下:

version: '3.8'
services:
  server:
    image: webapi:0.0.1
    container_name: webapi-service
    #restart: unless-stopped
    # networks:
    #   - internal_network
    ports:
      - "8001:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    volumes:
      - ${APP_ROOT}/resources:/app/wwwroot
      - ${APP_ROOT}/logs:/app/logs
      - ${APP_ROOT}/config/appsettings.json:/app/appsettings.json
      - ${APP_ROOT}/config/appsettings.Development.json:/app/appsettings.Development.json
# networks:
#   internal_network:
#     external: true

其中resources 中包含index.html;切换会话到docker-compose 目录执行如下命令,为方便查看并未设置-d 用于后台运行。

$sudo docker-compose up 
[+] Running 1/1
 ✔ Container webapi-service  Recreated 0.1s
Attaching to webapi-service
webapi-service  | info: Microsoft.Hosting.Lifetime[14]
webapi-service  |       Now listening on: http://[::]:8080
webapi-service  | info: Microsoft.Hosting.Lifetime[0]
webapi-service  |       Application started. Press Ctrl+C to shut down.
webapi-service  | info: Microsoft.Hosting.Lifetime[0]
webapi-service  |       Hosting environment: Development
webapi-service  | info: Microsoft.Hosting.Lifetime[0]
webapi-service  |       Content root path: /app

单独开启一个会话,查看对应容器运行情况,可以查看到容器运行正常。

$sudo docker ps|grep webapi-service
74ae4f5771c8   webapi:0.0.1   "dotnet ./WebApplica…"   About a minute ago   Up About a minute   0.0.0.0:8001->8080/tcp, [::]:8001->8080/tcp   webapi-service

此时可以在服务运行会话中,ctrl+C 退出,然后再执行docker-compose up -d用于后台运行。

$sudo docker-compose  up -d
[+] Running 1/1
 ✔ Container webapi-service  Started

运行效果

浏览器访问http://localhost:8001/index.html,内容如下:
Pasted image 20251207144853.png

访问http://localhost:8001/swagger/index.html,输出结果如下:
Pasted image 20251207144947.png

更多推荐