Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Docker compose依赖于Docker环境外部本地安装的软件包_Node.js_Docker_Npm_Docker Compose - Fatal编程技术网

Node.js Docker compose依赖于Docker环境外部本地安装的软件包

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在本地环境中创建我的图像,但我遇到了一些问题

看起来,在执行
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并启动)
  • 旋转容器
  • 走健康之路
这意味着我不需要在docker之外的本地项目中运行
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