我正在尝试在docker容器中运行docker且容器具有nodeJs App。
这是我的 Dockerfile :
FROM docker:dind
WORKDIR /app
RUN apk add --update nodejs nodejs-npm
COPY . /app
RUN npm install
CMD node app.js
EXPOSE 4000
我使用上述Dockerfile构建了docker映像(newdockerimage),并使用docker run -d --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker newdockerimage
创建了容器。
我能够将docker安装在容器内,但是由于体积(/var/run/docker.sock
),主机系统上的所有docker镜像也在容器内共享。
如果我在运行容器时不使用卷-v /var/run/docker.sock:/var/run/docker.sock
,则会出现以下错误:-
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
因为容器将是节点应用程序(因为它是入口点),所以覆盖docker:dind入口点
请帮助我!如何在容器内运行docker而不共享卷(不复制主机系统的docker镜像)
答案 0 :(得分:1)
当您用CMD
覆盖默认的Docker-dind node app.js
时,它将不会启动Docker服务。因此,您将得到
Cannot connect to the Docker daemon
因为泊坞窗未在您的容器中运行。
因此,解决方法是在后台启动docker,在前台启动您的节点应用程序。
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
构建图像并像启动容器一样
docker run -it --privileged --name test --rm my-docker-dind
答案 1 :(得分:0)
从技术上讲,可以在Docker容器中运行Docker,但通常不建议这样做。 Docker Hub description for the docker
image有很多文档,请务必仔细阅读。我通常也不认为从容器内部访问Docker套接字是一种最佳实践,除非它是绝对必要的,并且通常来说,您不应该尝试在单个程序中运行两个程序图片。我会强烈考虑采用其他方法来解决您的更高级别的问题:这既不是标准也不是简单的设置。
有两种访问DinD套接字的方法。它通过TCP-over-TLS在端口2376上发布它,或者如果您在嵌套Docker中运行一个容器,则用于绑定安装的“主机系统”是DinD容器。
(但是,等等:网络HTTP对Docker套接字的访问是否会造成安全性灾难?这里有两个缓解措施:由于它位于主机Docker内部,因此存在一层NAT /防火墙,并且您无法访问该嵌套的Docker。套接字,除非您发布它;虽然可以使用它来获得不受限制的根访问,但它只能在嵌套的DinD容器及其内容上进行。
您应该做的第一件事是将Dockerfile重写为标准Node映像。它不应扩展docker
映像,因为它不是Docker映像,而是Node-application映像。
FROM node:12
WORKDIR /app
COPY . .
RUN npm install
CMD node app.js
EXPOSE 4000
启动DinD,作为一个单独的容器:
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
现在,您可以在主机Docker上启动一个容器,并为其提供指向嵌套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
或者,您可以在DinD设置中运行此容器。
# 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