0

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? 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)

David Maze
  • 130,717
  • 29
  • 175
  • 215
Priya Rani
  • 1,063
  • 3
  • 11
  • 21

2 Answers2

1

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

enter image description here

Adiii
  • 54,482
  • 7
  • 145
  • 148
  • I tried your suggestions but got an same error response `root@ip-*.*.*.*:/home/ubuntu# docker exec -it 1de2a6d8ae23 /bin/sh /app # docker version Client: Docker Engine - Community Version: 19.03.4 API version: 1.40 Go version: go1.12.10 Git commit: 9013bf583a Built: Fri Oct 18 15:49:05 2019 OS/Arch: linux/amd64 Experimental: false Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?` – Priya Rani Oct 30 '19 at 10:15
  • did rebuild the image? did you assign `--privileged`? you run command should be like `docker run -it --privileged --name test --rm my-docker-dind` and then `docker exec -it test ash` then type `docker ps` – Adiii Oct 30 '19 at 10:21
  • Yes I rebuild the image and start container like docker run -it --privileged --name test --rm mydockerimage-name – Priya Rani Oct 30 '19 at 10:22
  • `docker exec -it test ash -c "docker ps"` this should work. – Adiii Oct 30 '19 at 10:25
  • 1
    root@ip-*-*-*-* :/home/ubuntu# docker exec -it test ash -c "docker ps" Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? – Priya Rani Oct 30 '19 at 10:27
  • I am sure something is missing on your side. – Adiii Oct 30 '19 at 10:32
0

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
David Maze
  • 130,717
  • 29
  • 175
  • 215