Docker + NodeJS: docker-compose up 和 docker-compose run 下的 node_modules 不一致

4

我正在尝试将一个简单的Node.js应用程序Docker化,以进行开发目的。

为此,我创建了一个简单的Dockerfile:

FROM node:15-alpine

# Code folder inside Docker
RUN mkdir /code
WORKDIR /code


# Install deps before mounting volume to improve caching
COPY package*.json ./
RUN npm install

# No need to copy code, we are building a volume later
EXPOSE 1234

除了两个非常相似的docker-compose.yml文件外,一个用于测试,另一个用于以dev模式运行应用程序。

version: "3.1"
services:
  db:
    image: mongo:4
    environment:
      MONGO_INITDB_ROOT_USERNAME: my-user
      MONGO_INITDB_ROOT_PASSWORD: my-pswd
      MONGO_INITDB_DATABASE: my-db

  app:
    environment:
      - NODE_ENV=development
    depends_on:
      - "db"
    build: .
    ports:
      - "1234:1234"
    env_file: ./.docker.env
    command: npm run dev
    volumes:
      - .:/code
      - /code/node_modules

问题在于每当我启动docker-compose upnpm run dev(它只是指向nodemon index.js)时,失败了,因为没有安装nodemon包。
每当我启动docker-compose run app时,它都可以正常运行。以及docker-compose run app sh也可以让我顺利地启动npm run devdocker-compose.ymldocker-compose.test.yml都有NODE_ENV=development,测试文件还从node_modules中启动一个命令(mocha确切说)。
请注意,这种行为是在我从node:15迁移到node:15-alpine后出现的。
如果有人知道原因,我将非常感激。

你能分享一下你的项目结构吗?更具体地说,你的Docker文件在Docker Compose文件中是处于哪个位置的呢? - nishkaush
@nishkaush 我的 Dockerfile 位于项目根目录,docker-compose 文件也是如此。 - Jo Colina
1
你的 volumes: 指示 Docker 在第一次运行时保留 node_modules 树,并优先使用该保留卷,而不是镜像中的内容:所有对 package.json 的更新都将被完全忽略。如果你只是想针对本地源树运行 Node,那么在本地安装可能会更容易些。 - David Maze
1
我不是在发布答案,但问题自己解决了(?)。重建镜像多次后,它就奇迹般地工作了。Dockerfile或docker-compose文件没有任何更改。 - Jo Colina
1个回答

0

请尝试将您的node_modules进行如下映射:

volumes:
  - .:/code
  - node_modules:/code/node_modules

或者,尝试重新构建,但首先清除缓存:

docker-compose build --no-cache

然后运行docker-compose up


非常感谢@nishkaush!不幸的是,这些解决方案都没有起作用。我认为这是alpine镜像工作方式固有的问题,因为在node:15(ubuntu)中我没有遇到这个问题。但是我无法解释为什么手动启动容器时它可以正常工作,而使用docker-compose up却不行。 - Jo Colina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接