title: How to use multiple Docker containers to set up Jenkins agent in Jenkins pipeline
body: <p>The following snippet is an example provided by Cypress, a Javascript testing framework that I'm using. Here is the <a href="https://github.com/cypress-io/cypress-example-kitchensink/blob/master/Jenkinsfile" rel="nofollow noreferrer">link</a> to the Github page.</p>
  
  <pre><code>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 &amp;'
        }
      }
  
      // 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'
      }
    }
  }
  </code></pre>
  
  <p>My goal is to have a Jenkinsfile that is very similar to the above because I want to have parallel Cypress testing as shown in the above snippet. In the example above, the Jenkins agent is simply the official Cypress Docker image <code>cypress/base:10</code>.</p>
  
  <pre><code>  agent {
      // this image provides everything needed to run Cypress
      docker {
        image 'cypress/base:10'
      }
    }
  </code></pre>
  
  <p>However, for me to run all my tests with my own database, I need to spin up two separate Docker containers. One container contains the front-end portion of my web app and the other container contains the back-end portion of my web app.</p>
  
  <p>Below is the Dockerfile for my front-end container, which is located in <code>my-app/docker/combined/Dockerfile</code>.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Below is the Dockerfile for my back-end container, which is located in <code>my-app/docker/db/Dockerfile</code>. All it is doing is copying some local data into the Docker container and then initialising my MongoDB database with this data.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Usually, I would use <code>docker-compose</code> and the following <code>docker-compose.yml</code> file to spin up these two containers. As you can see, the front-end container called "combined" is dependent on the back-end container called "db".</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Below is the docker-compose command I would use.</p>
  
  <pre><code>docker-compose up --build
  </code></pre>
  
  <p><strong>I would like my Jenkins agent to be the <code>combined</code> container; however, I need the <code>combined</code> container to connect to my <code>db</code> container, which needs to be spun up. My question is, how do I achieve this in Jenkins pipelines? I've read <a href="https://jenkins.io/doc/book/pipeline/syntax/" rel="nofollow noreferrer">this documentation</a>; however, it doesn't mention anything about using multiple Dockerfiles to create a Jenkins agent. Is something like this possible and could someone please show me what my Jenkinsfile should look like in order to achieve my goal?</strong></p>