使用Docker自动编译发布Net Core项目
前言
项目是使用的Net Core 2.2的老项目,而编译服务器是Debian12,Debian12已不再支持Net Core 2.2 SDK所以无法直接编译,故使用Docker实现编译项目。
环境介绍
系统版本:Debian GNU/Linux 12 (bookworm)
代码管理:Gitea 23.0.0
代码集成:Jenkins 2.492.1
Jenkins 配置
主要是用来触发编译,感觉随便用一个WebHook就可以
1、安装必要插件
在系统管理->插件管理->Available plugins中搜索Generic Webhook Trigger Plugin并安装
2、新建任务流程
新建一个自由风格的任务流程
3、配置任务流程
在源码管理中配置代码仓库
在Triggers中勾选Generic Webhook Trigger,并设置下方Token,其他不用操作
在Build Steps中添加执行 shell步骤,用来执行命令(也可以直接写,不过我还是喜欢单独写文件中执行)
填写完毕后保存。
Gitea 配置
配置webhook,触发jenkins构建
1、添加Web钩子
在仓库中的设置->Web钩子中,点击右上角Web钩子按钮,选择Gitea添加;
配置目标Url,格式为Jenkins地址 + __generic-webhook-trigger/invoke?token=__ + Token,例如http://192.168.1.100:8080/generic-webhook-trigger/invoke?token=123456
脚本编写
编写Dockerfile与编译脚本
Dockerfile文件
下述流程先使用SDK进行编译发布,然后在RunTime中运行项目;
因为微软官方提供的RunTime并无libgdiplus,所以项目中使用图形的地方都会报错,这里咱们修改下镜像源,手动安装libgdiplus,如果项目还需安装其他的,自行追加安装即可。
# 使用 .NET Core SDK 镜像来构建项目
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
# 设置工作目录
WORKDIR /app
# 复制文件
COPY . ./
# 恢复 Test_Project 项目的依赖项
RUN dotnet restore Test_Project.csproj
# 发布 Test_Project 项目
RUN dotnet publish Test_Project.csproj -c Release -o /app/publish
# 使用 .NET Core 运行时镜像来运行应用程序
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
# 设置工作目录
WORKDIR /app
# 暴漏端口
EXPOSE 11081
# 修复软件源并安装 libgdiplus
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian-elts stretch main contrib non-free" > /etc/apt/sources.list \
&& curl -fsSL https://deb.freexian.com/extended-lts/archive-key.gpg -o /tmp/elts-archive-key.gpg \
&& mv /tmp/elts-archive-key.gpg /etc/apt/trusted.gpg.d/freexian-archive-extended-lts.gpg \
&& apt-get update && apt-get install -y libgdiplus \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 将发布后的 Web API 文件复制到运行时容器中
COPY --from=build /app/publish .
# 配置应用程序 URL
ENV ASPNETCORE_URLS=http://*:11081
# 设置容器的启动命令
ENTRYPOINT ["dotnet", "Test_Project.dll"]编译脚本
下述脚本主要是将配置文件appsettings.json和Dockerfile复制到Jenkins编译的项目中(Jenkens需映射宿主机项目路径),然后构建新镜像并删除旧容器(如果有),最后运行新容器;
启动容器时我做了重启策略--restart=on-failure:3,运行报错退出后自动重启,重启次数最多3次,然后映射资源目录wwwroot和日志目录logs,便于直接在宿主机上查看。
#!/bin/bash
set -e
# 变量
SRC_DIR="/home/project/Test_Project"
DEST_DIR="."
DOCKER_IMAGE="test_project"
DOCKER_CONTAINER="Test_Project"
PORT_MAPPING="11081:11081"
# 检查目录和文件
[ -d "$SRC_DIR" ] || { echo "错误: 目录 $SRC_DIR 不存在!"; exit 1; }
[ -f "$SRC_DIR/Dockerfile" ] || { echo "错误: Dockerfile 不存在!"; exit 1; }
mkdir -p "$DEST_DIR"
[ -f "$SRC_DIR/appsettings.json" ] && cp "$SRC_DIR/appsettings.json" "$DEST_DIR/"
# 确保 Api 目录结构完整
mkdir -p "$SRC_DIR/Api/wwwroot" "$SRC_DIR/Api/logs"
# 构建 Docker 镜像
cp "$SRC_DIR/Dockerfile" .
docker build -t "$DOCKER_IMAGE" .
# 移除旧容器
docker rm -f "$DOCKER_CONTAINER" 2>/dev/null || true
# 运行新容器
docker run -d -p "$PORT_MAPPING" --name "$DOCKER_CONTAINER" \
--restart=on-failure:3 \
-v "$SRC_DIR/Api/wwwroot:/app/wwwroot" \
-v "$SRC_DIR/Api/logs:/app/logs" \
"$DOCKER_IMAGE"处理流程
提交代码 -> Gitea WebHook触发Jenkins构建 -> Jenkins拉取Gitea代码 -> Jenkins执行编译脚本 ->脚本复制配置文件与Dockerfile -> 脚本使用Dockerfile内容构建镜像 -> Dockerfile先使用SDK进行编译发布 -> Docker使用AspNet作为运行环境并构建镜像 -> 脚本删除旧容器(如果有) ->脚本启动新容器