I was studying jpetazzo’s docker-in-docker (dind) to manage Jenkins builds, annoyed by the fact that I wasn’s able to separate the build engine from my build artifacts.
While digging deeper I’ve found the two alternative options (read this):
- installing the Docker CLI using your base image’s packaging system (i.e. if your image is based on Debian, use .deb packages)
- using the Docker API
So I decided for the third option … 😎
Communicate with your host’s docker daemon through the docker API using docker-compose inside your jenkins image.
Remember that to make it works you have to bind the docker.sock file from-in-to-out (-v /var/run/docker.sock:/var/run/docker.sock)
Install docker-ce and docker-compose on your host
Create a folder that will contain the dockerized jenkins (server) stuff in your home (if you change this path please fix the following docker run command):
mkdir -p $HOME/jenkins/jenkins_home
Into jenkins/ create a Dockerfile that extends the jenkins/jenkins image and downloads+install the docker-compose executable:
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
Finally you can run the built image, with some trick: run as a daemon, expose needed ports, mount a named volume for jenkins stuff (to save state) and share the docker.sock
docker run -it -d --name jenkins_docker -p 8080:8080 -p 50000:50000 -v $HOME/jenkins/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkins-docker
Or, if you prefer using compose:
version: '3' services: jenkins: image: jenkins-docker build: . ports: - "8080:8080" - "50000:50000" volumes: - $HOME/jenkins/jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock
Now, after configuring the first jenkins run, you are able to build your 1st pipeline.
As a test, you can enter the running image:
docker exec -it -u root jenkins-docker bash
and manually launch a build of a docker image using compose.
It will communicate through the container-host binding and the image will be built into our host.