visit
Attention!: You can read the original article here //carltheperson.com/posts/jenkins-in-docker-and-tests-inside-own-container/
The code formatting is much better there
Why run Jenkins in a Docker container?
Having your Jenkins setup containerized makes it portable and quick to set up. Whether you are running Mac, Windows or Linux running Jenkins inside Docker is easy and straightforward.
Why run my project in a Docker container within Jenkins?
This is definitely not always necessary but can be an advantage if you want to specify your exact testing situation.
Here we are going to need Docker to be installed inside our Jenkins container, so we create a Dockerfile that builds on top of the official Jenkins image. Put this in a file called
Dockerfile_jenkins_setup
FROM jenkins/jenkins:lts
USER root
RUN apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common && \
curl -fsSL //download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] //download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce
RUN apt-get install -y docker-ce
RUN usermod -a -G docker jenkins
USER jenkins
Building the image:
docker build -f DockerfileJenkinsSetup -t gustavoapolinario/jenkins-docker .
Running the container:
docker run -d -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/jenkins_home:/var/jenkins_home \ # Optional
--name Jenkins_Docker gustavoapolinario/jenkins-docker
# One line:
docker run -d -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock -v /var/jenkins_home:/var/jenkins_home --name Jenkins_Docker gustavoapolinario/jenkins-docker
Now visit localhost:8080
Jenkins will ask you for a password. You can retrieve it by running:docker exec Jenkins_Docker cat /var/jenkins_home/secrets/initialAdminPassword
For this project I have created a very simple Node app. You can find the full source code at:
I have also written a simple test using Mocha and Chai. The test just tests if the app returns with status 200. I test my app using
npm test
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.status(200);
res.send("Cool beans");
});
app.listen(port, () => {
console.log(`App is up and listening on port ${port}`);
});
module.exports = app;
FROM node:latest
ENV PROJECTDIR /nodeApp
WORKDIR $PROJECTDIR
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Here is the Jenkinsfile I am using. It will build an image from the files in the Git repository using our Dockerfile. It will then enter the image and extract the
PROJECTDIR
environment variable that we defined earlier. Then it copies everything from that directory into our workspace. This is not always necessary, and we could just run the tests directly with the files from the repository, but I like doing it because the project directory might look different depending on what you specified in your Dockerfile.pipeline {
environment {
// This registry is important for removing the image after the tests
registry = "yourname/nodeapp"
}
agent any
stages {
stage("Test") {
steps {
script {
// Building the Docker image
dockerImage = docker.build registry + ":$BUILD_NUMBER"
try {
dockerImage.inside() {
// Extracting the PROJECTDIR environment variable from inside the container
def PROJECTDIR = sh(script: 'echo \$PROJECTDIR', returnStdout: true).trim()
// Copying the project into our workspace
sh "cp -r '$PROJECTDIR' '$WORKSPACE'"
// Running the tests inside the new directory
dir("$WORKSPACE$PROJECTDIR") {
sh "npm test"
}
}
} finally {
// Removing the docker image
sh "docker rmi $registry:$BUILD_NUMBER"
}
}
}
}
}
}
We can now try building our app (just select your item and click build) and it should fail or succeed depending on if the tests we’ve written pass.
If something unexpected happens you can click on the build and look at the console output. This should give you a clue as to what happened.
If your build fails saying something like “Got permission denied while trying to connect to the Docker daemon socket”, then the GID of the Docker group in the container does not match the one on your machine (some problems with permissions). What worked for me on Ubuntu was:
docker exec --user root Jenkins_Docker groupmod -g `cut -d: -f3 < <(getent group docker)` docker
docker restart Jenkins_Docker