I am new to docker. I just tried to use docker in my local machine(Ubuntu 16.04) with Jenkins.
I configured a new job with below pipeline script.
often need a reboot to take effect on the new user group and user.
2019-05-26
This worked for me !
Example docker-compose:
version: "3"
services:
jenkins:
image: jenkinsci/blueocean
privileged: true
ports:
- "8080:8080"
volumes:
- $HOME/learning/jenkins/jenkins_home:/var/jenkins_home
environment:
- DOCKER_HOST=tcp://socat:2375
links:
- socat
socat:
image: bpack/socat
command: TCP4-LISTEN:2375,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
expose:
- "2375"
Simply adding docker
as a supplementary group for the jenkins
user
sudo usermod -a -G docker jenkins
is not always enough when using a Docker image as the Jenkins Agent. That is, if your Jenkinsfile
starts with pipeline{agent{dockerfile
or pipeline{agent{image
:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
}
}
stages {
This is because Jenkins performs a docker run command, which results in three problems.
docker run
does not do a login to the container (it's more like a sudo
).Making the Docker programs available within the Docker image simply requires running the Docker installation steps in your Dockerfile:
# Dockerfile.jenkinsAgent
FROM debian:stretch-backports
# Install Docker in the image, which adds a docker group
RUN apt-get -y update && \
apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
RUN apt-get -y update && \
apt-get -y install \
docker-ce \
docker-ce-cli \
containerd.io
...
As has been said before, fixing the second problem means running the Jenkins Docker container so it shares the Docker daemon socket with the Docker daemon that is outside the container. So you need to tell Jenkins to run the Docker container with that sharing, thus:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
args '-v /var/run/docker.sock:/var/run/docker.sock'
}
}
The ideal fix to the third problem would be set up supplementary groups for the Agent. That does not seem possible. The only fix I'm aware of is to run the Agent with the Jenkins UID and the Docker GID (the socket has group write permission and is owned by root.docker
). But in general, you do not know what those IDs are (they were allocated when the useradd ... jenkins
and groupadd ... docker
ran when Jenkins and Docker were installed on the host). And you can not simply tell Jenkins to user user jenkins
and group docker
args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'
because that tells Docker to use the user and group that are named jenkins
and docker
within the image, and your Docker image probably does not have the jenkins
user and group, and even if it did there would be no guarantee it would have the same UID and GID as the host, and there is similarly no guarantee that the docker
GID is the same
Fortunately, Jenkins runs the docker build
command for your Dockerfile in a script, so you can do some shell-script magic to pass through that information as Docker build arguments:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
additionalBuildArgs '--build-arg JENKINSUID=`id -u jenkins` --build-arg JENKINSGID=`id -g jenkins` --build-arg DOCKERGID=`stat -c %g /var/run/docker.sock`'
args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'
}
}
That uses the id
command to get the UID and GID of the jenkins
user and the stat command to get information about the Docker socket.
Your Dockerfile can use that information to setup a jenkins
user and docker
group for the Agent, using groupadd, groupmod and useradd:
# Dockerfile.jenkinsAgent
FROM debian:stretch-backports
ARG JENKINSUID
ARG JENKINSGID
ARG DOCKERGID
...
# Install Docker in the image, which adds a docker group
RUN apt-get -y update && \
apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
RUN apt-get -y update && \
apt-get -y install \
docker-ce \
docker-ce-cli \
containerd.io
...
# Setup users and groups
RUN groupadd -g ${JENKINSGID} jenkins
RUN groupmod -g ${DOCKERGID} docker
RUN useradd -c "Jenkins user" -g ${JENKINSGID} -G ${DOCKERGID} -M -N -u ${JENKINSUID} jenkins
On the server where Jenkins is running, I used
sudo setfacl -m user:tomcat:rw /var/run/docker.sock
And then run each docker container with
-v /var/run/docker.sock:/var/run/docker.sock
Using setfacl seems a better option, and no "-u user" is needed. The containers then run as the same user that is running Jenkins. But I would appreciate any feedback from the security experts.
Change the access permission of the docker.sock file
chmod 777 /var/run/docker.sock
or u can use sudo
in the start of the command.
chmod 777
will allow all actions for all users while chmod 666
will allow all users to read and write but cannot execute the file.
Step 1: add your username to the docker
group:
sudo usermod -a -G docker $USER
Then logout and login again.
Step 2: Then change docker group ID :
newgrp docker