网上寻找了很多关于jenkins发布.net程序的方案,但是没有找到合适的文章,很多内容都有些过时了,或者并不适用在Docker 中安装的Jenkins, 我结合了外网的一些搜索结果和ChatGPT自己摸索了一下。
一. 环境、准备工作
- 新建一个.NET 6 website 项目,并且上传到git中。
- 完成Jenkins的安装 (本例是通过Docker安装的Jenkins)
- 发布服务器中安装Docker环境
二. Jenkins 添加git认证与安装插件
Jenkins安装好后,进行以下配置和插件安装
我的Jenkins是英文界面,麻烦自行匹配中文,抱歉抱歉。
1. 添加git认证
登录首页后,点击 Manage Jenkins

点击 Credentials

点击 System

点击 Global credentials

点击右上角 Add Credentials

选择对应的认证方式,例子中使用的是gitlab的username + access token,选择 username with password,填入信息后保存。

2. 安装 Publish Over SSH 插件
这个插件用于连接到远程服务器,Linux 和 windows server都可以用
在首页中,点击 Manage Jenkins -> Plugins 进入插件管理页面

点击 Available plugins , 搜索 Publish Over SSH, 勾选后点击 安装且不重启

安装完成后,点击 Manage Jenkins -> System 拖到下方 Publish over SSH 位置,在SSH Server 下点击 Add

在新出现的选项卡中,填入对应信息:
- name : 自定义服务器名称
- hostname: 链接地址
- username: 服务器的登录账号
- Remote Directory: 自定义远程连接后的默认地址,通常是传输文件的父级目录,我设定的是/docker-space/app ,目录下再设置app1、app2等其他程序的目录
点击下方 Advance 后,再点击 Use password authentication, or use a different key 在下方 Password 中填写密码,完成后点击 Save, 这样远程服务器的连接配置就完成了

三、配置发布流程方案1:在目标服务器的Docker中编译、发布
1. 编写Dockerfile
打开Visual Studio, 右击项目

点击 Add , 选择 Docker Support

选择 Linux , 会在项目中新建一个DockerFile。也可以自己手动添加文件

