本地Docker Jenkins构建dotnet core web应用到Linux服务器 Docker上

1、准备工作

环境

  • 本地: WindowsDocker
  • 代码仓库:Git
  • 服务器:LinuxDocker

前提准备

  1. 创建个有dockerfile文件的dotnet core 3 web项目
    新建一个dotnet 3.0的web项目,在项目文件夹添加Dockerfile文件,内容如下:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
COPY . .
ENTRYPOINT ["dotnet", "WebApplication.dll"]
  1. 准备git仓库,将项目的代码上传上去
  2. 构建有dotnet core 3.0 环境jenkins
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 [arch=amd64] 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

因为jenkins里面是没有dotnetcore环境的,所以需要本地创建个支持dotnetcore环境的。
找个地方新建文件夹,创建dockerfile文件,内容如上。
4. build镜像并运行容器

docker build . -t jenkins_dotnet

这里等待时间会比较长~


# 运行刚刚构建好的容器
docker run -d  --name jenkins -p 8080:8080 jenkins_dotnet
  1. 打开jenkins,安装推荐插件
    打开 localhost:8080 ,可以看到
docker exec -it jenkins bash
dotnet --version
cat /var/jenkins_home/secrets/initialAdminPassword
<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`重启下应用,然后重新打开[localhost:8080](http://localhost:8080)使用创建的管理员登录。

2、搞好了,开始干活

哦,还有些需要安装的插件 =.=||

需要安装的插件:

  • SCP publisher
  • Publish Over SSH
  • Environment Injector

进入 系统管理>插件管理->可选插件->输入插件名称->勾选需要插件->点击安装

安装完后,设置下这些插件,进入系统管理->系统配置,

  1. SCP publisher设置
    Ctrl + F 搜下 SCP找到SCP repository hosts-SCP sites设置位置,点新增
    HostName: 服务器IP地址
    Port:端口,默认22、
    Root Repository Path:文件存放目录
    User Name:登录用户名
    Password/Passphrase:密码

  2. Publish Over SSH 设置
    Ctrl + F 搜下 SCP找到SCP repository hosts-SSH Server设置位置,点新增再点高级勾选上 Use password authentication, or use a different key
    Name:名称
    Hostname:服务器IP地址
    Username:登录用户名
    Remote Directory:远程目录
    Passphrase / Password:密码
    Port:连接端口(默认22)

配置完后别忘记点保存。

创建构建任务第一种:自由风格的软件项目

点击新建任务, 选择构建一个自由风格的软件项目

  1. 源码管理设置
    选择Git,在Repository URL填入Git仓库地址

  2. 触发构建器
    可以配置一些定时构建等,我这里只是测试所以没有选择触发器。

  3. 构建环境

    1. 勾选Delete workspace before build starts
    2. 勾选Inject environment variables to the build process,存放构建是需要用到的环境变量
  4. 构建- 添加执行shell步骤
    增加构建步骤-执行shell,脚本如下:

#切换目录
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 
  1. 构建后步骤

    1. 上传文件到服务器
      增加构建后操作步骤-选择Publish artifacts to SCP Repository ,填入需要上传的压缩文件

      这里文件目录的基础目录是workspace,如果不知道具体的地址,可以先不创建构建后步骤保存下,然后点击立即构建,等待成功后,点击工作空间看下文件路径是怎样的,比如我的是这样的:

      得到压缩文件目录是WebApplication/bin/web-publish.tar

    2. 添加 服务器上要执行的shll命令 步骤

    增加构建后操作步骤- 选择 Send build artifacts over SSH

    这里要新增两个Transfers Set,在第一个TransfersExec command输入创建镜像脚本:

# 工作目录
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} ./;
在第二个`Transfers`的`Exec command`,输入运行容器命令:
# 运行容器
docker run -d -p 8001:80 --name  ${DOCKER_CONTAINER_NAME}  ${DOCKER_IMAGE_NAME}

到这里所有的设置都已经搞好啦,别忘记点击保存,点击立即构建 测试一下吧~

创建构建任务第二种:流水线[pipeline]

TODO:评论有位哥推荐流水线 可视化会好一点,马上动手尝试下~

首先创建任务,选择流水线:

与自由风格的一样也有触发器。

然后就没看到有其他设置有点懵 😄 ~百度了下发现流水线主要是用脚本写的

粗略研究下流水线语法,然后在网上找了个 SSH Pipeline Steps 流水线插件, 可以以SSH方式登录远程机器,集sshCommand、sshPut、sshGet 、sshRemove等功能,很符合我的需求到插件管理安装下

然后半懂不懂的开始撸脚本,不过基本上就是把自由风格的脚本复制过来,按照流水线脚本的风格,以及配合这个插件修改下。

流水线脚本如下:

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 ! ----------------' 
                }
            }
        }

    }
}

成果展示 😄

自由风格的

流水线的

dotnet core web应用

第一次研究这个,本来以为本地用Docker直接拉取个jenkins会简单快速一点,但还是花了不少时间~ 如果有什么问题,欢迎评论,大家一起学习解决。

posted @ 2019-12-08 20:41  Xiao24  阅读(875)  评论(3编辑  收藏