问题
I am trying to build an docker image and start the container with docker-compose inside a Jenkins pipeline.
I have a custom docker image for my Jenkins where I use the Jenkins out of the box image and install Docker CE and docker compose.
The Dockerfile:
FROM jenkins/jenkins:2.159
USER root
# create dir to save jenkins log files
RUN mkdir /var/log/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins
########################################################################################################################
## install docker based on: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-debian-9
########################################################################################################################
RUN apt update
RUN apt -y install apt-transport-https ca-certificates curl gnupg2 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 update
# make sure you are about to install from the Docker repo instead of the default Debian repo
RUN apt-cache policy docker-ce
RUN apt -y install docker-ce
#RUN systemctl status docker
# give jenkins docker rights
RUN apt update
RUN apt-get install acl
#RUN ls /var/run
#RUN setfacl -m user:jenkins:rw /var/run/docker.sock
RUN usermod -aG docker jenkins
RUN gpasswd -a jenkins docker
################################################################################################################################
## install docker-compose based on: https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-debian-9
################################################################################################################################
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
RUN chmod +x /usr/local/bin/docker-compose
RUN docker-compose --version
USER jenkins
RUN id -nG
#tell jenkins to use the created folder to store logs
I build this image with docker-compose build
with this docker-compose file:
version: '3'
volumes:
jenkins-log:
jenkins-data:
networks:
jenkins-net:
services:
master:
build: ./jenkins-master
ports:
- "50000:50000"
volumes:
- jenkins-log:/var/log/jenkins
- jenkins-data:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
networks:
- jenkins-net
nginx:
build: ./jenkins-nginx
ports:
- "80:80"
networks:
- jenkins-net
And start it with docker-compose -p jenkins up -d
This starts Jenkins and works fine for now.
Then I create a Pipeline Job which uses the following Jenkinsfile:
node {
stage('Build Docker Image') {
sh '''
cd env-ci/
docker-compose --version
docker --version
docker-compose build
'''
}
}
When I run this pipeline I get the following error:
+ cd env-ci/
+ docker-compose --version
docker-compose version 1.22.0, build f46880fe
+ docker --version
Docker version 18.09.1, build 4c52b90
+ docker-compose build
Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
When I try to run docker info
within the pipeline:
node {
stage('Build Docker Image') {
sh '''
cd env-ci/
docker-compose --version
docker --version
docker info
'''
}
}
I get the following error:
+ cd env-ci/
+ docker-compose --version
docker-compose version 1.22.0, build f46880fe
+ docker --version
Docker version 18.09.1, build 4c52b90
+ docker info
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/info: dial unix /var/run/docker.sock: connect: permission denied
I am currently out of ideas what the issue might be or how I can resolve it.
The Jenkins pipeline is run as user jenkins
and this user is added to the docker group. So the permission should be fine?!
Does anyone have an idea what might be wrong? Thank you!
回答1:
Apperantly there is a problem with permissions since it is docker in docker. I could solve it with the following:
1) from the host system: connect to the running jenkins container as root
docker exec -u root -it <containerid> bin/bash
2) give the jenkins user the right to /var/run/docker.sock
chown jenkins:docker /var/run/docker.sock
Now I can run the pipeline with the Jenkinsfile successfully. But this does not really solve the problem since the chown step needs to be done after each image build.
Edit: The clean solution to solve this problem is to use a Jenkins Slave (worker) with a Docker Proxy. This is described in this turotial https://engineering.riotgames.com/news/building-jenkins-inside-ephemeral-docker-container
回答2:
People mostly face the issue Couldn't connect to Docker daemon
because they are not the member of docker
group and don't have permissions to read that file.
Running with sudo
docker will fix that, but this is not a proper solution.
Solution
Docker can be run as a non-root user (without sudo) that has the proper group permissions. The Linux post-install docs has the details.
Here is the short version:
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
# Log out and log back in again to apply the groups
$ groups # docker should be in the list of groups for your user
$ docker run hello-world # Works without sudo
This will grant permission to users in the docker
group to run docker
and docker-compose
commands without sudo
.
Give permission to the jenkins use:
chown jenkins:docker /var/run/docker.sock
来源:https://stackoverflow.com/questions/54232842/jenkins-pipeline-does-not-run-with-docker-compose-because-it-cant-connect-to-doc