主要简单的介绍了一下 GitLab CI 的持续集成以及持续部署,这篇将通过 GitLab CI 发布一个 .net core 项目,来带小伙伴们感受一下自动化的魅力,从此告别手动发布。

准备工作

创建一个空MVC项目来进行演示:

mkdir hello-world
cd hello-world
dotnet new sln -n HelloWorld
mkdir src
cd src
dotnet new mvc -n GitLabCIDemo
cd ../
dotnet sln add .\src\GitLabCIDemo\GitLabCIDemo.csproj

完成以上创建后,用 vscode 打开应该是下面这个样子:

项目上传至 GitLab

在 gitlab 上新建一个 hello-world 的项目,将本地的项目上传。这个按照如下提示操作即可:

项目上传成功后,切一个 dev 分支出来,我这里的策略是,代码提交到 dev 分支是自动发布到开发环境进行验证的,生产环境是通过 master 分支打 tag 进行发布的。

  • 切换到 dev 分支!
  • 切换到 dev 分支!
  • 切换到 dev 分支!

添加相关脚本

在 hello-world 文件夹内创建 .build/docker 文件夹,并添加如下脚本以及Dockerfile:

  • build-image.sh
docker build -f .build/docker/Dockerfile --build-arg PROJECT=$1 --build-arg ASPNETCORE_ENVIRONMENT=$2 -t $3 .
  • build-project.sh
set -e
for arg in "$@"
do
target=$(pwd)/src/$arg
dotnet restore -v n $target
dotnet publish -c Release -o $target/publish $target
done
  • push-image.sh
NEW_TAG="registry.cn-hangzhou.aliyuncs.com/xxx/$1"; // 这里得用你自己命名空间哦
docker tag $1 $NEW_TAG
docker push $NEW_TAG
docker rmi $NEW_TAG
  • Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine
ARG PROJECT
ARG ASPNETCORE_ENVIRONMENT
ENV ASPNETCORE_ENVIRONMENT ${ASPNETCORE_ENVIRONMENT}
WORKDIR /app
COPY src/${PROJECT}/publish .
RUN echo "#!/bin/bash \n dotnet ${PROJECT}.dll" > start.sh && chmod +x ./start.sh
ENTRYPOINT ["./start.sh"]

这里构建镜像所使用 3.1-alpine 构建出来的镜像体积只有其他镜像版本构建出来体积的一半。推荐使用。到此目录结构就成了现在这样:

至此准备工作已经差不多了!我们先简单过一下 CI 的流程:

提交代码 --> 编译 --> 测试 --> 构建镜像 --> 发布

编译 -- Build

在 hello-world 目录下添加 .gitlab-ci.yml 文件,添加 build 任务:

stages:
- build helloworld-build:
stage: build
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- .build/docker/build-project.sh GitLabCIDemo
artifacts:
paths:
- src/*/bin
- src/*/publish

这里起一个容器来跑编译任务,具体细节可以看 build-project.sh 脚本,用 artifacts 将发布出来的资源上传,给后面的 构建任务使用,不需要重复 build,节约时间。这里执行会出现如下错误:

/bin/bash: line 89: .build/docker/build-project.sh: Permission denied

这是因为脚本没有执行权限,通过 chmod 命令可以解决:

chmod +x build-image.sh build-project.sh push-image.sh

重新提交,触发 build 任务。打开 GitLab CI 界面,执行成功,是不是很开心呢?

测试 -- Test

现在项目里面没有测试代码,那就新建一个吧。在 hello-world 根目录下:

mkdir test
cd test
dotnet new xunit -n GitLabCIDemo.UnitTests

更新 .gitlab-ci.yml 添加 Test 任务:

stages:
- build
- test helloworld-build:
stage: build
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- .build/docker/build-project.sh GitLabCIDemo
artifacts:
paths:
- src/*/bin
- src/*/publish helloworld-test:
stage: test
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- dotnet test -c Release
dependencies:
- helloworld-build

等待一会,查看 CI 运行。

构建 Docker 镜像 -- Pack

我这里使用的是阿里云的镜像仓库,需要现在阿里云上创建对应的命名空间以及镜像名称。我这里给镜像名取名为 hello-world,别忘了修改 push-image.sh 中的命名空间哦!

更新 .gitlab-ci.yml 添加 Pack 任务:

stages:
- build
- test
- pack helloworld-build:
stage: build
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- .build/docker/build-project.sh GitLabCIDemo
artifacts:
paths:
- src/*/bin
- src/*/publish helloworld-test:
stage: test
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- dotnet test -c Release
dependencies:
- helloworld-build helloworld-pack-staging:
stage: pack
tags:
- shell
script:
- .build/docker/build-image.sh GitLabCIDemo Staging hello-world:beta
- .build/docker/push-image.sh hello-world:beta
dependencies:
- helloworld-build
only:
- dev
  • Staging: 用来设置环境变量 ASPNETCORE_ENVIRONMENT,让 .net core 读取对应的配置文件,可以设置Development,Staging,Production 三种,可以在对应的环境设置对应环境变量,使用不同配置。

  • beta: 因为是开发环境,就一直使用同一个 tag 去覆盖之前的镜像,每次 pull 最新的镜像就好了,也可以使用 $CI_COMMIT_SHORT_SHA 使用当前 git 提交的 hash 值作为版本号

