I want to set up CICD with docker and Jenkins on Windows with Docker Desktop and run docker commands from the Jenkins container. As I understand it, one way to do that is to expose the hosts docker daemon through the socket
docker.sock to the Jenkins container. When I run the below
with the command
docker compose up -d --build in an Ubuntu VM with docker installed, the Jenkins container can run docker commands and everything seems to be working as intended. E.g. I can run
docker -v inside the docker container (no
sudo is needed).
But when I run the same
compose.yaml on my Windows (Windows 10 Pro, 19045.3693) laptop with Docker Desktop (4.25.2), the Jenkins container can’t run docker commands. When I run
docker -v inside the Jenkins container I get the error:
/bin/sh: 1: docker: not found
I have also installed
sudo in the Jenkins VM and run
sudo docker -v and get the error:
sudo: docker: command not found
More things I have tried is to use an extra slash
- //var/run/docker.sock:/var/run/docker.sock. I have tried using named pipes but I think that is only relevant if you want to run a Windows container. I have tried to also bind mount
Edit: I forgot
- /usr/bin/docker:/usr/bin/docker under volumes. This is needed for it to work in Ubuntu.
Edit: This post is about how to get it to work with Docker Desktop on Windows. All other posts doesn't mention Docker Desktop and seem to assume a Linux environment. Added clarification in first sentence. I don't think this question should be closed as it can illustrate the differences between e.g. Ubuntu VM and Docker Desktop.
The current jenkins/jenkins:lts image does not have docker client installed, you need to add it to an image and use it.
Interesting how and why your compose file works on ubuntu VM even though no docker cli installed in the container running from jenkins/jenkins:lts. Maybe previous jenkins/jenkins:lts image had it, and your docker engine on the ubuntu VM still has it and that is what used in your VM? This is why you should never use latest, lts, etc running tags/versions because the underlying software can and will change over time, you should pin your version like jenkins/jenkis:1.2.3-debian or something like this.
Anyways, this works on my Windows 10 machine with Docker Desktop for Windows:
Create this Dockerfile:
# Install Docker client cli
RUN apt-get update && \
apt-get -y install \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
apt-key fingerprint 0EBFCD88 && \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce-cli
# create docker group
RUN groupadd -g 1001 docker
# add jenkins user to docker group
RUN usermod -aG docker jenkins
!!!Important!!! You must use the same GUID for docker group in
RUN groupadd -g 1001 docker command as it is on the wsl distro that you enabled the Docker Desktop WSL2 integration with and from where you issue your commands (docker build, docker run, etc). You can check the GUID on the wsl2 distro with
getent group docker, for me it is 1001.
Note: Docker engine, the server, itself is not running in this wsl2 distro but rather it has it's own separate wsl2 distros with names docker-desktop and docker-desktop-data. You connect to this docker engine server with the docker client, the docker cli command.
Build the image:
docker build -f Dockerfile -t myjenkins:1.0.0-docker-cli .
Run the container from the image from the wsl2 distro shell that you enabled Docker Desktop integration with:
docker run -v /var/run/docker.sock:/var/run/docker.sock --rm -it myjenkins:1.0.0.-docker-cli sh
docker ps in the container shell and you will see your containers running on the host, including the container that you are currently inside.
Be aware that granting this kind of access to the container gives the jenkins user root level access on the host: https://docs.docker.com/engine/security/#docker-daemon-attack-surface