docker+jenkins自动部署前端项目(二)

974 阅读3分钟

上一篇文章初步介绍了如何用docker+jenkins自动部署前端项目,但实际开发过程中,安装jenkins的机器一般和部署服务器是分离的,一般是一台安装jenkins的机器负责n个项目的部署,本篇文章介绍如何将前端(VUE)项目部署到远程服务器上,实际上是多了ssh连接远程服务器的过程,本文演示用到了阿里云服务器(各个厂商的云服务器大同小异)和本地安装了docker+jenkins的机器(上篇文章已经介绍了如何安装docker+jenkins)。

整体步骤: image.png

获取源代码

本文依然拿github试手,过程与上篇文章一致, 测试github地址:github.com/marco110/do… ,全部脚本都在此项目中。

打包代码并构建镜像

脚本同上篇文章基本一致。

镜像推送到阿里云镜像仓库

此过程涉及到了阿里云账号的问题,我已经在阿里云镜像服务创建了个人实例,仓库名称为image-test,命名空间为marco_images,点击‘images-test’进入镜像仓库基本信息,该页面介绍了如何登录阿里云Docker Registry,如何拉取和推送镜像。

image.png

image.png

开始改造我们的Jenkinsfile,github已提供了完整脚本。

node() {
    // 个人阿里云镜像仓库地址及命名空间
    def registry = 'registry.cn-beijing.aliyuncs.com'
    def aliyunNamespace = 'marco_images/image-test'
    ...
    // 构建并上传镜像到阿里云
    stage('build & upload Image') {
        withCredentials([usernamePassword(credentialsId: 'jenkins_login_aliyun_docker', usernameVariable: 'username', passwordVariable: 'password')]) {
            try {
                sh 'cp -r dist ./devops_build'
                // 登录到阿里云Docker Registry
                sh "docker login -u ${username} -p ${password} ${registry}"

                sh "docker build -t ${registry}/${aliyunNamespace} ./devops_build"

                sh "docker tag ${registry}/${aliyunNamespace} ${registry}/${aliyunNamespace}:${dockerTag}"
                // 推送到阿里云镜像仓库
                sh "docker push ${registry}/${aliyunNamespace}:${dockerTag}"
                // 删除本地镜像
                sh "docker rmi ${registry}/${aliyunNamespace}:${dockerTag}"
            }
            catch(err) {
                echo "build and upload Image failed"
                throw err
            }
        }
    }
}

注意到我们脚本里面有 withCredentials([usernamePassword(credentialsId: 'jenkins_login_aliyun_docker', usernameVariable: 'username', passwordVariable: 'password')]),没错,这就是需要你的阿里云账户名和密码,像这么敏感信息肯定不会直接暴露在代码里,需要我们在jenkins页面配置。进入jenkins页面,点击进入我们的项目添加凭据,我直接添加为了全局凭据,注意id需要和我们Jenkinsfile中填写的一致。当脚本运行到此处时,就会发现自己的阿里云容器仓库->镜像版本中多了一条记录,此时我们已经成功的把镜像推送到了云端!

image.png

image.png

连接远程服务器,拉取镜像并运行容器

此时镜像已经在云端了,需要连接的远程项目部署服务器,上一篇文章我们安装了jenkins SSH Pipeline Steps插件,从名字我们就能看出是为了连接远程服务器的,继续改造我们的Jenkinsfile。

我们在连接远程服务器时,getServer方法中又出现了withCredentials([usernamePassword(credentialsId: 'ssh_remote_server', passwordVariable: 'password', usernameVariable: 'username')]), 同样需要我们添加凭据,输入远程服务器的账户名和密码。

此时我将远程服务器ip直接放在了脚本中,感觉此做法不对,希望有大神指点!

node() {
// 部署项目的服务器ip
    def sshIP = 'xxx.xxx.xxx.xxx'
    def dockerName = 'marco-test'
    
    stage('ssh server & pull image'){
        try {
            // 连接远程服务器
            def sshServer = getServer(sshIP)
            // 更新或下载镜像
            sshCommand remote: sshServer, command: "docker pull ${registry}/${aliyunNamespace}:${dockerTag}"
            
            // 停止并删除容器
            sshCommand remote: sshServer, command: "docker rm -f ${dockerName}"
            // 启动
            sshCommand remote: sshServer, command: "docker run -u root --name ${dockerName} -p 80:80 -d ${registry}/${aliyunNamespace}:${dockerTag}"
            // 只保留3个最新的镜像
            sshCommand remote: sshServer, command: """docker rmi -f \$(docker images | grep ${registry}/${aliyunNamespace} | sed -n  '4,\$p' | awk '{print \$3}') || true"""
        }
        catch(err){
            echo "remote & pull image failed"
            throw err
        }
    }
}

def getServer(ip){
    def remote = [:]
    remote.name = "server-${ip}"
    remote.host = ip
    remote.port = 22
    remote.allowAnyHosts = true
    withCredentials([usernamePassword(credentialsId: 'ssh_remote_server', passwordVariable: 'password', usernameVariable: 'username')]) {
        remote.user = "${username}"
        remote.password = "${password}"
    }
    return remote
}

大功告成

此时访问ip:80 就能看到你发布的网站了。

image.png

如有失败,务必先去看错误信息,不要盲目的百度!此过程需要jenkins插件的支持,同上篇文章提到的Docker Pipeline、SSH Pipeline Steps、CloudBees Docker Build and Publish。

此篇依旧是为了记录过程,在下也是初识docker和jenkins,在这方面并不专业,如有错误,欢迎指出。