One thing really missing from everywhere is a way to run Jenkins on Docker with Docker agents and Testcontainers. It's not as easy as it seems!
* Docker will be exposed on the Jenkins master network via a Socat ("""proxy""") image
* The build nodes will be created dynamically on request
* The build could use Testcontainers out of the box
* Docker will not be exposed to the outside world!
* No need for privileged containers or weird CAPs
*
The stack
Let's first create the stack with docker compose
version: '3.8'
networks:
jenkins:
driver: bridge
services:
jenkins:
networks:
- jenkins
image: jenkins/jenkins:lts
user: root
environment:
- DOCKER_HOST=tcp://socket-proxy:2375
ports:
- 8011:8080
- 50000:50000
container_name: jenkins
volumes:
- jenkins_home:/var/jenkins_home
socket-proxy:
image: alpine/socat
container_name: socket-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
- jenkins
command: Tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
volumes:
jenkins_home:
The whole server is based on the exposure of the docker deamon inside the jenkins network through the socat image that act as a proxy for port 2375 to the local docker.
Jenkins server
Now you can
* Get the logs of jenkins -container- and the temporary password and login
- Install the suggested plugins
- Login and go to [Dashboard]>[Manage Jenkins]>[Plugins]>[Available Plugins]
- Enable it and check the enable [Expose DOCKER_HOST]
- Click on [Docker Agent Template]
- Labels and Name: dockeragent
- Docker Image: jenkins/agent:jdk11 (this is the jdk needed to run the agent)
- Remote File System Root: /home/jenkins/agent
- Connect Method: Attach Docker Container
- Java Executable: /opt/java/openjdk/bin/java
- In [Container Settings] set the network to "jenkins_jenkins" (this is the network where all agents and testcontainers will live)
- Then in [Node Properties] add some environment variables
- DOCKER_HOST=tcp://socket-proxy:2375 (this to tell how to interact with the newly created containers
- DOCKERTLSVERIFY=0
- TESTCONTAINERSHOSTOVERRIDE=[your docker machine IP] (to tell where to find the new docker instances
- TESTCONTAINERSRYUKDISABLED=true (to avoid creating the ryuk container, it does cleanup after the tests but is not strictly needed since the cleanup is already in place. The problem is that you can't set the network for this thus is always unreachable)
Java/Maven configuration
- Go to [Dashboard]>[Manage Jenkins]>[Tools]->[JDK Installations]->Add Jdk
- Name it (we are working on 11) jdk11
- Click on [Install Automatically] then [Add Installer] and [Install from adoptium.net]
- And select the most recent jdk 11 version
- Go to [Maven Installations]->Add Macen
- Name it maven399
- Click on [Install Automatically] then [Add Installer] and [Install from apache]
- And select the most recent jdk 11 version
- Go to [Dashboard]>[Manage Jenkins]>[Tools]->[JDK Installations] Add Jdk
- And select maven 3.9.9
Simple build with docker!
- Go to [Dashboard]>[+ New Item]
- Create a new build named Test Build of type "Freestyle Project"
- Go on [Build Steps]>[Add build step]>[Execute shell]
- Enter the build script (just an hello for now!)
echo "build done"
- Save everything,
- Then [Build Now]
And here is the build result!
Running a Testcontainer based project
Now to run the standard testcontainer Spring Boot example.
It runs on Jdk 17 so we have first to add the jdk
- Go to [Dashboard]>[Manage Jenkins]>[Tools]->[JDK Installations]->Add Jdk
- Name it (we are working on 17) jdk17
- Click on [Install Automatically] then [Add Installer] and [Install from adoptium.net]
- And select the most recent jdk 17 version
Then we can create a new build
- Go to [Dashboard]>[+ New Item]
- Create a new build named TescontainerBuild of type "Pipeline"
- Go the [Pipeline] Section and use "Pipeline script" as definition. This will be the Jenkinsfile used for the pipeline
- The agent will be our dynamic docker agent
- Tools will be maven 3.9.9 and Jdk17
- In the "Build" stage the repo will be checked out and maven will be run!
- With the post all artifacts will be listed in the build and the surefire reports run!
pipeline {
agent { label 'dockeragent'}
tools {
maven 'maven399'
jdk 'jdk17' }
stages {
stage('Build') {
steps {
git branch: 'main',
url:'https://github.com/testcontainers/testcontainers-java-spring-boot-quickstart.git'
sh "mvn package" } } }
post {
always {
archiveArtifacts artifacts: 'target/**/*.jar', fingerprint: true
junit 'target/surefire-reports/*.xml'
} } }
And here is the result, with the downloadable artifact and the progress of test results
Last modified on: September 20, 2024