使用 Gitlab CI/CD 实现自动化发布站点到 IIS
说明
这里先介绍下两个东西 CI/CD、GitLab Runner,当然在此之前你需要对 git 有所了解,关于 git 这里不做说明,可以自行百度。
首先介绍 CI/CD :随着我们开发方式的转变,程序的发布变得非常频繁,而其这些发布操作都是重复的。CI/CD 就是为了使这些操作能变得自动化,那它是怎么实现自动化的呢?其实它做的就是当我们使用 git push(推送)代码的时候会执行 任务(task) 而这个 任务 里面其实又包含多个 作业(job),如对代码进行单元测试、部署项目等等,这些 任务 和 作业 在 gitlab 中其实是以一个 .gitlab-ci.yml 文件存在的,这个文件后面会说明。好了我们知道了 CI/CD 是什么(心虚~,你们可以自行百度查看更详细的说明。),那么到底是谁在执行这些 任务 和 作业 的呢?这就是下面要介绍的 GitLab Runner。
GitLab Runner:GitLab Runner 就是用来运行我们定义好的 任务 和 作业 也就是 .gitlab-ci.yml 文件。Runner 分为 Shared Runner(共享型) 和 Specific Runner(专有型),Shared Runner 是所有的项目都能用,但只能由管理员创建,而 Specific Runner(专有型)只能为指定的项目服务。Shared Runner 一般是用在有多个项目的服务器上,Specific Runner 则是单个项目的服务器,或者是你自己的电脑上。
下面列出我本次使用的环境:
操作系统:Windows 10
项目版本:.NET Core 2.2
脚本执行环境:PowerShell 5.1.17763.316
Web服务器:IIS 10.0
Gitlab:使用 gitlab.com (*Gitlab 支持私有化部署 )
项目地址:https://gitlab.com/WigorRunnerTest

Gitlab CI/CD
首先你需要在 GitLab 上注册个账号,这里需要使用你懂的工具上网,因为它使用了谷歌的 reCAPTCHA,如果你是自己部署的 gitlab 将没有这个问题。如果大家有需要请留下邮箱。
Gitlab 设置中文界面
Gitlab 默认的界面是英文的,只需要点击头像行的 Settings,然后点击 左侧导航栏 的 Preferences,之后在滑到最底部找到 Localization 旁边的 Language 选择 简体中文,最后点击 Save changes,F5 刷新页面即可。
设置好后我们可能更方便的操作 gitlab 了,接着我们需要创建一个项目,这里将使用一个 DotNET Core 项目为例。创建好项目后我们需要将它先 clone 到本地。
下载 Gitlab Runner
在我们定义 任务 和 作业 之前我们需要在我们的服务器或者是电脑上安装好 Gitlab Runner。
官网下载地址:https://docs.gitlab.com/runner/install/
下面是我整理好的下载地址,本次使用的是 Windows amd64:
下载好后,找到你下载的目录,将软件重命名为 gitlab-runner.exe。只用使用 cmd 进入到该目录,需要注意的是你需要以 管理员 的方式运行 cmd,否者后面执行命令的时候会报错。

注册 Gitlab Runner
接着在命令行中输入:
gitlab-runner register
这时会出现提示:Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
它叫你输入协调器的地址,这个地址是在你 gitlab 项目的 左侧导航栏 ,设置 下的 CI/CD 中,找到 Runner 点击展开,就会看到 专有Runner 和 共享Runner ,这里我们使用 专有Runner 做演示说明。红色框中的东西是我们后面需要用到的东西。

好了我们有了 coordinator URL 把它复制下了,粘贴到刚刚的命令中回车。
出现了另外一个提示:Please enter the gitlab-ci token for this runner:,需要你输入 token ,这个 token 就是你刚刚复制 URL 下面的 注册令牌。接着它要你输入这个 Runner 的描述,这个根据自己的情况填。
之后又来一个提示:Please enter the gitlab-ci tags for this runner (comma separated):,需要我们输入 Runner 的标签,这里我使用 deploy。
最后一个提示:Please enter the executor: docker, virtualbox, shell, ssh, docker+machine, docker-ssh+machine, kubernetes, docker-ssh, parallels:,需要我们填入脚本的执行环境,这里先填 shell,这时你的 gitlab-runner.exe 下会生成一个 config.toml 文件,里面保存着我们刚刚输入的信息。

