[翻译]  docker-compose volume on node_modules but is empty

[CHINESE]  docker-compose在node_modules上的卷但是为空


I'm pretty new with Docker and i wanted to map the node_modules folder on my computer (for debugging purpose).

我是Docker的新手,我想在我的计算机上映射node_modules文件夹(用于调试目的)。

This is my docker-compose.yml

这是我的docker-compose.yml

web:
  build: .
  ports:
    - "3000:3000"
  links:
    - db
  environment:
    PORT: 3000
  volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules
db:
  image: mongo:3.3
  ports:
    - "27017:27017"
  command: "--smallfiles --logpath=/dev/null"

I'm with Docker for Mac. When i run docker-compose up -d all go right, but it create a node_modules folder on my computer but it's empty. I go into the bash of my container and ls node_modules, all the packages was there.

我用Docker for Mac。当我运行docker-compose up -d all go right,但它在我的计算机上创建了一个node_modules文件夹,但它是空的。我进入我的容器的bash和ls node_modules,所有的包都在那里。

How can i get the content on the container on my computer too?

如何在计算机上获取容器上的内容呢?

Thank you

谢谢

3 个解决方案

#1


6  

TL;DR Working example, clone and try: https://github.com/xbx/base-server

TL; DR工作示例,克隆并尝试:https://github.com/xbx/base-server


You need a node_modules in your computer (outside image) for debugging purposes first (before run the container).

您需要首先在计算机(外部映像)中使用node_modules进行调试(在运行容器之前)。

If you want debug only node_modules:

如果您只想调试node_modules:

volumes:
    - /path/to/node_modules:/usr/src/app/node_modules

If you want debug both your code and the node_modules:

如果要调试代码和node_modules:

volumes:
    - .:/usr/src/app/

Remember that you will need run npm install at least one time outside the container (or copy the npm_modules that the docker build generates). Let me now if you need more details.

请记住,您需要在容器外至少运行一次npm install(或者复制docker build生成的npm_modules)。如果您需要更多详细信息,现在就让我


Edit. So, without the need of npm in OSX, you can:

编辑。因此,在OSX中不需要npm,您可以:

  1. docker build and then docker cp <container-id>:/path/to/node-modules ./local-node-modules/. Then in your docker-compose.yml mount those files and troubleshot whatever you want.
  2. docker build然后docker cp :/ path / to / node-modules ./local-node-modules/。然后在你的docker-compose.yml中安装这些文件并麻烦你想要的任何东西。
  3. Or, docker build and there (Dockerfile) do the npm install in another directory. Then in your command (CMD or docker-compose command) do the copy (cp) to the right directory, but this directory is mounted empty from your computer (a volume in the docker-compose.yml) and then troubleshot whatever you want.
  4. 或者,docker build和那里(Dockerfile)在另一个目录中执行npm install。然后在你的命令(CMD或docker-compose命令)中复制(cp)到正确的目录,但是这个目录从你的计算机(docker-compose.yml中的一个卷)挂起,然后麻烦你想要的任何东西。

Edit 2. (Option 2) Working example, clone and try: https://github.com/xbx/base-server I did it all automatically in this repo forked from the yours.

编辑2.(选项2)工作示例,克隆并尝试:https://github.com/xbx/base-server我在这个由您自己分配的仓库中自动完成了所有操作。

Dockerfile

Dockerfile

FROM node:6.3

# Install app dependencies
RUN mkdir /build-dir
WORKDIR /build-dir
COPY package.json /build-dir
RUN npm install -g babel babel-runtime babel-register mocha nodemon
RUN npm install

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN ln -s /build-dir/node_modules node_modules

# Bundle app source
COPY . /usr/src/app

EXPOSE 1234
CMD [ "npm", "start" ]

docker-compose.yml

泊坞窗,compose.yml

web:
  build: .
  ports:
    - "1234:1234"
  links:
    - db # liaison avec la DB
  environment:
    PORT: 1234
  command: /command.sh
  volumes:
    - ./src/:/usr/src/app/src/
    - ./node_modules:/usr/src/app/node_modules
    - ./command.sh:/command.sh
db:
  image: mongo:3.3
  ports:
    - "27017:27017"
  command: "--smallfiles --logpath=/dev/null"

command.sh

command.sh

#!/bin/bash

cp -r /build-dir/node_modules/ /usr/src/app/

exec npm start

Please, clone my repo and do docker-compose up. It does what you want. PS: It can be improved to do the same in a better way (ie best practices, etc)

请克隆我的回购并做docker-compose。它做你想要的。 PS:可以改进以更好的方式做同样的事情(即最佳实践等)

I'm in OSX and it works for me.

我在OSX,它适合我。

#2


1  

First, there's an order of operations. When you build your image, volumes are not mounted, they only get mounted when you run the container. So when you are finished with the build, all the changes will only exist inside the image, not in any volume. If you mount a volume on a directory, it overlays whatever was from the image at that location, hiding those contents from view (with one initialization exception, see below).

首先,有一个操作顺序。构建映像时,未装入卷,只有在运行容器时才会装入卷。因此,当您完成构建时,所有更改将仅存在于图像内,而不是存在于任何卷中。如果在目录上安装卷,它会覆盖该位置图像中的任何内容,从视图中隐藏这些内容(有一个初始化异常,请参见下文)。


Next is the volume syntax:

接下来是卷语法:

  volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules

tells docker-compose to create a host volume from the current directory to /usr/src/app inside the container, and then to map /usr/src/app/node_modules to an anonymous volume maintained by docker. The latter will appear as a volume in docker volume ls with a long uuid string that is relatively useless.

