【问题标题】:How to use multiple Docker containers to set up Jenkins agent in Jenkins pipeline如何使用多个 Docker 容器在 Jenkins 管道中设置 Jenkins 代理
【发布时间】:2019-12-16 12:47:20
【问题描述】:

下面的 sn-p 是 Cypress 提供的一个示例,我正在使用的 Javascript 测试框架。这是 Github 页面的link

pipeline {
  agent {
    // this image provides everything needed to run Cypress
    docker {
      image 'cypress/base:10'
    }
  }

  stages {
    // first stage installs node dependencies and Cypress binary
    stage('build') {
      steps {
        // there a few default environment variables on Jenkins
        // on local Jenkins machine (assuming port 8080) see
        // http://localhost:8080/pipeline-syntax/globals#env
        echo "Running build ${env.BUILD_ID} on ${env.JENKINS_URL}"
        sh 'npm ci'
        sh 'npm run cy:verify'
      }
    }

    stage('start local server') {
      steps {
        // start local server in the background
        // we will shut it down in "post" command block
        sh 'nohup npm run start:ci &'
      }
    }

    // this stage runs end-to-end tests, and each agent uses the workspace
    // from the previous stage
    stage('cypress parallel tests') {
      environment {
        // we will be recording test results and video on Cypress dashboard
        // to record we need to set an environment variable
        // we can load the record key variable from credentials store
        // see https://jenkins.io/doc/book/using/using-credentials/
        CYPRESS_RECORD_KEY = credentials('cypress-example-kitchensink-record-key')
        // because parallel steps share the workspace they might race to delete
        // screenshots and videos folders. Tell Cypress not to delete these folders
        CYPRESS_trashAssetsBeforeRuns = 'false'
      }

      // https://jenkins.io/doc/book/pipeline/syntax/#parallel
      parallel {
        // start several test jobs in parallel, and they all
        // will use Cypress Dashboard to load balance any found spec files
        stage('tester A') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npm run e2e:record:parallel"
          }
        }

        // second tester runs the same command
        stage('tester B') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npm run e2e:record:parallel"
          }
        }
      }

    }
  }

  post {
    // shutdown the server running in the background
    always {
      echo 'Stopping local server'
      sh 'pkill -f http-server'
    }
  }
}

我的目标是拥有一个与上面非常相似的 Jenkinsfile,因为我想要进行并行 Cypress 测试,如上面的 sn-p 所示。在上面的示例中,Jenkins 代理只是 Cypress Docker 官方镜像cypress/base:10

  agent {
    // this image provides everything needed to run Cypress
    docker {
      image 'cypress/base:10'
    }
  }

但是,为了让我使用自己的数据库运行所有测试,我需要启动两个独立的 Docker 容器。一个容器包含我的网络应用程序的前端部分,另一个容器包含我的网络应用程序的后端部分。

下面是我的前端容器的 Dockerfile,它位于my-app/docker/combined/Dockerfile

FROM cypress/included:3.4.1

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5000

RUN npm install -g history-server nodemon

RUN npm run build-test

EXPOSE 8080

下面是我的后端容器的 Dockerfile,它位于my-app/docker/db/Dockerfile。它所做的只是将一些本地数据复制到 Docker 容器中,然后用这些数据初始化我的 MongoDB 数据库。

FROM  mongo:3.6.14-xenial

COPY ./dump/ /tmp/dump/

COPY mongo_restore.sh /docker-entrypoint-initdb.d/

RUN chmod 777 /docker-entrypoint-initdb.d/mongo_restore.sh

通常,我会使用docker-compose 和下面的docker-compose.yml 文件来启动这两个容器。可以看到,名为“combined”的前端容器依赖于名为“db”的后端容器。

version: '3'
services:
    db:
        build:
            context: .
            dockerfile: ./docker/db/Dockerfile
        container_name: b-db
        restart: unless-stopped
        volumes:     
            - dbdata:/data/db
        ports:
            - "27017:27017"
        networks:
            - app-network

    combined:
        build:
            context: .
            dockerfile: ./docker/combined/Dockerfile
        container_name: b-combined
        restart: unless-stopped
        env_file: .env
        ports:
            - "5000:5000"
            - "8080:8080"
        networks:
            - app-network
        depends_on:
            - db

以下是我将使用的 docker-compose 命令。

docker-compose up --build

我希望我的 Jenkins 代理成为 combined 容器;但是,我需要 combined 容器连接到我的 db 容器,该容器需要启动。我的问题是,我如何在 Jenkins 管道中实现这一点?我读过this documentation;但是,它没有提及使用多个 Dockerfile 来创建 Jenkins 代理。这样的事情可能吗?有人可以告诉我为了实现我的目标我的 Jenkinsfile 应该是什么样子吗?

【问题讨论】:

  • 至于 2021 年第三季度,这通常是不可能的。另一种方法是使用 kubernetes,其中代理是具有多个容器的 pod。

标签: docker jenkins docker-compose jenkins-pipeline dockerfile


【解决方案1】:

【讨论】:

    【解决方案2】:

    我不认为你可以在并行构建之间进行通信,问题是,在 Jenkinsfile 上的不同 parallel 阶段运行的阶段理论上可以在不同的 Jenkins 从站上运行,因此无法相互通信.

    我建议做的是使用& 在同一阶段并行运行服务器和前端应用程序,然后调用wait 以等待所有进程退出。

    您甚至可以放弃在 Jenkinsfile 中使用 docker 关键字,而是在舞台本身内部调用 docker。

    【讨论】:

    • 感谢您的回复!我认为对于并行构建可能存在一些误解。我不介意并行构建是否无法相互通信。我只想拥有一个由combineddb 组成的代理。在这个阶段,我只想模拟赛普拉斯提供的 Jenkinsfile 示例,以在我的应用程序上测试并行构建。
    猜你喜欢
    • 2018-06-21
    • 2018-03-13
    • 2017-12-20
    • 2020-07-19
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    相关资源
    最近更新 更多