需要注意的是这个标签就是我们后面编写
.gitlab-ci.yml里的 job 会用到,它根据 tags 来指派哪些 Runner 会执行该任务和作业。
之后我们回到 gitlab 可以看到这里已经有个激活的运行器了,这里的图标也变成了绿色。如果你这里显示的不是绿色,那么你刷新下页面看看,还不行的话那么你需要运行 gitlab-runner restart 命令来重启 Runner,接着可以使用 gitlab-runner status 查看 Runner 的运行状态。出现 gitlab-runner: Service is running! 那么表示你的服务已经运行成功了。 再次强调你的命令需要使用 管理员 身份运行。

将 Shell 改成 PowerShell
上面选择脚本执行环境的时候我们选了 shell,但是本次我是在 Windows 环境下运行,所以需要将它改为 PowerShell,打开 config.toml 文件,在 [[runners]] 下加入 shell = "powershell" ,然后保存文件即可。

.gitlab-ci.yml 简单说明
上面已经提过 .gitlab-ci.yml 使用来干什么的了,.gitlab-ci.yml 其实是本次自动化发布的核心,它是放在你 gitlab 上项目的根目录下。这里将对 .gitlab-ci.yml 该怎么配做一个简单说明,我只会介绍我用的东西更多的东西你可以查看我下面的「相关文档」。
首先在项目根目录下建立一个 .gitlab-ci.yml 文件,代码如下:
before_script:
- cd src
stages:
- test
# job
test:
stage: test
# 将会执行的脚本
script:
- dotnet restore
- dotnet build
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
我们来一个个说明这些东西的作用:
before_script 在整个项目 clone 到 Runner 所处的服务器时会先执行这个里面的脚本,这里我是进入到了 src 目录,你还可以在这里面做一些包还原的操作。
stages 里放的是将会执行的 job。
test 是做作业(job),这个命名你可以根据自己的情况来。test 就是上面 stages 会执行的 job 的真正配置处。
stage对应stages中的项,如果一个 job 没有指定 stage,那么这个任务会分配到test stage。script就是执行的脚本,构建自动化的核心也就是在此处。作为简单的演示,我就还原了包和生成项目。only是值该 job 会在被哪些分支 push 触发。tags上面在我们注册时有提到过,这个tags对应的是我们注册gitlab runner时所填的tages,表示的是该 job 会触发哪些 Runner。
OK,我们此时已经将一个最简单的 .gitlab-ci.yml 构建好了,在项目根目录下执行 git commit -am "[init] .gitlab-ci.yml",git push,将配置好的文件 push(推送)到远端。回到 gitlab 中,我们点击 CI/CD 可以看到有一个流水线在运行。

点进去可以看到运行的日志,可以看到我们 before_script、script 中的命令在一条条的执行,当然如果你的脚本出现了错误,状态会是 失败,你需要检查你的脚本是否有误。如果你的状态一直处于 等待中 那么需要检查你的 gitlab runner 是否允许正常,以及上面提到的 设置 中的 Runner 是否处于激活状态(绿色图标)。

输出乱码问题解决
你可能发现了这里怎么有一些奇怪的字符,这是因为我的操作系统是中文,乱码了解决办法是在 before_script 加入 - chcp 65001 脚本。
再次提交代码,ok 这次的中文信息显示正确了。

