Docker没有将文件更改从主机传播到容器

时间:2017-09-04 21:38:34

标签: node.js docker docker-compose

我的目标是配置docker,以便在我修改主机上的文件时,更改会在容器文件系统内传播。

您可以将此视为服务器端节点代码的热重载。

nodemon文件观察器应该重新启动服务器以响应文件更改。

但是,当我使用docker exec pokerspace_express_1 bash检查容器时,主机卷上的这些文件更改似乎没有反映在容器内,并检查修改后的文件,更改不会从容器中传播到容器内。

Dockerfile

FROM node:8

MAINTAINER therewillbecode

# Create app directory
WORKDIR src/app

RUN npm install nodemon -g

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install


CMD [ "npm", "start" ]

搬运工-compose.yml

version: '2'
services:
  express:
   build: .
   depends_on:
    - mongo
   environment:
    - MONGO_URL=mongo:27017/test
    - SERVER_PORT=3000
   volumes:
    - ./:/src/app
   ports:
    - '3000:3000'
   links:
    - mongo

  mongo:
    image: mongo
    ports:
     - '27017:27017'

  mongo-seed:
    build: ./mongo-seed
    links:
     - mongo

.dockerignore

.git
.gitignore
README.md
docker-compose.yml

如何确保主机卷文件更改反映在容器中?

3 个答案:

答案 0 :(得分:2)

在Dockerfile中尝试这样的事情:

CMD ["nodemon", "-L"]

有些人遇到了类似问题,并且能够通过将-L(意为“传统监视”)传递给nodemon来解决问题。

参考文献:

答案 1 :(得分:1)

Daniel的回答部分对我有用,但是热重装仍然不起作用。我使用的是Windows主机,不得不将他的docker-compose.yml更改为

version: '3'
services: 
  web: 
    build: .
    ports:
      - "3000:3000"
    volumes:
      - /App/node_modules
      - .:/App

(我将volumes的参数从/app/node_modules更改为/App/node_modules,并从.:/app更改为.:/App。这使更改可以传递到容器,< strong>但是仍然无法进行热重装。每次要刷新应用程序时,我都必须使用docker-compose up --build。)

答案 2 :(得分:0)

对,所以使用Docker,我们需要重新构建映像或找出一些聪明的解决方案。

您可能不想在每次更改源代码时都重新构建映像。

让我们找出一个聪明的解决方案。让我们来概括一下Dockerfile,以解决您的问题并为他人提供帮助。

这就是样板Dockerfile

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . .

CMD ["npm", "run", "start"]

请记住,在图像构建过程中,我们正在创建一个临时容器。制作副本时,我们实际上是对内容/src/public进行快照。它的快照在时间上是锁定的,默认情况下不会通过更改代码来更新。

因此,为了对文件/src/public进行这些更改,我们需要放弃直接复制,我们将调整用于启动的docker run命令上我们的容器。

我们将利用称为音量的功能。

使用Docker卷,我们在Docker容器内设置了一个占位符,因此可以想象我们不会复制整个/src目录,而是想像一下将引用这些文件并允许我们访问文件和文件夹在本地计算机内部。

我们正在建立从容器内的文件夹到容器外的文件夹的映射。使用该命令有点麻烦,但是一旦在此处记录了该命令,您就可以将该答案添加为书签。

docker run -p 3000:3000 -v /app/node_modules -v $(pwd):/app <image_id>

-v $(pwd):/app用于在当前工作目录中设置卷。这是捷径。所以我们说的是获取当前的工作目录,获取其中的所有内容并将其映射到我们正在运行的容器中。我知道这已经很长了。

要实现此目的,您必须首先通过运行以下命令重建docker映像:

docker build -f Dockerfile.dev .

然后运行:

docker run -p 3000:3000 -v $(pwd):/app <image_id>

然后您将很快得到一条错误消息,react-scripts not found错误。您会看到该消息,因为我跳过了-v /app/node_modules

那怎么了?

volume命令设置了一个映射,当我们这样做时,是说将所有内容都放入当前工作目录中,并将其映射到我们的/app文件夹中,但是问题是没有{{1} }文件夹,这是我们所有依赖项所在的位置。

因此/node_modules文件夹被覆盖。

因此,我们基本上没有指向任何东西,这就是为什么我们需要不带冒号的/node_modules的原因,因为冒号是将容器内的文件夹映射到容器外的文件夹。没有冒号,我们是说要它成为占位符,不要将它映射到任何东西上。

现在,继续运行:-v /app/node_modules

完成后,您可以对项目进行所有想要的更改,并在浏览器中看到它们“热重载”。无需弄清楚如何实现Nodemon。

因此,发生的事情是对本地文件系统所做的任何更改都会传播到您的容器中,容器中的服务器会看到更改并进行更新。

现在,在进入Docker Compose时,我很难记住这么长的命令。

我们可以利用Docker Compose大大简化启动容器所需的命令。

因此,要实现创建Docker Compose文件并在其中的内容,您将包括端口设置和所需的两个卷。

在您的根项目中,创建一个名为docker run -p 3000:3000 -v $(pwd):/app <image_id>的新文件。

在其中您将添加以下内容:

docker-compose.yml

然后运行:version: '3' services: web: build: . ports: - "3000:3000" volumes: - /app/node_modules - .:/app