How to run docker container inside docker (DIND)? - docker

I am trying to run a container inside another container using Docker inside docker https://hub.docker.com/_/docker.
When I run the following:
docker run --privileged docker:stable-dind docker run hello-world
I get the following error message:
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.
I must be missing something, how can I run docker inside docker?

I don't think you can do this in a one-liner (others might correct me). However, as explained at hub.docker.com/_/docker/, you can start the a docker-in-docker container as a background daemon (-d) and then start other containers inside.
To start the parent container, run
docker run -d --name some-docker --privileged docker:stable-dind
The name some-docker is arbitrary. It will be used to identify this container later on. To start a container inside, run
docker run --link some-docker:docker docker run hello-world
The --link option exposes the network ports of the parent container and sets environment variables, such that the inner container uses docker from the dind image.

Related

Why does 'docker stop CONTAINERID' also removes my stopped container?

If I run docker stop CONTAINERID, docker also deletes my stopped container, so I cannot restart it afterwards. Is there a way to avoid that?
As a note, I ran the container doing docker run --rm -dit --name somename someimages:v1.2.3 and Docker version is 20.10.
From the docker documentation for run you can read:
By default a container’s file system persists even after the container exits. This makes debugging a lot easier (since you can inspect the final state) and you retain all your data by default. But if you are running short-term foreground processes, these container file systems can really pile up. If instead you’d like Docker to automatically clean up the container and remove the file system when the container exits, you can add the --rm flag:
So run the container without --rm
Remove --rm from your docker run command because of --rm argument docker is removing your container when you stop your container.
Correct Docker run command -
docker run -dit --name somename someimages:v1.2.3

What is the difference between "docker run -it" versus docker run without --detach?

I heard that in case of no --detach in docker run option my terminal is attach to the container, is it this the same as attaching terminal with docker run -it options? What is the difference?
You can start a docker container in detached mode with a -d option. So the container starts up and run in background. That means, you start up the container and could use the console after startup for other commands.
This example runs a container named test using the debian:latest image. The -it instructs Docker to allocate a pseudo-TTY connected to the container’s stdin; creating an interactive bash shell in the container.
docker run --name test -it debian

jenkins in docker - Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

I'm running https://hub.docker.com/r/jenkinsci/blueocean/ in docker. Trying to build a docker image in jenkins.
but i get the following error:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
clearly the jenkins version in docker does not have access to the docker binary.
I confirmed this by,
docker exec -it db4292380977 bash
docker images
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
"db4292380977" is the running container. It shows the same error.
Question:
how do I allow access to docker in the jenkins container?
The docker client is installed on the jenkinsci/blueocean image, but not the daemon. Docker client will use the daemon (by default via the socket unix:///var/run/docker.sock). Docker client needs a Docker daemon in order to work, you can read Docker Architecture for more info.
What you can do:
Use docker-in-docker (DinD) image
Library Docker image provides a way to run a Docker daemon in Docker, you can then use it from another container. For example, using plain docker CLI:
docker run --name docker-dind --privileged -d docker:stable-dind
docker run --name jenkins --link=docker-dind -d jenkinsci/blueocean
docker exec jenkins docker -H docker-dind images
REPOSITORY TAG IMAGE ID CREATED SIZE
Docker daemon runs in docker-dind container and can be reached using the same hostname. You just need to provide the docker client with the daemon host (-H docker-dind in the example, you can also use DOCKER_HOST env variable as described in the doc).
Mount host machine /var/run/docker.sock in your container
As described by #Herman Garcia answer:
docker run -p 8080:8080 --user root \
-v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
You need to mount your local /var/run/docker.sock and run the container as root user
NOTE: this might be a security flaw so be careful who has access to the jenkins container
docker run -p 8080:8080 --user root \
-v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
you will be able to execute docker inside the container
➜ ~ docker exec -it gracious_agnesi bash
bash-4.4# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
c4dc85b0d88c jenkinsci/blueocean "/sbin/tini -- /usr/…" 18 seconds ago Up 16 seconds 0.0.0.0:8080->8080/tcp, 50000
/tcp gracious_agnesi
Just only try to do the same command but with sudo in the beginning
For example
sudo docker images
sudo docker exec -it db4292380977 bash
To avoid use sudo in the future you should run this command in Unix O.S
sudo usermod -aG docker <your-user>
Change for the user that you are using at this moment. Remember to log out and back in for this to take effect! More information about Docker installation click here

Share a volume between containers with DinD

I have a GitLab CI job that is currently using DinD. The CI runs inside a docker container.
What I am trying to accomplish is:
The CI job docker container, using dind, runs a docker container with a volume.
docker run --name cvmfs --pid=host --user 0 --privileged --restart always -v /cvmfsmounts:/cvmfsmounts:rshared <our_registry>/vcs/cvmfs-automounter:master
The CI job docker container runs another docker container using the same volume.
docker run --rm -v /cvmfsmounts/cvmfs:/cvmfs:rslave busybox ls -lrt /cvmfs/atlas.cern.ch
This is trying to automount a volume on the second docker container. It works when not using dind.
The main issue is this:
Error response from daemon: linux mounts: path /cvmfsmounts is mounted on / but it is not a shared mount
Any idea what is wrong with it?

Official Docker image says docker not running?

I perform the following docker commands in the following order:
docker pull docker
docker run -ti <imgId>
https://hub.docker.com/_/docker/
Now I am inside the "docker" image for Docker
Now suppose I create a temp folder and download a Dockerfile
mkdir temp
cd temp
curl <dockerfile>
docker build .
It will tell me Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
This means that the docker service needs to be started, but as the official docker image comes on alpine linux, commands like service/systemctl are not available, so we must perform apk add openrc --no-cache to access these.
After I install it, I still cannot start the docker service.
Performing system docker start says that it cannot find docker as a service?
service: service docker does not exist
Eventually I want to build this via Jenkins.
In the build step, I perform Execute Shell
if [ -f "Dockerfile" ]; then
echo "Dockerfile exists ... removing it"
rm Dockerfile
fi
wget <dockerFile url>
docker build .
I purposely don't do the openrc on Jenkins since I want to test locally first
The image you're pulling here (with the latest tag) does not contain the docker daemon. It's meant to be used as the docker client. What you want is to first get the docker daemon running with the image tagged dind (docker in docker).
docker network create dind
docker run --privileged --name docker --network dind -v docker-client-certs:/certs/client -d docker:dind
To verify it started up and works, you can check the logs.
docker logs docker
Now you can use a client container to connect to the daemon. This is how you connect interactively to the shell, like you wanted to:
docker run -ti --network dind -e DOCKER_TLS_CERTDIR=/certs -v docker-client-certs:/certs/client:ro docker
Docker commands should work inside this container. If you do docker version, you should see the versions of both the client and the server.
Note the two containers share the same network (some examples online feature links, but those are deprecated). They also share some of the TLS certs, which are generated when starting up the dind image.

Resources