变量作用的说明
.gitlab-ci.yml 是存放在我们项目的根目录下的,如果我们项目使开源的,那么我们将会暴露一些私密信息如token,密钥,项目发布所处服务器的路径,这些信息公开可能会使我们的项目存在安全隐患。亦或者我们需要部署多个项目但是它们的 .gitlab-ci.yml 文件十分相似那么我们就可以通过变量控制哪些可变的因素。
那么到底怎么使用变量呢?第一步我们需要先声明变量,在 gitlab 的项目中找到 设置 下的 CI/CD,可以看到 变量 然后展开,这里就是可以声明我们需要用到的变量。.gitlab-ci.yml 只需要在脚本需要用到变量的方法使用 $env:变量名 的形式使用即可,需要注意的是:不同的系统使用变量的方法也不一样,这里我使用是 PowerShell。

常用的变量使用方法:
| Shell | 使用方法 |
|---|---|
| bash/sh | $variable |
| windows batch | %variable% |
| PowerShell | $env:variable |
关于变量的更多说明可以参考官方的文档:https://gitlab.com/help/ci/variables/README#variables
自动化部署到 IIS
前面已经介绍了构建一个自动化的流程,有了前面的基础其实自动化部署到 IIS 也就是编写的脚本发生了变化。
再开干之前我们需要把我们的思路捋一捋,核心在于怎么通过命令的形式发布一个站点。
- 首先需要编译项目,确保代码没有问题
- 使用
dotnet publish -c release -r win81-x64获取我们需要发布站点的部署文件 - IIS 停止运行需要发布的站点
- IIS 停止该站点的进程池
- 备份原有项目(不是必须,但是最好不要省去该步骤)
- 删除 IIS 上需要发布的站点的原有文件
- 复制我们准备好发布的文件(也就是 publish 文件夹)到 IIS 站点下
- IIS 启动进程池
- IIS 启动该站点
下面一步一步已脚本的形式来说明:
- 首先确定整体的东西,这里我准备构建两个 job
test和deploy,第一个 job 用于校验我们的代码是否正确,第二个是部署的 job。第一个 job 只有两行命令,还原和编译。
before_script:
#中文乱码问题
- chcp 65001
- cd src
# 执行的 job
stages:
- test
- deploy
# 校验代码
test:
stage: test
# 将会执行的脚本
script:
- dotnet restore
- dotnet build
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
# 部署
deploy:
stage: deploy
# 将会执行的脚本
script:
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
- 在进行编写剩下的脚本之前需要定义几个变量:
ProjectName:项目名称,用于 publish 用,如 VS 下一个解决方案可能存在多个项目,这时候就需要知道我们 publish 的项目使哪个。
WebSiteName:站点名称,用户关闭 IIS 站点和 IIS 对应进程池的,如果你的进程池和站点的名称不一致请在声明一个变量。
WebSitePath:站点的路径,用于备份、删除原有站点、新的项目复制到该路径下。

定义好这些变量后接着写我们 deploy 的脚本:
可以看到这里使用了:$env:ProjectName、$env:WebSitePath、$env:WebSiteName 变量。
# 部署
deploy:
stage: deploy
# 将会执行的脚本
script:
# 声明一个变量保存当前时间,用作备份数据文件夹名称
- $datetime=Get-Date -Format 'yyyy-MM-dd-HH-mm'
# 编译打包项目
- dotnet publish -c release -r win81-x64
# 进入编译好的项目目录
- cd $env:ProjectName\bin\Release\netcoreapp2.2\win81-x64\
# 停止 IIS 对应站点
- C:\Windows\System32\inetsrv\appcmd.exe stop site $env:WebSiteName
# 停止进程池
- C:\Windows\System32\inetsrv\appcmd.exe stop apppool /apppool.name:"$env:WebSiteName"
# 备份原有项目文件,项目名_当前时间
- cp "$env:WebSitePath" "$env:WebSitePath$datetime" -Recurse
# 删除原有站点
- del "$env:WebSitePath" -Recurse
#复制 publish 文件到站点
- cp "publish" "$env:WebSitePath" -Recurse
# 启动进程池
- C:\Windows\System32\inetsrv\appcmd.exe start apppool /apppool.name:"$env:WebSiteName"
# 启动 IIS 站点
- C:\Windows\System32\inetsrv\appcmd.exe start site $env:WebSiteName
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
到这一步整个自动化发布已经完成了,我们只要 push 代码到远端就会自动部署我们的项目到 IIS 中,需要注意的是你必须确保你的 IIS 中已经有这个站点了。
回到 gitlab 中查看 CI/CD 可以看到这次我们的阶段有两个,因为我配置了两个 作业(job),一个 test一个 deploy。