告诉docker-compose从当前目录创建一个主机卷到容器内的/ usr / src / app,然后将/ usr / src / app / node_modules映射到由docker维护的匿名卷。后者将显示为docker volume ls中的一个卷,其中一个长的uuid字符串相对无用。

To map /usr/src/app/node_modules to a folder on your host, you'll need to include a folder name and colon in front of that like you have on the line above. E.g. /host/dir/node_modules:/usr/src/app/node_modules.

要将/ usr / src / app / node_modules映射到主机上的文件夹,您需要在上面的行中包含一个文件夹名称和冒号。例如。 /主机/ DIR / node_modules:/ usr / src目录/应用/ node_modules。

Named volumes are a bit different than host volumes in that docker maintains them with a name you can see in docker volume ls. You reference these volumes with just a name instead of a path. So node_modules:/usr/src/app/node_modules would create a volume called node_modules that you can mount in a container with just that name.

命名卷与主机卷略有不同,因为docker使用您在docker volume ls中可以看到的名称维护它们。您只使用名称而不是路径来引用这些卷。所以node_modules:/ usr / src / app / node_modules会创建一个名为node_modules的卷,您可以将其挂载到只具有该名称的容器中。

I diverged to describe named volumes because they come with a feature that turns into a gotcha with host volumes. Docker helps you out with named volumes by initializing them with the contents of the image at that location. So in the above example, if the named volume node_modules is empty (or new), it will first copy the contents of the image at /usr/src/app/node_modules` to this volume and then mount it inside your container.

我分歧来描述命名卷,因为它们带有一个功能,变成了主机卷的问题。 Docker通过使用该位置的图像内容初始化命名卷来帮助您解决它们。因此,在上面的示例中,如果命名卷node_modules为空(或新),它将首先将/ usr / src / app / node_modules`中的映像内容复制到此卷,然后将其挂载到容器中。

With host volumes, you will never see any initialization, whatever is at that location, even an empty directory, is all you see in the container. There's no way to get contents from the image at that directory location to first copy out to the host volume at that location. This also means that directory permissions needed inside the container are not inherited automatically, you need to manually set the permissions on the host directory that will work inside the container.

使用主机卷,您将永远不会看到任何初始化,无论在该位置,甚至是空目录,您都可以在容器中看到。无法从该目录位置的映像获取内容,以便首先复制到该位置的主机卷。这也意味着容器内所需的目录权限不会自动继承,您需要手动设置将在容器内工作的主机目录的权限。


Finally, there's a small gotcha with docker for windows and mac, they run inside a VM, and your host volumes are mounted to the VM. To get the volume mounted to the host, you have to configure the application to share the folder in your host to the VM, and then mount the volume in the VM into the container. By default, on Mac, the /Users folder is included, but if you use other directories, e.g. a /Projects directory, or even a lower case /users (unix and bsd are case sensitive), you won't see the contents from your Mac inside the container.

最后,有一个针对Windows和Mac的docker的小问题,它们在VM内部运行,并且您的主机卷已安装到VM。要将卷装入主机,必须将应用程序配置为将主机中的文件夹共享到VM,然后将VM中的卷装入容器中。默认情况下,在Mac上,包含/ Users文件夹,但如果您使用其他目录,例如a / Projects目录,甚至是小写/用户(unix和bsd区分大小写),您将无法在容器内看到Mac中的内容。


With that base knowledge covered, one possible solution is to redesign your workflow to get the directory contents from the image copied out to the host. First you need to copy the files to a different location inside your image. Then you need to copy the files from that saved image location to the volume mount location on container startup. When you do the latter, you should note that you are defeating the purpose of having a volume (persistence) and may want to consider adding some logic to be more selective about when you run the copy. To start, add an entrypoint.sh to your build that looks like:

有了这些基础知识,一种可能的解决方案是重新设计工作流程,以便将图像中的目录内容复制到主机。首先,您需要将文件复制到图像中的其他位置。然后,您需要将保存的映像位置中的文件复制到容器启动时的卷装入位置。当你执行后者时,你应该注意到你正在破坏拥有卷(持久性)的目的,并且可能想要考虑添加一些逻辑以便在运行副本时更具选择性。首先,将一个entrypoint.sh添加到您的构建中,如下所示:

#!/bin/sh
# copy from the image backup location to the volume mount
cp -a /usr/src/app_backup/node_modules/* /usr/src/app/node_modules/
# this next line runs the docker command
exec "$@"

Then update your Dockerfile to include the entrypoint and a backup command:

然后更新Dockerfile以包含入口点和备份命令:

FROM node:6.3

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install -g babel babel-runtime babel-register mocha nodemon
RUN npm install

# Bundle app source
COPY . /usr/src/app
RUN cp -a /usr/src/app/. /usr/src/app_backup

EXPOSE 1234
ENTRYPOINT [ "/usr/src/app/entrypoint.sh" ]
CMD [ "npm", "start" ]

And then drop the extra volume from your docker-compose.yml:

然后从docker-compose.yml中删除额外的音量:

  volumes:
    - .:/usr/src/app

#3


0  

change:

更改:

  volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules

TO:

至:

  volumes:
    - .:/usr/src/app

And it will put the node_modules in your local mapped volume. The way you have it, the /usr/src/app/node_modules will be stored in different volume that you would need to docker inspect {container-name} to find the location. If you do want to specify the location, specify it like:

它会将node_modules放在本地映射的卷中。你拥有它的方式,/ usr / src / app / node_modules将存储在docker inspect {container-name}找到位置所需的不同卷中。如果您确实要指定位置,请将其指定为:

- /path/to/my_node_modules:/usr/src/app/node_modules

- / path / to / my_node_modules:/ usr / src / app / node_modules


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2018 ITdaan.com 粤ICP备14056181号