修改文件
bash
# 用.net 6.0 的sdk镜像创建编译镜像
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
# 容器内部的工作目录为/app
WORKDIR /app
# 复制工程文件,restore 项目
COPY *.csproj .
RUN dotnet restore
# 复制源代码文件
COPY . .
# 复制源代码下的wwwroot文件下到/app/wwwroot目录下
COPY wwwroot /app/wwwroot
# 发布项目,发布目录为out,绝对路径是/app/out
RUN dotnet publish -c Release -o out --verbosity detailed
# 用.net 6.0 的runtime镜像作为发布镜像
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
# 容器内部的工作目录为/app
WORKDIR /app
# 从编译镜像中复制发布的文件到发布镜像
COPY --from=build /app/out ./
# 暴露80端口,也可以设置为其他接口
EXPOSE 80
# 启动项目
ENTRYPOINT ["dotnet", "DockerTest.dll"]
保存后,提交到git
2. 创建Jenkins项目
-
在Jenkins首页点击 New Item , 输入名称,选择第一个 Freestyle project , 点击 OK, 创建新的项目
-
创建后,在 Source Code Management 中选择 git, Repository URL 中填入 git 地址,Credentials 中选择之前录入的认证信息,如果认证失败,会有红色提醒显示,Branches to build 中填写对应分支。
-
git地址输入好后,在 Build Steps 中添加 Send files or execute commands over SSH 步骤,用来传输文件到远程服务器,或者在远程服务器上执行命令
在SSH Server -> Name中填入之前配置好的远程服务器
在下方 Transfer Set 中, 输入以下信息:
Source Files 中输入需要传输的文件路径,此处我的web端项目名是DockerTest,换成你的项目名称, /** 代表子目录下所有的文件和文件下
Remote Diectory 中输入服务器端的文件夹。此处${JOB_NAME}代表jenkins创建的项目名作为文件夹名,路径是Publish Over SSH 插件中配置的默认路径+项目名
Exec command 中输入远程服务器执行的命令,内容分别是定义路径;移除之前的镜像;创建新的镜像;运行镜像服务并将8060端口映射到容器的80端口(可自定义修改);最后一行命令是清除多次发布后生成的镜像
坑:如果采用 ${JOB_NAME} 环境变量在命令中,jenkins的项目名称不能带空格,最好使用小写加短横的命令方式,否则就手动输入地址、镜像和容器名称,不要用环境变量
bashcd /docker-space/app/${JOB_NAME}/DockerTest docker rm \${JOB_NAME} -f docker build -t ${JOB_NAME} . docker run -d -p 8060:80 --name \${JOB_NAME} --restart always ${JOB_NAME} docker image prune -f
完成后点击 Save 保存,然后点击 Build Now 运行,成功后可以看到绿色标志,若失败可以查看日志,调试错误。
坑:在 Send files or execute commands over SSH 中添加的运行在远程服务器的命令,日志中并不会体现,所以最好这些命令先在服务器中手动运行一遍,这样能更快调试。

完成后,可以看到在远程服务器的地址中已经有了文件

并且容器也已经运行起来了

这种方案的优点是Jenkins配置简单,并且相对自由,缺点是Dockerfile相对复杂,并且依赖目标服务器的Docker,如果不是发布到Docker则无法使用
四、配置发布流程方案2:在Jenkins中编译、发布
在Jinkins中编译.net项目,网上的文章不多,且大多数都是用的MSBuilder,这个插件很久没更新了,而且我并没有成功。无意中看到有 .NET SDK Support 插件,而且更新时间较近,只在外网找到一篇文章,所以决定自己照着试试并且研究下。
1. 安装 .NET SDK Support 插件
在 Manage Jenkins -> Plugins -> Avaliable plugins 中搜索 .NET SDK SupportVersion 并安装

在 Manage Jenkins -> Tools -> .NET SDK installations 中添加.net版本,依照.NET 6为例
点击 Add .Net SDK 后,输入名称.NET 6 (自定义)

.NET Vsersion \ Release \ SDK \ Platform 中选择对应的选项

点击保存后完成
2. 编写Dockerfile
打开Visual Studio, 右击项目

点击 Add , 选择 Docker Support

选择 Linux , 会在项目中新建一个DockerFile。也可以自己手动添加文件

修改文件,此处较为简单,只是做运行使用
bash
# 用.net 6.0 的镜像创建作为基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
# 容器内部的工作目录为/app
WORKDIR /app
# 暴露80端口,也可以设置为其他接口
EXPOSE 80
# 复制文件到app文件夹下
COPY . /app
# 启动项目
ENTRYPOINT ["dotnet", "DockerTest.dll"]
保存后,提交到git
3. 创建Jenkins项目
-
在Jenkins首页点击 New Item ,输入名称,选择第一个 Freestyle project , 点击 OK, 创建新的项目
-
创建后,在 Source Code Management 中选择 git, Repository URL 中填入 git 地址,Credentials 中选择之前录入的认证信息,如果认证失败,会有红色提醒显示,Branches to build 中填写对应分支。
-
Build Enviroment 中选择之前创建的.NET版本
-
Build Step 中添加 Execute shell 步骤,执行命令在Jenkins中编译、发布。
将 DockerTest 替换成你的.Net项目名称,此处发布文件夹是
publish
csscd /var/jenkins_home/workspace/${JOB_NAME}/DockerTest dotnet clean DockerTest.csproj --configuration Release dotnet restore DockerTest.csproj dotnet build DockerTest.csproj --configuration Release dotnet publish -c Release -o publish --verbosity detailed
到此处,建议先保存,然后点击一下 build 尝试运行
坑:如果你的Jenkins也是Docker版本的,很有可能遇到 Globalization的问题,原因是Jenkins容器内需要安装 libicu-dev
解决方案:
进入容器内容内部
docker exec -it -u root <container name> bash
安装libicu-dev
apt-get install libicu-dev
坑中坑:安装时遇到
Unable to locate package
问题,按照网上的办法更换国内镜像也没有用,最后耗费2个小时,最后在这个网站上找到最新的sources.list并且更换成功了解决方案
备份源列表文件
mv /etc/apt/sources.list /etc/apt/sources-backup.list
修改源文件,将下载的文件内容覆盖这个文件中的内容,当然也可以直接替换文件
vim /etc/apt/sources.list
执行更新命令
apt update
apt upgrade
-
在Jenkins中能编译通过后,添加 Send files or execute commands over SSH 步骤,传输文件到远程服务器
在 Name 中选择远程服务器
SourceFile 中添加需要传输的路径地址,由于此处发布的目录是publish,所以地址是 DockerTest/publish/**
** 代表文件夹下所有内容
Remote Diectory 中输入服务器端的文件夹。此处${JOB_NAME}代表jenkins创建的项目名作为文件夹名,路径是Publish Over SSH 插件中配置的默认路径+项目名
Exec command 中输入远程服务器执行的命令,内容分别是定义路径;移除之前的镜像;创建新的镜像;运行镜像服务并将8061端口映射到容器的80端口(可自定义修改);清除多次发布后生成的镜像;删除publish中的文件
坑:如果采用 ${JOB_NAME} 环境变量在命令中,jenkins的项目名称不能带空格,最好使用小写加短横的命令方式,否则就手动输入地址、镜像和容器名称,不要用环境变量
bash
cd /docker-space/app/${JOB_NAME}/DockerTest/publish
docker rm \${JOB_NAME} -f
docker build -t ${JOB_NAME} .
docker run -d -p 8061:80--name \${JOB_NAME} --restart always ${JOB_NAME}
docker image prune -f
cd /docker-space/app/${JOB_NAME}/DockerTest
rm -rf publish
点击 Save 完成后,最后点击 Build Now 发布,可以看到8061端口已经成功访问了


这个方案的优点是在不局限于发布在Docker上,也可以发布在Windows服务器中,缺点是配置时坑比较多,但是填完坑后,配置起来更简单