点击每个作业中看看执行的脚本是不是我们定义好的,需要提一下 powershell 脚本如果出错的话 gitlab-ci 返回的结果还是会显示成功,错误提示还是乱码的,坑啊。额~目前还找到解决的办法,如果是 docker 或者 linux 下应该没有这问题。

再看看 IIS 这边的效果,文件已经自动备份了,站点也正常运行了,一个自动化部署项目到 IIS 站点已经完成了。


模拟项目发布
下面修改代码然后 push 上去看看,看看我们的网站没有没有更新。

完整的 .gitlab-ci.yml
before_script:
#中文乱码问题
- chcp 65001
- cd src
# 执行的 job
stages:
- test
- deploy
# 校验代码
test:
stage: test
# 将会执行的脚本
script:
- dotnet restore
- dotnet build
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
# 部署
deploy:
stage: deploy
# 将会执行的脚本
script:
# 声明一个变量保存当前时间,用作备份数据文件夹名称
- $datetime=Get-Date -Format 'yyyy-MM-dd-HH-mm'
# 编译打包项目
- dotnet publish -c release -r win81-x64
# 进入编译好的项目目录
- cd $env:ProjectName\bin\Release\netcoreapp2.2\win81-x64\
# 停止 IIS 对应站点
- C:\Windows\System32\inetsrv\appcmd.exe stop site $env:WebSiteName
# 停止进程池
- C:\Windows\System32\inetsrv\appcmd.exe stop apppool /apppool.name:"$env:WebSiteName"
# 备份原有项目文件,项目名_当前时间
- cp "$env:WebSitePath" "$env:WebSitePath$datetime" -Recurse
# 删除原有站点
- del "$env:WebSitePath" -Recurse
- cp "publish" "$env:WebSitePath" -Recurse
# 启动进程池
- C:\Windows\System32\inetsrv\appcmd.exe start apppool /apppool.name:"$env:WebSiteName"
# 启动 IIS 站点
- C:\Windows\System32\inetsrv\appcmd.exe start site $env:WebSiteName
# 哪个分支会执行
only:
- master
#runner 注册时的 tag,这里指会触发的 runner
tags:
- deploy
小结
至此已经实现了 push 时项目自动发布到 IIS 。当然在这个过程中踩了 n 多的坑,总结要细心安装步骤一步一步认真的走。下一步准备对接钉钉的机器人。实现的效果是当我们项目发布时会自动通知,发布成功后也会自动通知。
相关文献
《什么是 CI/CD?》:https://linux.cn/article-9926-1.html
《GitLab-CI与GitLab-Runner》: http://www.cnblogs.com/cnundefined/p/7095368.html
《IIS 站点和进程池关闭》:https://www.cnblogs.com/jmaly/p/9860606.html
《Gitlab-CI job 配置文件 .gitlab-ci.yml 配置方式(翻译)》:https://blog.csdn.net/kunyus/article/details/81390330
powershell论坛:https://www.pstips.net
GitLab Runner 官方文档:https://docs.gitlab.com/ee/ci/runners/README.html
使用 Gitlab CI/CD 实现自动化发布站点到 IIS的更多相关文章
- .Net Core自动化部署系列(三):使用GitLab CI/CD 自动部署Api到Docker
之前写过使用Jenkins实现自动化部署,最近正好没事研究了下GitLab的自动化部署,顺便记录一下. 使用GitLab部署我们需要准备两件事,第一个起码你得有个GitLab,自己搭建或者使用官方的都 ...
- GitLab CI/CD 自动化部署入门
前言:因为找了B站内推,测试开发,正好知道内部使用GitLab做自动化测试,所以简单学了一下,有错误的地方请指正. 入门 初始化 cp: 无法获取'/root/node-v12.9.0-linux-x ...
- 使用Docker方式部署Gitlab,Gitlab-Runner并使用Gitlab提供的CI/CD功能自动化构建SpringBoot项目
1.Docker安装Gitlab,地址:https://www.cnblogs.com/sanduzxcvbnm/p/13814730.html 2.Docker安装Gitlab-runner,地址: ...
- GitLab CI/CD的官译【原】
CI / CD方法简介 软件开发的持续集成基于自动执行脚本,以最大限度地减少在开发应用程序时引入错误的可能性.从新代码的开发到部署,它们需要较少的人为干预甚至根本不需要干预. 它涉及在每次小迭代中不断 ...
- .NetCore 配合 Gitlab CI&CD 实践 - 单体项目
前言 上一篇博文 .NetCore 配合 Gitlab CI&CD 实践 - 开篇,主要简单的介绍了一下 GitLab CI 的持续集成以及持续部署,这篇将通过 GitLab CI 发布一个 ...
- 前端初探 Gitlab CI/CD
前言 纵观人类历史的发展以及三次工业革命,你会发现利用机器来替代部分人力劳动,将重复的工作自动化从而解放生产力都是发展的必然趋势,在软件工程领域也不例外,其中 CI/CD 就是其中一项,那么什么是 C ...
- Gitlab CI/CD
Gitlab CI/CD 前言 纵观人类历史的发展以及三次工业革命,你会发现利用机器来替代部分人力劳动,将重复的工作自动化从而解放生产力都是发展的必然趋势,在软件工程领域也不例外,其中 CI/CD 就 ...
- .NetCore 配合 Gitlab CI&CD 实践 - 开篇
引言 这是一个系列的文章,讲述的是一个中小型开发团队如何从零开始使用搭建基建 GitLab 代码托管平台,以及使用 GitLab Runner 实现 CI/CD 的故事.本系列通过部署一个完整的 .n ...
- 官网GitLab CI/CD英文文档翻译
在查阅GitLab官网的CI/CD功能说明时,全是英文看起来不方便,通过翻译软件自动翻译后"内容失真",看起来很变扭.查阅了百度上的资料发现很多翻译很老旧,有些甚至是挂羊头卖狗肉. ...
随机推荐
- Hibernate——(4)Hibernate映射类型
一.常用的Hibernat映射类型有如下几种: string integer double date 日期,只表示年月日 datetime 日期,只表示年月日 timestamp 时间戳,存放 ...
- yii2.0复选框默认选中
<?php $model->node = array('0','2') ;?> <? echo $form->field($model,'node')->che ...
- WPF依赖属性(续)(1)
原文:WPF依赖属性(续)(1) 之前有写过几篇文章,详细地介绍了依赖属性的基本使用方法,如果你不想了解其内部实现机制的话,那么通过那两篇文章的介绍,足以应付平时的应用 ...
- HDOJ 4901 The Romantic Hero
DP....扫两次合并 The Romantic Hero Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 ...
- ElasticSearch的基本用法与集群搭建 good
一.简介 ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式 ...
- 在WPF中添加3D特性
原文:在WPF中添加3D特性 35.4 在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...
- js -- 捆绑
1.环境配置 主要參考网址: http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=10226&extra=pa ...
- WPF实现抽屉效果
原文:WPF实现抽屉效果 界面代码(xaml): <Window x:Class="TransAnimation.MainWindow" xmlns="http:/ ...
- 关闭Mac OS 的Rootless
今天在使用mac的时候,需要删除 /usr/bin/下的 自带的php文件.然后提示Operation not permitted 使用sudo 依然不可以,通过google 得到解决方案. 需要关闭 ...
- ntp时间同步,各种配置方法
1 Windows xp NTP服务器的配置(2003配置方式一样) 1) 首先需要关闭作为NTP服务器的windows系统自带的防火墙,否则将同步不成功. 2) 单击“开始”,单击“运行”,键入 r ...