本地Docker Jenkins构建dotnet core web应用到Linux服务器 Docker上
<h1 id="_"></h1><h2 id="1准备工作">1、准备工作</h2>
<h3 id="环境">环境</h3>
<ul>
<li>本地: <code>Windows</code>、<code>Docker</code></li>
<li>代码仓库:<code>Git</code></li>
<li>服务器:<code>Linux</code>、<code>Docker</code></li>
</ul>
<h3 id="前提准备">前提准备</h3>
<ol>
<li>创建个有<code>dockerfile</code>文件的<code>dotnet core 3 web</code>项目<br>
新建一个dotnet 3.0的web项目,在项目文件夹添加Dockerfile文件,内容如下:</li>
</ol>
<pre><code class="language-powershell">FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
COPY . .
ENTRYPOINT ["dotnet", "WebApplication.dll"]
</code></pre>
<ol start="2">
<li>准备git仓库,将项目的代码上传上去</li>
<li>构建有<code>dotnet core 3.0 环境</code>的<code>jenkins</code></li>
</ol>
<pre><code class="language-powershell">FROM jenkins/jenkins:lts
# 切换root用户安装东西
USER root
# Show distro information!
RUN uname -a && cat /etc/*release
RUN apt-get update
RUN apt-get install -y curl libunwind8 gettext apt-transport-https
RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
RUN mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
RUN sh -c 'echo "deb https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/dotnetdev.list'
RUN apt-get update
RUN apt-get install -y dotnet-sdk-3.1
# 切换回来jenkins用户
USER jenkins
</code></pre>
<p>因为jenkins里面是没有dotnetcore环境的,所以需要本地创建个支持dotnetcore环境的。<br>
找个地方新建文件夹,创建dockerfile文件,内容如上。<br>
4. build镜像并运行容器</p>
<pre><code class="language-powershell">docker build . -t jenkins_dotnet
</code></pre>
<blockquote>
<p>这里等待时间会比较长~</p>
</blockquote>
<pre><code class="language-powershell">
# 运行刚刚构建好的容器
docker run -d--name jenkins -p 8080:8080 jenkins_dotnet
</code></pre>
<ol start="5">
<li>打开jenkins,安装推荐插件<br>
打开 localhost:8080 ,可以看到<br>
<img style="width: 500px" src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208123747847-1722522911.png"></li>
</ol>
<pre><code>docker exec -it jenkins bash
dotnet --version
cat /var/jenkins_home/secrets/initialAdminPassword
</code></pre>
<pre><code><img style="width:500px;" src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208124555303-170629763.png" />
把密码复制出来登录,点击`左边按钮`安装推荐插件
<img style="width:500px;" src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208203620027-1679218834.png" />
> 这里时间也会比较长,如果有部分安装失败了,等剩余的安装完后点击重试即可,如果服务器上还没有docker,现在可以去装下,装了的也可以连上服务器,去执行`docker pull mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim`拉取下dotnet core 3.1的镜像,等会创建镜像的时候就会快一点啦
插件安装完后,会有一些创建管理员和地址配置,搞一下吧。
<img style="width:500px;" src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208150033306-489017996.png" />
> 如果有插件安装失败,点过重试安装插件的,现在需要`docker restart jenkins`重启下应用,然后重新打开(http://localhost:8080)使用创建的管理员登录。
</code></pre>
<h2 id="2搞好了开始干活">2、搞好了,开始干活</h2>
<h3 id="哦还有些需要安装的插件-">哦,还有些需要安装的插件 =.=||</h3>
<p>需要安装的插件:</p>
<ul>
<li>SCP publisher</li>
<li>Publish Over SSH</li>
<li>Environment Injector</li>
</ul>
<p>进入 系统管理>插件管理->可选插件->输入插件名称->勾选需要插件->点击安装</p>
<p>安装完后,设置下这些插件,进入系统管理->系统配置,</p>
<ol>
<li>
<p><code>SCP publisher</code>设置<br>
Ctrl + F 搜下 <code>SCP</code>找到<code>SCP repository hosts</code>-<code>SCP sites</code>设置位置,点<code>新增</code><br>
HostName: 服务器IP地址<br>
Port:端口,默认22、<br>
Root Repository Path:文件存放目录<br>
User Name:登录用户名<br>
Password/Passphrase:密码<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208151246430-1223070383.png" alt="" loading="lazy"></p>
</li>
<li>
<p><code>Publish Over SSH</code> 设置<br>
Ctrl + F 搜下 <code>SCP</code>找到<code>SCP repository hosts</code>-<code>SSH Server</code>设置位置,点<code>新增</code>再点<code>高级</code>,<strong>勾选上 <code>Use password authentication, or use a different key</code></strong><br>
Name:名称<br>
Hostname:服务器IP地址<br>
Username:登录用户名<br>
Remote Directory:远程目录<br>
Passphrase / Password:密码<br>
Port:连接端口(默认22)<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208151601602-2052844485.png" alt="" loading="lazy"></p>
</li>
</ol>
<blockquote>
<p><strong>配置完后别忘记点保存。</strong></p>
</blockquote>
<h3 id="创建构建任务第一种自由风格的软件项目">创建构建任务第一种:自由风格的软件项目</h3>
<p>点击<code>新建任务</code>, 选择<code>构建一个自由风格的软件项目</code><br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208152024320-902148436.png" alt="" loading="lazy"></p>
<ol>
<li>
<p>源码管理设置<br>
选择Git,在<code>Repository URL</code>填入Git仓库地址<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208152301015-1735939415.png" alt="" loading="lazy"></p>
</li>
<li>
<p>触发构建器<br>
可以配置一些定时构建等,我这里只是测试所以没有选择触发器。<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208152522084-246314991.png" alt="" loading="lazy"></p>
</li>
<li>
<p>构建环境</p>
<ol>
<li>勾选<code>Delete workspace before build starts</code></li>
<li>勾选Inject environment variables to the build process,存放构建是需要用到的环境变量<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208153134484-540093633.png" alt="" loading="lazy"></li>
</ol>
</li>
<li>
<p>构建- 添加执行shell步骤<br>
增加构建步骤-执行shell,脚本如下:</p>
</li>
</ol>
<pre><code class="language-powershell">#切换目录
cd ./WebApplication
#还原nuget包
dotnet restore
#编译
dotnet build
#删除之前发布文件
cd ./bin
rm -rf web-publish
rm -f web-publish.tar
cd ..
#发布
dotnet publish -o ./bin/web-publish
#删除配置文件
cd ./bin/web-publish
cp ../../Dockerfile .
rm -rf config
cd ..
#压缩
tar -cvf web-publish.tar web-publish
</code></pre>
<ol start="5">
<li>
<p>构建后步骤</p>
<ol>
<li>
<p>上传文件到服务器<br>
<code>增加构建后操作步骤</code>-选择<code>Publish artifacts to SCP Repository</code> ,填入需要上传的压缩文件<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208163121648-1725578843.png" alt="" loading="lazy"><br>
这里文件目录的基础目录是workspace,如果不知道具体的地址,可以先不创建构建后步骤保存下,然后点击立即构建,等待成功后,点击工作空间看下文件路径是怎样的,比如我的是这样的:<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208162400248-1912436917.png" alt="" loading="lazy"><br>
得到压缩文件目录是<code>WebApplication/bin/web-publish.tar</code></p>
</li>
<li>
<p>添加 服务器上要执行的shll命令 步骤</p>
</li>
</ol>
<p><code>增加构建后操作步骤</code>- 选择 <code>Send build artifacts over SSH</code></p>
<p>这里要新增两个Transfers Set,在第一个<code>Transfers</code>的<code>Exec command</code>输入创建镜像脚本:</p>
</li>
</ol>
<pre><code class="language-powershell"># 工作目录
WORK_DIR="/root/publish/WebApplication";
cd ${WORK_DIR}
# 删除原有发布文件夹
rm -rf web-publish;
# 解压
tar -xvf web-publish.tar;
#删除文件压缩包
rm -f web-publish.tar;
#切换生成目录
cd web-publish/
#备份镜像
#停止容器
docker stop ${DOCKER_CONTAINER_NAME};
#删除容器
docker rm ${DOCKER_CONTAINER_NAME};
#删除镜像
docker rmi $(docker images | grep ${DOCKER_IMAGE_NAME});
#创建镜像
docker build -t ${DOCKER_IMAGE_NAME} ./;
</code></pre>
<pre><code>在第二个`Transfers`的`Exec command`,输入运行容器命令:
</code></pre>
<pre><code class="language-powershell"># 运行容器
docker run -d -p 8001:80 --name${DOCKER_CONTAINER_NAME}${DOCKER_IMAGE_NAME}
</code></pre>
<p><img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208202346480-2044067851.png" alt="" loading="lazy"></p>
<blockquote>
<p>到这里所有的设置都已经搞好啦,<code>别忘记点击保存</code>,点击<code>立即构建</code> 测试一下吧~</p>
</blockquote>
<h3 id="创建构建任务第二种流水线pipeline">创建构建任务第二种:流水线</h3>
<blockquote>
<p>TODO:评论有位哥推荐流水线 可视化会好一点,马上动手尝试下~</p>
</blockquote>
<p>首先创建任务,选择流水线:<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191217215230901-142748780.png" alt="" loading="lazy"></p>
<p>与自由风格的一样也有触发器。<br>
<img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191217215334916-607455788.png" alt="" loading="lazy"></p>
<blockquote>
<p>然后就没看到有其他设置有点懵 😄 ~百度了下发现流水线主要是用脚本写的</p>
</blockquote>
<p>粗略研究下流水线语法,然后在网上找了个 SSH Pipeline Steps 流水线插件, 可以以SSH方式登录远程机器,集sshCommand、sshPut、sshGet 、sshRemove等功能,很符合我的需求<sub>到插件管理安装下</sub></p>
<p>然后半懂不懂的开始撸脚本,不过基本上就是把自由风格的脚本复制过来,按照流水线脚本的风格,以及配合这个插件修改下。</p>
<p>流水线脚本如下:</p>
<pre><code>def getHost(){
def remote = [:]
remote.name = 'aliyun-1'
remote.host = '你的服务器IP'
remote.user = '你的服务器登录用户名'
remote.port = 22
remote.password = '你的服务器登录用户密码'
remote.allowAnyHosts = true
return remote
}
pipeline {
agent {label 'master'}
environment{
def server = '';
def local_work_dir="./WebApplication";
def webpublish_name="web-publish";
def ssh_work_dir="/root/publish/WebApplication";
def ssh_docker_image_name="dotnet/webdemo";
def ssh_docker_container_name="webdemo";
}
stages {
stage('init-server'){
steps {
script {
server = getHost()
}
}
}
stage('git-checkout') {
steps {
git url: 'https://github.com/LXD24/DemoReposiroty.git'
}
}
stage('dotnet-build-publish'){
steps {
sh'''
#切换目录
cd ${local_work_dir};
#还原nuget包
dotnet restore;
#编译
dotnet build;
#删除之前发布文件
cd ./bin;
rm -rf ${webpublish_name};
rm -f ${webpublish_name}.tar;
cd ..;
#发布
dotnet publish -o ./bin/${webpublish_name};
#删除配置文件
cd ./bin/${webpublish_name};
cp ../../Dockerfile .;
rm -rf config;
cd ..;
#压缩
tar -cvf ${webpublish_name}.tar ${webpublish_name};
'''
echo '---------------- build complete ! ----------------'
}
}
stage('ssh-put'){
steps {
script {
sshPut remote: server, from: "${local_work_dir}/bin/web-publish.tar", into: "${ssh_work_dir}"
echo '---------------- sshput complete ! ----------------'
}
}
}
stage('ssh-build-docker-image'){
steps {
script {
sshCommand remote: server, command: """
# 工作目录
cd ${ssh_work_dir}
# 删除原有发布文件夹
rm -rf ${webpublish_name};
# 解压
tar -xvf ${webpublish_name}.tar;
#删除文件压缩包
rm -f ${webpublish_name}.tar;
#切换生成目录
cd ${webpublish_name}/
#备份镜像
#停止容器
docker stop ${ssh_docker_container_name};
#删除容器
docker rm ${ssh_docker_container_name};
#删除镜像
docker rmi \$(docker images | grep ${ssh_docker_image_name});
#创建镜像
docker build -t ${ssh_docker_image_name} ./;
"""
echo '---------------- ssh-build-docker-image complete ! ----------------'
}
}
}
stage('ssh-docker-run'){
steps {
script {
sshCommand remote: server, command: """
docker run -d -p 8001:80 --name${ssh_docker_container_name}${ssh_docker_image_name}
"""
echo '---------------- ssh-docker-run complete ! ----------------'
}
}
}
}
}
</code></pre>
<h2 id="成果展示-">成果展示 😄</h2>
<h3 id="自由风格的">自由风格的</h3>
<p><img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208220416145-391465593.png" alt="" loading="lazy"></p>
<h3 id="流水线的">流水线的</h3>
<p><img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191217221844616-1760087348.png" alt="" loading="lazy"></p>
<h3 id="dotnet-core-web应用">dotnet core web应用</h3>
<p><img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208220140261-247170660.png" alt="" loading="lazy"></p>
<p><img src="https://img2018.cnblogs.com/blog/1624324/201912/1624324-20191208215940594-1059777938.png" alt="" loading="lazy"></p>
<blockquote>
<p>第一次研究这个,本来以为本地用Docker直接拉取个jenkins会简单快速一点,但还是花了不少时间~ 如果有什么问题,欢迎评论,大家一起学习解决。</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/xiao24/p/docker_jenkins_dotnetcore3.html
頁:
[1]