简体   繁体   中英

Cannot connect to the Docker daemon without -v /var/run/docker.sock:/var/run/docker.sock

I am trying to run docker inside docker container and container have nodeJs App.

Here is my Dockerfile :

FROM docker:dind   
WORKDIR /app  
RUN apk add --update nodejs nodejs-npm  
COPY . /app  
RUN npm install  
CMD node app.js  
EXPOSE 4000

I built docker image (newdockerimage) using above Dockerfile and creating container using docker run -d --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker newdockerimage .

I am able to install docker inside container but all the docker images which are on host system is also sharing inside container because of volume ( /var/run/docker.sock ) .

If I dont use volume -v /var/run/docker.sock:/var/run/docker.sock while running container, I am getting below error:- Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? Because container will be node app (since that is entrypoint),so overriding docker:dind entrypoint

Please help me ! How can I run docker inside container without sharing volume (without copying docker images of host system)

When you override the default CMD of Docker-dind by node app.js then it will not start Docker service. so as a result you will get

Cannot connect to the Docker daemon

Because docker is not running in your container.

So the workaround is to start docker in the background and your node application in foreground.

FROM docker:dind   
WORKDIR /app  
RUN apk add --update nodejs nodejs-npm  
COPY app.js /app  
RUN npm install express
CMD nohup dockerd &> output & sleep 1 && node app.js  
EXPOSE 4000

Build the image and start the container like

docker run -it --privileged --name test --rm my-docker-dind

在此处输入图像描述

Running Docker inside a Docker container is technically possible, but generally disrecommended. The Docker Hub description for the docker image has a lot of documentation and it's important to read through it. I also wouldn't usually consider it a best practice to access the Docker socket from inside a container unless it's absolutely necessary, and as a general rule you shouldn't be trying to run two programs in a single image. I would strongly consider taking some other approach to your higher-level problem: this is neither a standard nor a straightforward setup.

There are two ways to access the DinD socket. It publishes it via TCP-over-TLS on port 2376, or if you run a container inside the nested Docker, "the host system" for purposes of bind mounts is the DinD container.

(But wait: isn't network HTTP access to the Docker socket a security disaster? There are two mitigations here: since it's inside the host Docker, there's a layer of NAT/firewall and you can't access that nested Docker socket unless you publish it; and while you can use it to get unrestricted root access, it's only over the nested DinD container and its contents.)

The first thing you should do is rewrite your Dockerfile to be a standard Node image. It should not extend the docker image, because it's not a Docker image, it's a Node-application image.

FROM node:12
WORKDIR /app
COPY . .
RUN npm install
CMD node app.js
EXPOSE 4000

Start DinD, as a separate container:

mkdir certs
docker network create myapp
docker run \
  --privileged \
  --net myapp \
  --name docker
  -e DOCKER_TLS_CERTDIR=/certs \
  -v $PWD/certs:/certs \
  -d \
  docker:dind

Now you can either start a container on the host Docker, and give it a pointer to the nested Docker

docker build -t myapp .
docker run
  --net myapp \
  --name myapp \
  -e DOCKER_HOST=tcp://docker:2376 \
  -e DOCKER_TLS_VERIFY=1 \
  -e DOCKER_CERT_PATH=/certs \
  -v $PWD/certs/client:/certs \
  myapp

Or, you can run this container inside the DinD setup.

# Add to the `docker run ... docker:dind` startup
# -p 127.0.0.1:22376:2376
export DOCKER_HOST=tcp://localhost:22376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=$PWD/certs/client

# These run inside the DinD Docker
docker build -t myapp .
docker network create myapp-dind
docker run
  --net myapp-dind \
  --name myapp \
  -v /var/run/docker.sock:/var/run/docker.sock \
  myapp

# Return to the host Docker
unset DOCKER_HOST DOCKER_TLS_VERIFY DOCKER_CERT_PATH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM