(寒天催日短,风浪与云平)
书接上文,上回咱们说到了《【Blog.Core开源】完成升级.NET 6.0》,只是代码层面的升级,今天趁着周末正好把生产环境也升级下(大家可以酌情升级哟)。过程很简单,自从用了容器化,再配上CI/CD,发布升级什么的都不是问题了,顺便也把我自定义的Jenkins升级下。
Github上已经把6.0合并到了master分支,5.0已经归档了,因为还有很多小伙伴还在用5.0的嘛,目前这个分支还在维护中,等到2022年,就不维护5.0了。
目前主要使用Docker来构建镜像,常见的主要是两种解决方案,两种方案又对应不同的操作。
方式一、外部编译
很久之前在使用Jenkins的时候,采用的是编译项目和构建镜像分开的两步,在Dockerfile中,只是Copy在Jenkins里发布好的可执行文件,这种在外部编译的方案也慢慢的被放弃了:
与之对应的Dockerfile是这样的:
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
WORKDIR /app
COPY . .
EXPOSE 9291
ENTRYPOINT ["dotnet", "Blog.Core.Api.dll","-b","0.0.0.0"]
这种方案有个弊端,就是在升级我们应用服务的时候,也需要配套升级Jenkins,因为需要对应的SDK嘛是吧,所以我也为了满足一部分在使用这种方式的小伙伴,升级了下我自己的Jenkins镜像,自己拉取下来,run一下就行,目前这个镜像里包含了.NET3.1/5.0/6.0的SDK,还有前端的NPM/CNPM命令。
这个镜像我之前是放到DockerHub的,但是有小伙伴反馈需要翻墙,拉取很慢,所以我以后都统一放到阿里云仓库吧。
相应的Dockerfile我已经上传到了Github:
https://github.com/anjoy8/devops
为了将敏捷开发中,一些资料和总结的方案给记录下来,供大家来学习和使用,如果有比较爱好开源的小伙伴,也可以把上云的一些配置和工具什么的提交上来,一起学习。
可以直接执行命令,就可以运行容器了:
docker run -u root --rm -d -p 3000:8080 \
--name jenkins \
-v /etc/localtime:/etc/localtime \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/dockerVolumes2/jenkins_home:/var/jenkins_home \
registry.cn-hangzhou.aliyuncs.com/bcvp/jenkins_with_dntcore3.1_5.0_6.0-cnpm_by_docker:latest
可以配置挂载,这样之前的所有配置和数据都会保留的,我每次升级都指定这个挂载,实现无缝更新。
这就是第一种方案,但是这种方案有些麻烦毕竟,目前更流行的就是发布和构建都在Dockerfile一起的。
方式二、编译和构建一起
先展示下代码是这样的,这也是官方给的:
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim AS build
WORKDIR /src
COPY ["Blog.Core.Api/Blog.Core.Api.csproj", "Blog.Core.Api/"]
COPY ["Blog.Core.Extensions/Blog.Core.Extensions.csproj", "Blog.Core.Extensions/"]
COPY ["Blog.Core.Tasks/Blog.Core.Tasks.csproj", "Blog.Core.Tasks/"]
COPY ["Blog.Core.IServices/Blog.Core.IServices.csproj", "Blog.Core.IServices/"]
COPY ["Blog.Core.Model/Blog.Core.Model.csproj", "Blog.Core.Model/"]
COPY ["Blog.Core.Common/Blog.Core.Common.csproj", "Blog.Core.Common/"]
COPY ["Blog.Core.Services/Blog.Core.Services.csproj", "Blog.Core.Services/"]
COPY ["Blog.Core.Repository/Blog.Core.Repository.csproj", "Blog.Core.Repository/"]
COPY ["Blog.Core.EventBus/Blog.Core.EventBus.csproj", "Blog.Core.EventBus/"]
RUN dotnet restore "Blog.Core.Api/Blog.Core.Api.csproj"
COPY . .
WORKDIR "/src/Blog.Core.Api"
RUN dotnet build "Blog.Core.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Blog.Core.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
EXPOSE 9291
ENTRYPOINT ["dotnet", "Blog.Core.Api.dll"]
这种方式是在容器内部进行项目还原,编译和打包操作,然后执行镜像的构建。好处很明显,不依赖于外部环境,只要保证有Dokcer环境,就能拉取源镜像SDK,所以也就不需要升级上边说的Jenkins了。
所以我现在都是采用这种模式。
PS:这里有个小问题,感兴趣的可以了解下,为什么Dockerfile要用EXPOSE来暴露端口,虽然最终起作用的是项目真正的监听端口,比如asp.netcore的5000。
最终效果预览
代码提交后,直接在Jenkins发版,可以看到详细的构建过程.
可以看到已经发布成功了,效果没啥问题:
打完收工,我的个人建议是,除非公司有要求,不然的话,还是升级下比较好的,整体很流畅,项目也无感知。