Docker-compose依赖于Docker环境之外的本地安装包

我正在使用docker-compose在我的本地环境中创build自己的图像,但是我遇到了一些问题。

看起来像做docker-compose up ,Docker compose不会运行,除非我在Docker之外的项目中本地安装了所有的软件包。

这是情景。

我有一个包简单的index.js文件( express

 const app = require('express')(); app.get('/health', (req, res) => res.status(200).send('ok')); app.listen(8080, () => console.log('magic happens here')); 

一个Dockerfile来构build图像

 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文件启动项目(我已经删除链接的图像,以保持最小)

 version: "2.1" services: api: build: . container_name: test_dc ports: - "8080:8080" volumes: - .:/src 

任何人的想法都可以克隆存储库并运行docker compose命令来:

  • 从Dockerfile构build镜像(安装戴尔并启动)
  • 旋转容器。
  • 击中健康路线。

这意味着我不需要在npm install之外的本地项目中运行npm install

然而,这是在docker-compose up

在这里输入图像说明

但是,当我在本地运行npm install时就解决了这个问题。

这不是对Docker的整个想法? 一个项目应该与系统的其他部分隔离开来吗?

有什么我失踪?

外部卷装载可以掩盖图像内容

您似乎想让您的项目代码在/src生存,如Dockerfile中所示:

 RUN mkdir /src WORKDIR /src COPY package.json /src COPY . /src 

但是在docker-compose.yml中,你正在将一个外部path挂载为/src

 volumes: - .:/src 

外部安装将优先,并掩盖Dockerfile中的图像内build的所有内容(以及在Dockerfile中定义的卷)。

使用自定义入口点运行启动任务

通常的处理方法是使用在启动时运行安装程序的入口点脚本。

entrypoint.sh:

 #!/bin/sh npm install exec "$@" 

Dockerfile:

 COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] 

在容器启动时,运行入口点脚本,并挂载外部卷。 因此, npm install可以在那里运行和安装模块。 完成后,执行CMD 。 在你的情况下,这是npm start

为什么你会想要使用自定义的入口点

使用容器的一个原因是创build隔离。 也就是说,你希望图像被隔离,而不是依赖于你的外部环境。 那么为什么你要使用外部安装呢?

答案是在开发过程中你经常要避免经常重build。 由于图像是不可变的,每一个改变都需要重build和重启容器。 所以每一个代码都会改变…是的,这会很慢。

一个很好的折衷办法就是将你的图像完全包含在内,但是在开发过程中,你需要从外部安装代码,这样你就可以快速地进行修改而无需重build。 一旦准备好释放代码,您可以删除外部安装并进行最终的构build。 由于您正在复制装入容器中的文件,所以它们都是一样的。 而构build中的npm install步骤与您在自定义ENTRYPOINT运行的步骤相同。