gpt4 book ai didi

node.js - docker-compose “up”与 “run”会产生不同的安装量

转载 作者:太空宇宙 更新时间:2023-11-03 21:55:50 25 4
gpt4 key购买 nike

更新2:我已经创建了a sample project on Git to reproduce this issue。经过进一步测试,测试用例与我在原始帖子中描述的略有不同。

我包括了我在下面的github存储库上编写的自述文件的内容。

用例

  • 一个简单的带有Dockerfile的nodejs项目。
  • 上述项目使用的一个本地NPM依赖项(通过Dockerfile复制到容器)。该项目通过local path引用依赖项。
  • nodejs项目有一个Web路由(/),它从package.json打印本地npm依赖项的版本。这用于验证测试用例过程的结果。
  • docker-compose使用this volume technique覆盖主机的源树
    在容器的源代码树的顶部,然后将容器的node_modules覆盖在第一个卷的顶部。

  • 重现步骤
  • 克隆this repo
  • 通过docker rmdocker rmi清理与此仓库的项目相关的所有以前的容器和图像。
  • checkout test2_run1标签。此状态表示使用本地NPM依赖版本1.0.0的项目。
  • 进行docker-compose build。如果正确执行了第2步,则所有步骤应在没有任何缓存使用的情况下运行。
    npm install命令期间注意本地NPM依赖项的版本,例如+-- my-npm@1.0.0
  • 进行docker-compose up。浏览到http://localhost:8000。该页面应报告1.0.0版本。
  • 停止正在运行的容器。 (发出up命令的终端上的Ctrl-C。)
  • checkout test2_run2标签。这会将a small change引入到NPM的index.js文件中,并提供一个版本
    将其package.json更改为1.0.1
  • 进行docker-compose build只有COPY ./my-npm ...以下的指令才应使用缓存。 (例如,docker输出显示该指令的---> Using cache。)所有后续步骤均应由docker运行。这是因为在步骤7中对NPM软件包进行的更改应该使COPY ./my-npm ...命令的缓存无效,因此,随后的步骤也无效。确认在npm install命令期间,新版本的NPM已打印在摘要树输出中,例如+-- my-npm@1.0.1
  • 进行docker-compose up。浏览到http://localhost:8000。该页面应报告1.0.1版本。

  • 预期的行为:步骤9中的页面应报告 1.0.1。也就是说,本地npm的更改应通过 docker-compose up反射(reflect)在容器中。

    实际行为:步骤9中的页面报告 1.0.0

    请注意,泊坞窗本身正在按预期重新构建镜像。 观察到的问题不是docker正在重新使用缓存的图像作为输出
    显示它重新运行NPM安装并显示本地NPM依赖关系的新版本。问题是 docker-compose没有看到
    构成 dctest_service1容器的基础图像已更新。

    实际上,在容器中运行bash可以使我们看到容器具有更新的 my-npm模块文件,但是 node_modules版本已过时:

    # docker exec -it dctest_service1_1 bash
    app@6bf2671b75c6:~/service1$ grep version my-npm/package.json node_modules/my-npm/package.json
    my-npm/package.json: "version": "1.0.1",
    node_modules/my-npm/package.json: "version": "1.0.0"
    app@6bf2671b75c6:~/service1$

    解决方法:使用 docker rm删除 dctest_service1容器。然后重新运行 docker-compose up,它将使用现有图像重新创建容器。在此步骤中值得注意的是,不会重建任何基础镜像。在重新创建容器时, docker-compose似乎想使用具有更新的 node_modules的较新的卷。

    请参阅 output 目录,以获取在第一次运行(步骤4和5)和第二次运行(步骤8和9)期间输出的输出。

    原始帖子

    我有一个基于 this tutorial ("Lessons from Building a Node App in Docker")nodejs Dockerfile。具体来说,请注意,本教程使用了一种批量技巧来从容器本身挂载 node_modules目录,使其覆盖在主机上等效目录的顶部。例如。:
    volumes:
    - .:/home/app/my-app
    - /home/app/my-app/node_modules

    我遇到一个问题,其中package.json的更新正在按预期方式触发 npm install(而不是使用docker缓存),但是当使用 docker-compose up启动服务时,生成的容器以某种方式以较旧版本的 node_modules结尾数据,因为目录中缺少已添加的新添加的NPM软件包。但是,如果通过 CMD手动运行指定的 docker-compose run --rm,那么我 会看到更新后的音量!

    我可以通过几种方式确认这一点:
    node_modules时间戳

    容器通过“向上”启动:
    app@88614c5599b6:~/my-app$ ls -l
    ...
    drwxr-xr-x 743 app app 28672 Dec 12 16:41 node_modules

    容器通过“运行”启动:
    app@bdcbfb37b4ba:~/my-app$ ls -l
    ...
    drwxr-xr-x 737 app app 28672 Jan 9 02:25 node_modules

    不同的 docker inspect“安装”条目ID

    容器通过“向上”启动:
    "Name": "180b82101433ab159a46ec1dd0edb9673bcaf09c98e7481aed7a32a87a94e76a",
    "Source": "/var/lib/docker/volumes/180b82101433ab159a46ec1dd0edb9673bcaf09c98e7481aed7a32a87a94e76a/_data",
    "Destination": "/home/app/my-app/node_modules",

    容器通过“运行”启动:
    "Name": "8eb7454fb976830c389b54f9480b1128ab15de14ca0b167df8f3ce880fb55720",
    "Source": "/var/lib/docker/volumes/8eb7454fb976830c389b54f9480b1128ab15de14ca0b167df8f3ce880fb55720/_data",
    "Destination": "/home/app/my-app/node_modules",

    HostConfig->绑定(bind)

    我不确定这是否相关,但是我也注意到(也在 docker inspect中)在两种情况下 Binds下的 HostConfig部分有所不同:

    容器通过“向上”启动:
    "Binds": [
    "180b82101433ab159a46ec1dd0edb9673bcaf09c98e7481aed7a32a87a94e76a:/home/app/my-app/node_modules:rw",
    "/Volumes/my-mount/my-app:/home/app/my-app:rw"
    ],

    容器通过“运行”启动:
    "Binds": [
    "/Volumes/my-mount/my-app:/home/app/my-app:rw"
    ],

    (两个都显示了安装在图像上的主机源,但是只有“up”显示了带有 node_modules的辅助覆盖量,这似乎又是一个奇怪的问题。)

    理论

    根据 docker-compose CLI reference:

    If there are existing containers for a service, and the service’s configuration or image was changed after the container’s creation, docker-compose up picks up the changes by stopping and recreating the containers



    因此, docker-compose up似乎不认为配置或图像已更改。我只是不确定如何调试此以确认。当然,我可以使用 --force-recreate来解决此问题,但是我希望解决导致配置问题的我的配置不正确的问题。

    更新:如果在 docker-compose build之前执行显式的 docker-compose up,问题仍然存在。因此,我现在对此理论的信心下降。

    这是整个 Dockefile:
    FROM node:6.9.1

    RUN useradd --user-group --create-home --shell /bin/false app

    ENV HOME=/home/app
    ENV APP=my-app
    ENV NPM_CONFIG_LOGLEVEL warn

    RUN npm install --global gulp-cli

    COPY ./package.json $HOME/$APP/package.json
    RUN chown -R app:app $HOME/*

    USER app
    WORKDIR $HOME/$APP
    RUN npm install && npm cache clean

    USER root
    COPY . $HOME/$APP
    RUN chown -R app:app $HOME/* && chmod u+x ./node_modules/.bin/* ./bin/*

    USER app

    ENTRYPOINT ["/home/app/my-app/bin/entrypoint.sh"]
    CMD ["npm", "run", "start:dev"]

    最佳答案

    命令docker-compose使用docker-compose.yml文件作为容器化service的配置文件。默认情况下,它将在您运行docker-compose的目录中查找此.yml配置文件。
    因此,可能是您的docker-compose.yml文件不是最新的,因为您在运行docker-compose up时未挂载其中一个卷。
    docker run忽略docker-compose.yml文件,仅使用Dockerimage构建容器。因此,Dockerimage文件和docker-compose.yml文件之间可能存在配置差异。

    关于node.js - docker-compose “up”与 “run”会产生不同的安装量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41569912/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com