Node.js Docker compose依赖于Docker环境外部本地安装的软件包
我正在使用docker compose在本地环境中创建我的图像,但我遇到了一些问题 看起来,在执行Node.js Docker compose依赖于Docker环境外部本地安装的软件包,node.js,docker,npm,docker-compose,Node.js,Docker,Npm,Docker Compose,我正在使用docker compose在本地环境中创建我的图像,但我遇到了一些问题 看起来,在执行docker compose up时,docker compose不会运行,除非我在docker之外的项目中本地安装了所有包 下面是一个场景 我有一个简单的index.js文件和一个包(express) 用于构建映像的Dockerfile FROM node:6.9.5 RUN mkdir -p /var/log/applications/test_dc RUN mkdir /src WORKD
docker compose up
时,docker compose不会运行,除非我在docker之外的项目中本地安装了所有包
下面是一个场景
我有一个简单的index.js
文件和一个包(express
)
用于构建映像的Dockerfile
FROM node:6.9.5
RUN mkdir -p /var/log/applications/test_dc
RUN mkdir /src
WORKDIR /src
COPY package.json /src
COPY . /src
RUN npm install
VOLUME ["/src", "/var/log/applications/test_dc"]
EXPOSE 8080
CMD ["npm", "start"]
和一个docker compose.yml
文件来启动项目(我已经删除了链接的图像以保持最小)
任何人都可以克隆存储库并运行docker compose命令来:
- 从Dockerfile生成映像(安装deps并启动)
- 旋转容器
- 走健康之路
npm install
但是,这在docker compose up上失败
但是,当我在本地运行npm install
时,这个问题就解决了
这是不是违背了Docker的整个想法?项目应该与系统的其他部分隔离吗
我缺少什么吗?外部卷装载可以屏蔽图像内容
您似乎希望项目代码位于/src
,如Dockerfile中所示:
运行mkdir/src
WORKDIR/src
复制package.json/src
抄袭/src
但是在docker-compose.yml中,您正在挂载一个外部路径作为/src
volumes:
- .:/src
外部装载将优先,并隐藏Dockerfile中内置到映像中的所有内容(以及在Dockerfile中定义的卷)
使用自定义入口点运行启动任务
处理此问题的通常方法是使用入口点脚本,该脚本在容器启动时运行安装程序
entrypoint.sh:
#/垃圾箱/垃圾箱
npm安装
执行官“$@”
Dockerfile:
复制entrypoint.sh/entrypoint.sh
运行chmod 755/entrypoint.sh
入口点[“/ENTRYPOINT.sh”]
在容器启动时,entrypoint脚本将运行,外部卷已装入。因此,npm install
可以在那里运行和安装模块。完成后,执行CMD
。在您的情况下,这就是npm start
为什么要使用自定义入口点
使用容器的一个原因是创建隔离。也就是说,您希望图像被隔离,而不依赖于外部环境。那么,为什么要使用外部挂载呢
答案是,在开发过程中,您通常希望避免频繁的重建。因为映像是不可变的,所以每一次更改都需要重新生成并重新启动容器。所以每次代码更改。。。是的,那会很慢
一个很好的折衷办法是构建完全包含的映像,但是在开发过程中,您可以从外部装载代码,这样您就可以非常快速地进行更改,而无需重新构建步骤。一旦准备好发布代码,就可以删除外部装载并进行最终构建。由于您正在将装载到容器中的文件复制到容器中,所以一切都是一样的。构建中的
npm安装
步骤与您在自定义ENTRYPOINT中运行的步骤相同
好的,我需要阅读更多关于Docker卷的内容,但这似乎是有意义的。我使用卷的目的是确保:-本地环境与本地系统隔离(即我可以只克隆repo并运行docker compose up
)-我在应用程序中所做的任何更改都会更新映像/容器。如何在Dockerfile和docker-compose.yml中重写/放弃当前卷配置以避免自定义脚本?@JohnKariuki此设置的通常使用情况是为了更快的开发(无需不断重建图像)。我更新了我的答案,补充了一些关于这个的信息。酷。现在检查一下。
version: "2.1"
services:
api:
build: .
container_name: test_dc
ports:
- "8080:8080"
volumes:
- .:/src
volumes:
- .:/src