CI 应该执行的差不多,再去瞧瞧呗! 又是全绿,真是开心!额,全绿,怪怪的...

打开阿里云镜像容器服务,查看一下刚刚上传的容器镜像吧!

部署 -- Deploy

这里我图方便就使用 docker-compose 来做演示了,通常部署环境都是使用集群来部署的,当然单机部署也不是不无可能的,我内网用 k3s 搭建的一个集群,为啥不用 k8s,因为要求资源配置比较高,k3s 刚好够用。但是部署到 k3s 需要写挺多的配置的文件,可以单独写一篇博文介绍。

作为自动化最后一步,无论你是用 k8s,k3s,docker swarm......,都是拉取对应的镜像,进行部署。思路是一样的,只是部署方式略有不同。这里通过 docker-compose 来发布 hello-world 应用咯。

在部署的 Linux 服务器上创建文件夹 /deploy ,在目录下添加 docker-compose.yml 文件,添加如下内容:

version: "3.8"
services:
hello-world:
image: registry.cn-hangzhou.aliyuncs.com/jd-rd/hello-world:beta
container_name: hello-world
restart: always
ports:
- 5013:80
networks:
- basic_service networks:
basic_service:

更新 .gitlab-ci.yml,添加部署任务:

stages:
- build
- test
- pack
- deploy helloworld-build:
stage: build
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- .build/docker/build-project.sh GitLabCIDemo
artifacts:
paths:
- src/*/bin
- src/*/publish helloworld-test:
stage: test
tags:
- docker
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- dotnet test -c Release
dependencies:
- helloworld-build helloworld-pack-staging:
stage: pack
tags:
- shell
script:
- .build/docker/build-image.sh GitLabCIDemo Staging hello-world:beta
- .build/docker/push-image.sh hello-world:beta
dependencies:
- helloworld-build
only:
- dev deploy-staging:
stage: deploy
tags:
- staging
script:
- cd /deploy && docker-compose pull && docker-compose up --force-recreate -d && docker ps
only:
- dev

等待整个CI跑完,查看 CI 运行结果

通过服务器IP + 5013 访问应用了,就可以看到服务更新

修改一下 Index.cshtml 将 Welcome 修改为 Hello Devops ! ,重新提交一下,稍等片刻,重新访问即可看到变化了。

至此一个简单的 CI 流程已经走完了,各位看官可以根据自己的需求,继续探索。

题外话

如果将脚本都放在项目里面的话,将来涉及到脚本变更,需要每个项目都给改过去,这是十分痛苦的事情。这里推荐小伙伴可以通过 git submodule 子模块的方式进行引用,将公共的脚本都给提取出来,项目通过子模块来加载脚本项目,将来脚本变更,每个项目只需要更新一下子模块就好。

总结

通过以上一个小案例已经带小伙伴了解了一圈 GitLab-CI 如何来发布一个 .net core 应用,感受了一下 GitLab-ci 的魅力。但是以上方案还是有瑕疵的,对于单体应用来说,没有太大问题,但并不适合微服务项目。在微服务项目中,如果多个服务散落在多个仓库中,需要多个项目代码改动其实是很不方便的,所以现在很多的微服务项目都采用 Mono 仓库风格及将所有的服务都放在一个仓库里面,仓库体积虽然大,但是改动起来更方便。本篇就先到这里了,有关于 GitLab-CI 对于 Mono 仓库风格项目 CI&CD 探索实践,且听下回分解。

常见问题:

1、ci时报错:bash: line 119: dotnet: command not found

Unable to locate package dotnet-sdk-5.0
E: Couldn’t find any package by glob ‘dotnet-sdk-5.0’
E: Couldn’t find any package by regex ‘dotnet-sdk-5.0’

#解决方案:
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
apt search dotnet-sdk
然后重新运行安装指令即可。

