Docker 构建不在 `node_modules` 卷中安装包
Docker build does not install packages in `node_modules` volumes
什么原因导致 yarn/npm 安装时未在卷中安装任何软件包?
我有一个 Docker 文件,其中包含 运行 纱线安装的说明(使用 NPM 和 YARN 进行了测试),但是容器内的包 node_modules
目录是空的。如果我 exec -it service_name bash
和 运行 手动安装命令,它会正确安装包。
我在重构后注意到了这一点,我有一个 Worker 服务执行安装过程,第二个 运行 开发服务器。决定将所有内容都保留在相同的 Docker-compose 声明中,但由于问题开始发生,它仍然存在。尝试完全重置等但没有成功(关闭、rm 容器、p运行e 等)。
Docker-compose 文件中声明的相关服务:
node_dev:
build:
context: .
dockerfile: ./.docker/dockerFiles/node.yml
image: foobar/node_dev:latest
container_name: node_dev
working_dir: /home/node/app
ports:
- 8000:8000
- 9000:9000
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/
volumes:
- ./foobar-blog-ui/:/home/node/app
- ui_node_modules:/home/node/app/node_modules
- ui_gatsbycli_node_module:/usr/local/lib/node_modules/gatsby-cli
- ./.docker/scripts/wait-for-it.sh:/home/node/wait-for-it.sh
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn start'
depends_on:
- mysql
- wordpress
networks:
- foobar-wordpress-network
服务中的相关 Volumes
引用:
volumes:
ui_node_modules:
ui_gatsbycli_node_module:
最后,生成图片的Docker文件:
FROM node:8.16.0-slim
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
WORKDIR /home/node/app
RUN apt-get update
RUN apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx
RUN yarn global add gatsby-cli
RUN yarn install
此外,尝试 yarn install --force --no-lockfile
并确保它在项目根目录中没有任何包或 yarn 锁定文件的情况下进行测试,反之亦然。
我发现这很奇怪,肯定是某个地方的错字,但我还没有发现。
主机系统是 macOS Mojave。
我想提一下,如果 exec -it service_name bash
并执行 NPM/YARN 安装,node_modules 会填充软件包。
在我做的大多数测试之前,我还尝试通过以下方式重置:
docker-compose stop
docker-compose rm -f
docker volume prune -f
docker network prune -f
现在测试了:
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker volume prune -f
docker volume rm $(docker volume ls -qf dangling=true)
docker network prune -f
docker system prune --all --force --volumes
rm -rf ./.docker/certs/ ./.docker/certs-data/ ./.docker/logs/nginx/ ./.docker/mysql/data
特定图像的日志:
Building node_dev
Step 1/8 : FROM node:8.16.0-slim
8.16.0-slim: Pulling from library/node
9fc222b64b0a: Pull complete
7d73b1e8f94b: Pull complete
1059045652d5: Pull complete
08cd60b80e4e: Pull complete
b7d875c65da4: Pull complete
Digest: sha256:0ec7ac448d11fa1d162fb6fd503ec83747c80dcf74bdf937b507b189b610756a
Status: Downloaded newer image for node:8.16.0-slim
---> 67857c9b26e1
Step 2/8 : ARG NODE_ENV=development
---> Running in da99a137d733
Removing intermediate container da99a137d733
---> 0f9b718d3f66
Step 3/8 : ARG NPM_TOKEN=3ea44a41-9293-4569-a235-a622ae216d60
---> Running in e339a4939029
Removing intermediate container e339a4939029
---> e47b42008bc3
Step 4/8 : ENV NODE_ENV=${NODE_ENV}
---> Running in fdc09147e9da
Removing intermediate container fdc09147e9da
---> 3b28ab5539d3
Step 5/8 : WORKDIR /home/node/app
---> Running in 44eef1d9293d
Removing intermediate container 44eef1d9293d
---> 2d07ecf3de2e
Step 6/8 : RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
---> Running in a47d5e22839b
Removing intermediate container a47d5e22839b
---> bd9f896846b7
Step 7/8 : RUN yarn global add gatsby-cli
---> Running in ca3e74d12df4
yarn global v1.15.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "gatsby-cli@2.7.47" with binaries:
- gatsby
Done in 15.51s.
Removing intermediate container ca3e74d12df4
---> bc8d15985ad0
Step 8/8 : RUN yarn install --force --no-lockfile
---> Running in 3f0e35e5487b
yarn install v1.15.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Rebuilding all packages...
Done in 0.04s.
Removing intermediate container 3f0e35e5487b
---> 485b9e9bccba
Successfully built 485b9e9bccba
Successfully tagged foobar/node_dev:latest
将服务命令更改为 sleep 300s
和 exect -it
和 ls -la
/home/node/app/node_modules
以查找:
.yarn-integrity
当 cat .yarn-integrity
我看到:
{
"systemParams": "linux-x64-57",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}
您在构建期间安装了节点包,并且如您从日志中看到的那样正确安装,没有任何错误。所以 docker-compose 或现有卷的问题。
因此,可以帮助您调试的一件事是创建卷,然后尝试使用 docker 运行 而不是 docker-compose。
docker volume create my_node_modules
docker run -it --rm -v my_node_modules:/home/node/app foobar/node_dev:lates bash -c "cd /home/node/app;npm list"
现在通过附加任何容器来检查体积以验证行为
docker run -it --rm -v my_node_modules:/home/test/ node:alpine ash -c "cd /home/test/;npm list"
或者另一种选择是在 运行 时安装软件包,然后安装的软件包将在任何卷中可用。
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn install && yarn start'
验证包是否退出尝试 运行 没有 docker-compose。
docker run -it --rm foobar/node_dev:lates bash -c "cd /home/node/app;npm list"
移动 yarn install
到入口点或不附加节点模块的卷。
我找到了一个解决方案,通过 COPY 指令利用 Docker 的缓存系统,我已将其设置为 COPY package.json、package-lock.json 和 yarn.lock;它缓存构建步骤并且仅在文件有任何差异时更新,否则跳过重新安装包。
总而言之,Docker compose 中的服务与卷保持不变,遵循社区中针对 nodejs 项目共享的最佳实践。
我们可以在volumes
中看到一个bind-mount ./foobar-blog-ui/:/home/node/app
,它将宿主机上的App源代码挂载到容器中的app目录中。这允许一个快速的开发环境,因为我们在主机中所做的更改会立即填充到容器中,否则不可能这样做。
最后是 node_modules
的命名卷,我将其命名为 ui_node_modules
,这很难理解,因为我们首先绑定安装包含根目录的应用程序源代码,其中 node_modules
坐下。 npm install
运行时 node_modules
目录在容器中创建,对吗?但是我们声明的 bind-mount
隐藏了它。因此,名为 ui_node_modules
的命名 node_modules
卷通过将 /home/node/app/node_modules
目录的内容持久化到容器中并绕过隐藏的 bind-mount
.
来解决它。
node_dev:
build:
context: .
dockerfile: ./.docker/dockerFiles/node.yml
image: foobar/node_dev:latest
container_name: node_dev
working_dir: /home/node/app
ports:
- 8000:8000
- 9000:9000
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/
volumes:
- ./foobar-blog-ui/:/home/node/app
- ui_node_modules:/home/node/app/node_modules
- ui_gatsbycli_node_module:/usr/local/lib/node_modules/gatsby-cli
- ./.docker/scripts/wait-for-it.sh:/home/node/wait-for-it.sh
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn start'
depends_on:
- mysql
- wordpress
networks:
- foobar-wordpress-network
volumes:
ui_node_modules:
ui_gatsbycli_node_module:
但是 Docker 文件包含复制包的指令*。json 文件有助于确定何时应更新指令步骤或层的 Docker 缓存。
FROM node:8.16.0-slim
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
# The package files should use Docker cache system
COPY ./foobar-blog-ui/package*.json .
COPY ./foobar-blog-ui/yarn.lock .
RUN yarn global add gatsby-cli
RUN yarn install
RUN apt-get update
RUN apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx
EXPOSE 8000
希望这对以后的其他人有所帮助!
什么原因导致 yarn/npm 安装时未在卷中安装任何软件包?
我有一个 Docker 文件,其中包含 运行 纱线安装的说明(使用 NPM 和 YARN 进行了测试),但是容器内的包 node_modules
目录是空的。如果我 exec -it service_name bash
和 运行 手动安装命令,它会正确安装包。
我在重构后注意到了这一点,我有一个 Worker 服务执行安装过程,第二个 运行 开发服务器。决定将所有内容都保留在相同的 Docker-compose 声明中,但由于问题开始发生,它仍然存在。尝试完全重置等但没有成功(关闭、rm 容器、p运行e 等)。
Docker-compose 文件中声明的相关服务:
node_dev:
build:
context: .
dockerfile: ./.docker/dockerFiles/node.yml
image: foobar/node_dev:latest
container_name: node_dev
working_dir: /home/node/app
ports:
- 8000:8000
- 9000:9000
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/
volumes:
- ./foobar-blog-ui/:/home/node/app
- ui_node_modules:/home/node/app/node_modules
- ui_gatsbycli_node_module:/usr/local/lib/node_modules/gatsby-cli
- ./.docker/scripts/wait-for-it.sh:/home/node/wait-for-it.sh
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn start'
depends_on:
- mysql
- wordpress
networks:
- foobar-wordpress-network
服务中的相关 Volumes
引用:
volumes:
ui_node_modules:
ui_gatsbycli_node_module:
最后,生成图片的Docker文件:
FROM node:8.16.0-slim
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
WORKDIR /home/node/app
RUN apt-get update
RUN apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx
RUN yarn global add gatsby-cli
RUN yarn install
此外,尝试 yarn install --force --no-lockfile
并确保它在项目根目录中没有任何包或 yarn 锁定文件的情况下进行测试,反之亦然。
我发现这很奇怪,肯定是某个地方的错字,但我还没有发现。
主机系统是 macOS Mojave。
我想提一下,如果 exec -it service_name bash
并执行 NPM/YARN 安装,node_modules 会填充软件包。
在我做的大多数测试之前,我还尝试通过以下方式重置:
docker-compose stop
docker-compose rm -f
docker volume prune -f
docker network prune -f
现在测试了:
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker volume prune -f
docker volume rm $(docker volume ls -qf dangling=true)
docker network prune -f
docker system prune --all --force --volumes
rm -rf ./.docker/certs/ ./.docker/certs-data/ ./.docker/logs/nginx/ ./.docker/mysql/data
特定图像的日志:
Building node_dev
Step 1/8 : FROM node:8.16.0-slim
8.16.0-slim: Pulling from library/node
9fc222b64b0a: Pull complete
7d73b1e8f94b: Pull complete
1059045652d5: Pull complete
08cd60b80e4e: Pull complete
b7d875c65da4: Pull complete
Digest: sha256:0ec7ac448d11fa1d162fb6fd503ec83747c80dcf74bdf937b507b189b610756a
Status: Downloaded newer image for node:8.16.0-slim
---> 67857c9b26e1
Step 2/8 : ARG NODE_ENV=development
---> Running in da99a137d733
Removing intermediate container da99a137d733
---> 0f9b718d3f66
Step 3/8 : ARG NPM_TOKEN=3ea44a41-9293-4569-a235-a622ae216d60
---> Running in e339a4939029
Removing intermediate container e339a4939029
---> e47b42008bc3
Step 4/8 : ENV NODE_ENV=${NODE_ENV}
---> Running in fdc09147e9da
Removing intermediate container fdc09147e9da
---> 3b28ab5539d3
Step 5/8 : WORKDIR /home/node/app
---> Running in 44eef1d9293d
Removing intermediate container 44eef1d9293d
---> 2d07ecf3de2e
Step 6/8 : RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
---> Running in a47d5e22839b
Removing intermediate container a47d5e22839b
---> bd9f896846b7
Step 7/8 : RUN yarn global add gatsby-cli
---> Running in ca3e74d12df4
yarn global v1.15.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "gatsby-cli@2.7.47" with binaries:
- gatsby
Done in 15.51s.
Removing intermediate container ca3e74d12df4
---> bc8d15985ad0
Step 8/8 : RUN yarn install --force --no-lockfile
---> Running in 3f0e35e5487b
yarn install v1.15.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Rebuilding all packages...
Done in 0.04s.
Removing intermediate container 3f0e35e5487b
---> 485b9e9bccba
Successfully built 485b9e9bccba
Successfully tagged foobar/node_dev:latest
将服务命令更改为 sleep 300s
和 exect -it
和 ls -la
/home/node/app/node_modules
以查找:
.yarn-integrity
当 cat .yarn-integrity
我看到:
{
"systemParams": "linux-x64-57",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}
您在构建期间安装了节点包,并且如您从日志中看到的那样正确安装,没有任何错误。所以 docker-compose 或现有卷的问题。
因此,可以帮助您调试的一件事是创建卷,然后尝试使用 docker 运行 而不是 docker-compose。
docker volume create my_node_modules
docker run -it --rm -v my_node_modules:/home/node/app foobar/node_dev:lates bash -c "cd /home/node/app;npm list"
现在通过附加任何容器来检查体积以验证行为
docker run -it --rm -v my_node_modules:/home/test/ node:alpine ash -c "cd /home/test/;npm list"
或者另一种选择是在 运行 时安装软件包,然后安装的软件包将在任何卷中可用。
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn install && yarn start'
验证包是否退出尝试 运行 没有 docker-compose。
docker run -it --rm foobar/node_dev:lates bash -c "cd /home/node/app;npm list"
移动 yarn install
到入口点或不附加节点模块的卷。
我找到了一个解决方案,通过 COPY 指令利用 Docker 的缓存系统,我已将其设置为 COPY package.json、package-lock.json 和 yarn.lock;它缓存构建步骤并且仅在文件有任何差异时更新,否则跳过重新安装包。
总而言之,Docker compose 中的服务与卷保持不变,遵循社区中针对 nodejs 项目共享的最佳实践。
我们可以在volumes
中看到一个bind-mount ./foobar-blog-ui/:/home/node/app
,它将宿主机上的App源代码挂载到容器中的app目录中。这允许一个快速的开发环境,因为我们在主机中所做的更改会立即填充到容器中,否则不可能这样做。
最后是 node_modules
的命名卷,我将其命名为 ui_node_modules
,这很难理解,因为我们首先绑定安装包含根目录的应用程序源代码,其中 node_modules
坐下。 npm install
运行时 node_modules
目录在容器中创建,对吗?但是我们声明的 bind-mount
隐藏了它。因此,名为 ui_node_modules
的命名 node_modules
卷通过将 /home/node/app/node_modules
目录的内容持久化到容器中并绕过隐藏的 bind-mount
.
node_dev:
build:
context: .
dockerfile: ./.docker/dockerFiles/node.yml
image: foobar/node_dev:latest
container_name: node_dev
working_dir: /home/node/app
ports:
- 8000:8000
- 9000:9000
environment:
- NODE_ENV=development
- GATSBY_WEBPACK_PUBLICPATH=/
volumes:
- ./foobar-blog-ui/:/home/node/app
- ui_node_modules:/home/node/app/node_modules
- ui_gatsbycli_node_module:/usr/local/lib/node_modules/gatsby-cli
- ./.docker/scripts/wait-for-it.sh:/home/node/wait-for-it.sh
command: /bin/bash -c '/home/node/wait-for-it.sh wordpress-reverse-proxy:80 -t 10 -- yarn start'
depends_on:
- mysql
- wordpress
networks:
- foobar-wordpress-network
volumes:
ui_node_modules:
ui_gatsbycli_node_module:
但是 Docker 文件包含复制包的指令*。json 文件有助于确定何时应更新指令步骤或层的 Docker 缓存。
FROM node:8.16.0-slim
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
# The package files should use Docker cache system
COPY ./foobar-blog-ui/package*.json .
COPY ./foobar-blog-ui/yarn.lock .
RUN yarn global add gatsby-cli
RUN yarn install
RUN apt-get update
RUN apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx
EXPOSE 8000
希望这对以后的其他人有所帮助!