node.js - 如何解决纱线构建错误 - 错误:ENOTEMPTY: directory not empty, rmdir '/frontend/out/node_modules/cacache/node_modules/.bin'
问题描述
我在 Docker Compose 中使用 NextJS、Django、Postgres、Nginx 部署项目,它在本地运行良好(ubunutu 18.04)。但是在服务器(ubuntu 20.04)中它会引发Error: ENOTEMPTY: directory not empty, rmdir '/frontend/out/node_modules/cacache/node_modules/.bin'
错误。如何解决这个问题。PS我正在使用wait-for.sh作为前端等待api服务准备好(否则我也会得到构建错误)并且我的本地docker版本是Docker version 19.03.12, build 48a66213fe
,我的服务器docker版本Docker version 19.03.11, build dd360c7
可能是错误的原因?
我用于前端服务的 Dockerfile:
USER root
WORKDIR /frontend
COPY . /frontend
# Add wait-for-it
COPY wait-for.sh wait-for.sh
RUN chmod +x wait-for.sh
RUN yarn
我的 docker-compose.yml:
services:
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=purple_postgres_user
- POSTGRES_PASSWORD=purple_p@ssW0rd
- POSTGRES_DB=purple_db
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
# command: ./manage.py purple.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./backend/:/home/purple_user/purple/
- static_volume:/home/purple_user/purple/static/
- media_volume:/home/purple_user/purple/media/
expose:
- 8000
ports:
- 8000:8000
env_file:
- ./.env.dev
depends_on:
- db
nginx:
build: ./nginx
ports:
- 80:80
volumes:
- static_volume:/var/www/staticfiles/
- media_volume:/var/www/mediafiles/
- build_folder:/var/www/frontend/
depends_on:
- web
frontend:
container_name: frontend
build:
context: ./frontend
volumes:
- build_folder:/frontend/out
depends_on:
- web
command: ./wait-for.sh web:8000 -- yarn build
volumes:
postgres_data:
static_volume:
media_volume:
build_folder:```
解决方案
Docker 中的命名卷是持久的。当你的docker-compose.yml
文件有
volumes:
- build_folder:/frontend/out
它会导致先前构建的结果存储在 中build_folder
,并且下次运行该容器时它们仍然存在。这就是导致您看到的错误消息的原因。
我会避免设置 Compose 服务只是为了为其他服务构建文件。相反,使用多阶段构建在映像构建时构建工件。相反,在您的 Nginx 映像 Dockerfile 中,构建前端应用程序:
FROM node:12 AS frontend
WORKDIR /frontend
COPY frontend/package.json frontend/yarn.lock .
RUN yarn install
COPY frontend .
RUN yarn build
FROM nginx
# ... whatever this Dockerfile had before ...
# (except, change `COPY stuff /image/path` to `COPY nginx/stuff /image/path`)
COPY --from=frontend /frontend/out /var/www/frontend
您可以对图像COPY
的静态文件使用类似的技术;要么使用额外的构建阶段,它们直接来自构建上下文,要么使用单独的构建图像的名称。(这有点难以编排,因为 Compose 不会对依赖构建进行排序。)这避免了类似的问题,即hide 的内容更改了两个图像中的静态文件。--from
web
COPY
COPY --from
static_volume
services:
nginx:
# The build context must be an ancestor of anything that
# it needs to `COPY` in. Since we `COPY` from both the `frontend`
# and `nginx` directories, we need to specify
build: .
ports: ['80:80']
depends_on: [web]
# No `volumes:`; the image is self-contained
# No build-only `frontend` container
推荐阅读
- sql - 大查询 - 使用关键字 @run_date 在外部分区表上安排查询
- kotlin - 一种在 kotlin 中锁定对特定资源的访问的简单方法
- reactjs - 使用 refs 将反应类转换为功能组件
- react-native - 有没有办法使用 expo 检测位置的“蓝牙扫描”是否打开?
- javascript - 是否可以检索远程网站的控制台命令的结果?
- python - 尝试从 csv 创建 spark 数据帧时出错
- javascript - 创建 Discord.js 分页并使用“通道”出错
- android - Ionic Firestore 安全问题和 Firestore 规则
- webpack - 具有动态公共路径的 Webpack 文件加载器
- python - SELECT BETWEEN to date 和同一日期的两个不同时间