dockerjenkinsjenkins-pipelinejenkins-docker

Jenkins scripted pipeline with sidecar MYSQL container for testing


I have the below pipeline that would run the actual container along side with MYSQL container to run test.

stage('Test - To check MYSQL connect') { 
        def dockerfile = 'Dockerfile.test'
        def mysql = docker.image('mysql:5.6').run('-e MYSQL_ALLOW_EMPTY_PASSWORD=yes')
        docker.build("rds-test", "-f ${dockerfile} .")
        def rds_test_image = docker.image('rds-test')
        rds_test_image.inside("--link ${mysql.id}:mysql "){
            sh 'echo "Inside Container"'
        }
    }

And i am stuck with the below error

Successfully tagged rds-test:latest
[Pipeline] isUnix
[Pipeline] sh
+ docker inspect -f . rds-test
.
[Pipeline] withDockerContainer
Jenkins seems to be running inside container d4e0934157d5eb6a9edadef31413d0da44e0e3eaacbb1719fc8d47fbf0a60a2b
$ docker run -t -d -u 1000:1000 --link d14340adbef9c95483d0369857dd000edf1b986e9df452b8faaf907fe9e89bf2:mysql -w /var/jenkins_home/workspace/test-jenkinsfile-s3-rds-backup --volumes-from d4e0934157d5eb6a9edadef31413d0da44e0e3eaacbb1719fc8d47fbf0a60a2b -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** rds-test cat
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.io.IOException: Failed to run image 'rds-test'. Error: docker: Error response from daemon: Cannot link to a non running container: /sharp_sanderson AS /fervent_lewin/mysql.

Just in case you want to look at the rds-test dockerfile https://github.com/epynic/rds-mysql-s3-backup/tree/feature


Solution

  • The id of the running container will not be captured in the return of the run method, but rather is stored in the temporary lambda variable of the withRun block. To leverage this capability, we would modify your code accordingly:

    stage('Test - To check MYSQL connect') { 
      def dockerfile = 'Dockerfile.test'
      docker.build("rds-test", "-f ${dockerfile} .")
      def rds_test_image = docker.image('rds-test')
    
      docker.image('mysql:5.6').withRun('-e MYSQL_ALLOW_EMPTY_PASSWORD=yes') { container ->
        rds_test_image.inside("--link ${container.id}:mysql") {
          sh 'echo "Inside Container"'
        }
      }
    }
    

    As you can see above, running your second container within the code block of the other container's withRun makes the container id accessible within the id member variable of the temporary lambda variable initialized within the block (named container here for convenience).

    Note that you can also do a slight code cleanup here by assigning the value of rds_test_image to the return of docker.build("rds-test", "-f ${dockerfile} .") instead of adding another line of code assigning it to the return of docker.image('rds-test'). The new code would also be more stable.