自动化部署实例(donetcore GitLab CICD )的更多相关文章

  1. Jenkins-在windows上配置自动化部署(Jenkins+Gitlab+IIS)

    Jenkins-在windows上配置自动化部署(Jenkins+Gitlab+IIS) web部署样例 windows服务部署样例 系统备份 在服务器上创建后缀名为.ps1的文件,例:BackUpD ...

  2. Jenkins-在Centos上配置自动化部署(Jenkins+Gitlab+Rancher)

    Jenkins-在Centos上配置自动化部署(Jenkins+Gitlab+Rancher) 环境:centos7 首先在服务器上安装好Jenkins和Gitlab和Rancher Gitlab安装 ...

  3. Jenkins+Gitlab+Ansible自动化部署(二)

    接Jenkins+Gitlab+Ansbile自动化部署(一):https://www.cnblogs.com/zd520pyx1314/p/10210727.html Ansible的配置与部署 工 ...

  4. 基于Jenkins+Gitlab的自动化部署实战

    故事背景 一个中小型企业,是典型的互联网公司,当初期的时候可能运维只能标配到2~3人,此时随着公司的发展,项目会逐渐增多.前期部署项目可能都是手动的, 俗称“人肉部署”,这简直是无比的痛苦,不能忍受的 ...

  5. Jenkins持续集成git、gitlab、sonarqube(7.0)、nexus,自动化部署实战,附安装包,严禁转载!!!

    导读 之前用的都是SVN,由于工作需要用到Git,求人不如求己,技多不压身,多学一项技能,未来就少求别人一次,系统的学一遍,自己搭建一整套环境,自动化部署(自动发版),代码质量检测等等(为啥不用doc ...

  6. GitLab私有化部署 - CI/CD - 持续集成/交付/部署 - 源代码托管 & 自动化部署

    预期目标 源代码管理 借助GitLab实现源代码托管,私有化部署版本,创建项目,创建用户组,分配权限,项目的签入/牵出等. 自动化部署 源代码产生变更时(如签入),自动化编译并发布到指定服务器中部署, ...

  7. 使用 GitHub / GitLab 的 Webhooks 进行网站自动化部署

    老早就想写这个话题了,今天正好有机会研究了一下 git 的自动化部署.最终做到的效果就是,每当有新的 commit push 到 master 分支的时候,就自动在测试/生产服务器上进行 git pu ...

  8. Linux下的Jenkins+Tomcat+Maven+Gitlab+Shell环境的搭建使用(jenkins自动化部署)

    jenkins自动化部署 目标:jenkins上点构建(也可以自动检查代码变化自动构建)>>>项目部署完成. 一.安装jenkins 1.下载jenkins 这里我选择的是war包安 ...

  9. gitlab与jenkins的自动化部署(通过webhook与ansilble)

    gitlab与jenkins的自动化部署(通过webhook与ansilble) 1.部署介绍 gitlab服务器:192.168.1.49:80jenkins服务器:192.168.1.49:818 ...

  10. CentOS 7 Gitlab+Jenkins持续集成+自动化部署

    基于上次的环境<部署Gitlab+Jenkins持续集成环境> 来实现自动化部署 系统管理–>插件管理–>安装以下插件: Credentials Plugin(默认已经安装) ...

随机推荐

  1. maven中引入CDH依赖包,Cannot resolve org.apache.hadoop:hadoop-hdfs:3.0.0-cdh6.3.2

    POM文件加入仓库 cloudera https://repository.cloudera.com/artifactory/cloudera-repos/ 修改MAVEN配置文件 nexus-ali ...

  2. “/usr/bin/hdp-select”, line 226 print “ERROR: Invalid package – “ + name ^ SyntaxError: Missing parentheses in call to ‘print’. Did you mean print(“ERROR: Invalid package

    spark-submit时报错 python升级3.7引起 恢复2.7正常

  3. 错误: -source 1.7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)

    Modules 把 Language level 调成 8

  4. WebApi 接口请求耗时记录

    .Net Core NLog 配置 通过日志,记录每个接口请求的耗时情况 结合  <logger name="*" level="Trace" write ...

  5. 如何通过命令部署.Net

    如何通过命令部署.net3.5组件服务 问题:系统安装.net一直报错,无法安装该功能. 问题现象: 终极解决方案: 将windows10系统镜像文件拷贝在硬盘或者U盘中,鼠标右击选择"装载 ...

  6. Zookeeper面试题总结

    1.请简述Zookeeper的选举机制 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的. 假设这些服务器 ...

  7. 【教程】步兵 cocos2dx 加密和混淆

    文章目录 摘要 引言 正文代码加密具体步骤代码加密具体步骤测试和配置阶段IPA 重签名操作步骤 总结 参考资料 摘要 本篇博客介绍了针对 iOS 应用中的 Lua 代码进行加密和混淆的相关技术.通过对 ...

  8. python · ssh · SQL | python 连接远程 SQL 数据库

    python 连接本地 SQL 的 教程存档. 如果要连接远程的 SQL 数据库,需要先开一个 ssh 连接,在 ssh 连接里写 pymysql 的 connect 代码. 代码如下: ''' pi ...

  9. DFT Architecture

    Design For Test 在实际生产过程中产生的physical defect是导致芯片功能出错的根本原因 如何根据结构产生测试向量呢?主要考虑physical defect physical ...

  10. P5707 【深基2.例12】上学迟到

    1.题目介绍 2.题解 这里只有两个稍微注意的点 2.1 s % v != 0(向上取整) 这里的话,若是结果不为整数,我们必须向上取整,必须保证空余时间永远大于所需时间! 2.2 ceil向上取整函 ...