49

I'm looking for a way to run Docker-enabled build consisting of multiple containers in Jenkins 2.0.

Are there any plans for native support of Docker Compose in Pipeline, or through CloudBees docker plugins for pipeline.

Or can/must this be addressed by explicit calls sh docker-compose...? Maybe even use them inside try... finally to further control services lifecycle.


EDIT: The first answer was to suggest a way to build docker containers in jenkins. This is not what is needed here. I (EngineerDollery) want to bring up my target platform in jenkins using compose so that I can deploy my app to it and run end-to-end tests.

StephenKing
  • 36,187
  • 11
  • 83
  • 112
luka5z
  • 7,525
  • 6
  • 29
  • 52
  • I was able to use docker compose by running a shell scripts, I'm not sure if it can be used in a pipeline but if you can run shell scripts in a pipeline then it shouldn't be a problem. – Rogério Peixoto Aug 04 '16 at 13:17
  • 3
    Unfortunately I've also finally came with a solution which includes running `docker compose` from `sh` step, embedding it inside `try...finally` clause for lifecycle control. **At this moment there is no support for `docker-compose` from Jenkins plug-ins eco-system**. However I will keep a close eye on an official [CloudBees Docker Pipeline Plugin](https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Pipeline+Plugin) and rather experimental [Docker Slaves Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Docker+Slaves+Plugin). – luka5z Aug 06 '16 at 21:04
  • [Docker will be unhappy](https://stackoverflow.com/questions/55653747/using-testcontainers-in-a-jenkins-docker-agent-containers-fail-to-start-norout) if you run Docker compose in a Jenkins pipeline, and your are using Docker Jenkins Agents, and (as is likely) your Docker compose tries to create a Docker bridge network. – Raedwald Apr 12 '19 at 15:07

4 Answers4

18

After searching in Jenkins bug tracking, JENKINS-35025 suggests docker-compose.yml is taken into account when running a job in a docker container, using a maven build.

See also Creating CI pipeline with Jenkins, which assumes docker-compose is installed on your Jenkins server.

Note: a year later (August 2017), docker-compose is still not supported in the Docker Pipeline plugin

July 2018, Ivan Aracki notes in the comments:

Manually installing docker-cli and docker-compose with the same version as host's is the solution for now...

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
3

Here are the files to run a jenkins container that runs docker inside:

docker run \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  getintodevops/jenkins-withdocker:lts

reference: https://getintodevops.com/blog/the-simple-way-to-run-docker-in-docker-for-ci

Julio Marins
  • 10,039
  • 8
  • 48
  • 54
2

I am facing a similar problem, I found this https://reinout.vanrees.org/weblog/2017/10/03/docker-compose-in-jenkins.html but I do not know what is related to.

My problem is test while developing, and also automate the test in Jenkins, and I am using docker-compose to bring up some php scripts AND a mysql server, to run isolated tests (phpunit as of now).

I could think I can achieve this by

  1. creating a network in docker host (with docker network create)
  2. create and run a mysql docker attached to that network (with docker run mysql --network=netname --name=mysqlmachine
  3. run scripts by jenkins specifying --network and refering to mysqlmachine as host.

But this would means I need to setup db data, cleanup db data, and also leave always on the mysqlmachine even when not needed, consuming some ram resource. I can solve last problem with docker start mysqlmachine and docker stop mysqlmachine command in my Jenkinsfile defining the pipeline.

But, again, executing a shell into the docker where jenkins is running I can not find docker command

For me is a viable solution untill I can not find something better

UPDATE: I will try the https://wiki.jenkins.io/display/JENKINS/Docker+Slaves+Plugin solution, it has almost what I need

UPDATE 08.02: as suggest by Alexander Zeitler, using

agent {
        docker {
            image 'pdmlab/jenkins-node-docker-agent:6.11.1'
            args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
    }

in Jenkins file allow the use of docker-compose command: docker inside a docker, that is mostly docker near a docker as detailed here: Docker in Docker - volumes not working: Full of files in 1st level container, empty in 2nd tier

But I preferred to use another approach, that does not require to run jenkins in a special way.

The pipeline say:

stage('Test') {
    steps {
        sh './build_docker.sh jenkinstests'
    }
}

and build_docker.sh does:

 jenkinstests)
 docker volume create idealodbconn
 docker run -v idealodbconn:/data --name helper busybox true
 docker cp ./dbconn/db249.json helper:/data
 docker rm helper

 docker-compose -f services/docker-compose-jenkins.yml up \
 --abort-on-container-exit \
 --exit-code-from idealoifapi

 docker-compose -f services/docker-compose-jenkins.yml rm -f
 docker volume rm idealodbconn
 ;;

Also here --abort-on-container-exit say to exit once one container defined into docker-compose-jenkins.yml exits, and --exit-code-from idealoifapi says to take exit code from idealoifapi image.

That is all. Missing part, maybe, is the docker-compose-jenkins.yml use of volume, it is external: true:

volumes:
    idealodbconn:
        external: true
Daniele Cruciani
  • 623
  • 1
  • 8
  • 15
  • Really I still have to test it, pm and customer demands changed task priorities, I was coming back to this 2 days ago, but again I am in another task now. I will know it. But it looks complex, because I need to define a Dockerfile to build, and normally jenkins pipeline expect a Dockerfile (or image) to build from. So I think I should first move code and files (also the jenkins pipeline file) into the container built by Docker Slave and then execute pipeline there with the support of side container. – Daniele Cruciani Jul 11 '18 at 13:43
  • 3
    I tried it and it doesn't look like the plugin does install `docker-compose`. I solved it creating an image containing Node.js, Docker and Docker Compose. This image is referenced in `agent` in `Jenkinsfile`. Due to Docker in Docker Volume Mappings don't work as expected but the solution is described here: https://stackoverflow.com/questions/49312100/docker-in-docker-volumes-not-working-full-of-files-in-1st-level-container-em This is the Dockerfile: https://github.com/PDMLab/jenkins-node-docker-agent – Alexander Zeitler Jul 11 '18 at 13:58
  • on volume mounting I do not like the undestand-by-misunderstood approach like that. Instead I create a symbolic volume, copy file into it, run the tests, then remove the volume as suggested here https://stackoverflow.com/questions/37468788/what-is-the-right-way-to-add-data-to-an-existing-named-volume-in-docker this solution does not require a special setup of jenkins, it is all managed by the docker api, communicating via socket, so it is more general. I update the answer with details – Daniele Cruciani Aug 02 '18 at 20:40
2

I got docker-compose working in Jenkins pipelines using Nestybox, as described in their blog post. I built my Jenkins installation itself using the following Dockerfile:

FROM nestybox/jenkins-syscont:latest
# Install docker-compose
RUN curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose \ 
&& chmod +x /usr/local/bin/docker-compose

With that I simply followed the instructions in the blog post and can run pipelines that look something like this:

pipeline {

   agent any

   stages {
       stage('docker-compose') {
           steps {
              sh "docker-compose build"
              sh "docker-compose up -d"
              ...
           }
       }
   }
   post {
      always {
         sh "docker-compose down || true"
      }
   }   
}
Yoni Rabinovitch
  • 5,171
  • 1
  • 23
  • 34