如何填充docker-compose.yaml中的卷

我开始写我的第一个docker-compose.yml文件来设置组成我的应用程序的服务(所有node-js)的组合。 其中一个服务(web-server-bespoke,不是express)既有一大组模块,也有一组更大的bower_components。

为了提供关注点的分离,所以我可以更紧密地控制版本控制,我想创build两个存放node_modules和bower_components的命名卷,并将这些卷挂载到Web服务器服务的相关目录中。

令我困惑的问题是如何在启动服务时获得这两个卷。 我的困惑有两个原因:

  1. docker-compose的行为docker-compose-d标志docker-compose ,而docker run命令与-d标志组合 – Web服务显然需要保持运行(如果失败,实际上需要重新启动),而可能填充一个或另一个的容器的卷是运行一次,因为整个应用程序是由docker-compose up命令提出的。 我可以控制这个吗?
  2. 正在运行的服务和该服务的build命令。 我真的可以使用Dockerfiles来运行npm installbower install 。 特别是,如果我更改了Web应用程序的源代码,但是模块和bower_components不会更改,那么由于caching的结果,此构build步骤会瞬间完成吗?

我一直无法find这种行为的例子,所以我很困惑如何去做。 有人可以帮忙吗?

我将首先从标准的方式开始

2. Dockerfile

使用Dockerfile可以避免尝试解决如何设置docker-compose服务依赖关系或外部构build脚本,以便在docker构build之前填充和运行卷。

可以设置bower.json ,只更改bower.jsonpackage.json将触发重新安装node_modulesbower_components

首先安装的命令在某些时候必须使第二个命令caching失效,尽pipe如此,您将它们置于重要的位置。 哪个更新最less,或者显着更慢应该先去。 如果要先运行bower命令,则可能需要手动安装全局bower

如果您担心NPM版本,请查看使用yarn和yarn.lock文件。 纱线也会加速一点点。 Bower可以设置特定的版本,因为它没有NPM所做的相同的子模块版本控制问题。

文件Dockerfile

 FROM mhart/alpine-node:6.9.5 RUN npm install bower -g WORKDIR /app COPY package.json /app/ RUN npm install --production COPY bower.json /app/ RUN bower install COPY / /app/ CMD ["node", "server.js"] 

文件.dockerignore

 node_modules/ bower_components/ 

这在docker-compose build: stanza中被支持

1. Docker撰写+卷

填充卷最简单/最快捷的方法是在目录填充到映像中后,在Dockerfile定义一个VOLUME 。 这将通过撰写工作。 我会质疑,当图像已经有所需的内容,但使用卷的点…

任何其他的人口方法都需要一些构build之外的自定义构build脚本。 一个选项是docker run一个容器与所需的卷连接和填充npm/bower install

 docker run \ --volume myapp_bower_components:/bower_components \ --volume bower.json:/bower.json \ mhart/alpine-node:6.9.5 \ npm install bower -g && bower install 

 docker run \ --volume myapp_mode_modules:/node_modules \ --volume package.json:/package.json \ mhart/alpine-node:6.9.5 \ npm install --production 

然后,您将能够在您的应用程序容器上安装已填充的卷

 docker run \ --volume myapp_bower_components:/bower_components \ --volume myapp_node_modules:/node_modules \ --port 3000:3000 my/app 

您可能需要为卷名提供某种版本控制scheme,以便可以回滚。 听起来像一个图像已经为你做了很多努力。

或者可以看看摇杆 ,它提供了一个可选的docker构build系统,并且可以让你完成Docker开发人员所需的所有function,比如在构build过程中安装一个目录。 这再次超出了Docker Compose所支持的范围。

我做了像没有凉亭,但与像Sass,霍尔,活重装,茉莉花等nodeJS工具类似的东西…我用npm所有安装在npm项目(不全球安装)内部为此,官方节点图像很安静,我只需要将PATH设置为app / node_modules / .bin即可。 所以我的Dockerfile看起来像这样(非常简单):

 FROM node:7.5 ENV PATH /usr/src/app/node_modules/.bin/:$PATH 

我的docker-compose.yml文件是:

 version: '2' services: mydata: image: busybox stdin_open: true volumes: - .:/usr/src/app node: build: . image: mynodecanvassvg working_dir: /usr/src/app stdin_open: true volumes_from: - mydata sass: depends_on: - node image: mynodecanvassvg working_dir: /usr/src/app volumes_from: - mydata #entrypoint: "node-sass -w -r -o public/css src/scss" stdin_open: true jasmine: depends_on: - node image: mynodecanvassvg working_dir: /usr/src/app volumes_from: - mydata #entrypoint: "jasmine-node --coffee --autoTest tests/coffee" stdin_open: true live: depends_on: - node image: mynodecanvassvg working_dir: /usr/src/app volumes_from: - mydata ports: - 35729:35729 stdin_open: true 

入口点只有一些麻烦,在工作时都需要一个terminal来显示结果。 因此,我使用stdin_open:true来保持容器活动,然后使用每个容器上的docker exec -it来运行每个watch服务。

当然,我推出了docker-compose和-d来保持它作为守护进程。 接下来,您必须将npm package.json放在您的应用程序文件夹中(位于Dockerfile和docker-compose.yml旁边),并启动npm更新以加载和安装模块。