You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署turborepo(api+web)时遇权限错误:无法创建/nonexistent目录

Turborepo容器化权限错误(EACCES: permission denied, mkdir '/nonexistent')解决

问题描述

尝试将包含API和Web应用的Turborepo进行Docker容器化,参考官方示例编写对应的Dockerfile后,运行容器时出现如下权限错误:

Attaching to api, web
api  | Internal Error: EACCES: permission denied, mkdir '/nonexistent'
api  | Error: EACCES: permission denied, mkdir '/nonexistent'
api exited with code 1
web  | Internal Error: EACCES: permission denied, mkdir '/nonexistent'
web  | Error: EACCES: permission denied, mkdir '/nonexistent'
web exited with code 1

提供的文件内容

Web服务Dockerfile

FROM node:18 AS base
RUN npm install turbo -g
RUN corepack enable

# This Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
# Make sure you update both files!

FROM base AS builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
# RUN apk add --no-cache libc6-compat
# RUN apk update
# Set working directory
WORKDIR /app
COPY . .
RUN turbo prune web --docker

# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
# RUN apk add --no-cache libc6-compat
# RUN apk update
WORKDIR /app

# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
RUN pnpm install

# Build the project
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json

# Uncomment and use build args to enable remote caching
# ARG TURBO_TEAM
# ENV TURBO_TEAM=$TURBO_TEAM

# ARG TURBO_TOKEN
# ENV TURBO_TOKEN=$TURBO_TOKEN

RUN pnpm prettier:fix
RUN turbo build --filter=web...

FROM base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

COPY --from=installer /app/apps/web/next.config.js .
COPY --from=installer /app/apps/web/package.json .

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public

USER nextjs

CMD ["pnpm", "start"]

API服务Dockerfile

FROM node:18 AS base
RUN npm install turbo -g
RUN corepack enable

# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs.

FROM base AS builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
# RUN apk add --no-cache libc6-compat
# RUN apk update
# Set working directory
WORKDIR /app
COPY . .
RUN turbo prune api --docker

# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
# RUN apk add --no-cache libc6-compat
# RUN apk update
WORKDIR /app

# First install dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
RUN pnpm install

# Build the project and its dependencies
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json

# Uncomment and use build args to enable remote caching
# ARG TURBO_TEAM
# ENV TURBO_TEAM=$TURBO_TEAM

# ARG TURBO_TOKEN
# ENV TURBO_TOKEN=$TURBO_TOKEN

RUN turbo build --filter=api...

FROM base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 expressjs
RUN adduser --system --uid 1001 expressjs
USER expressjs
COPY --from=installer --chown=expressjs:expressjs /app .

USER expressjs

CMD ["pnpm", "start"]

项目结构

├── apps
├── docker-compose.yml
├── docs
├── FUNDING.json
├── LICENSE
├── node_modules
├── package.json
├── packages
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── prettier.config.js
├── script
└── turbo.json
apps/
├── api
│   ├── dist
│   ├── Dockerfile
│   ├── index.html
│   ├── node_modules
│   ├── package.json
│   ├── src
│   └── tsconfig.json
├── README.md
└── web
    ├── Dockerfile
    ├── next.config.js
    ├── next-env.d.ts
    ├── node_modules
    ├── package.json
    ├── postcss.config.js
    ├── public
    ├── script
    ├── src
    ├── tailwind.config.js
    ├── tsconfig.json
    └── tsconfig.tsbuildinfo

解决方法

错误原因

/nonexistent是pnpm在非root用户运行时默认尝试使用的缓存目录,但该目录不存在且非root用户无权限创建。同时,当前Dockerfile存在工作目录不匹配、文件复制不完整的问题,导致启动命令无法正确执行。

Web服务Dockerfile修复

修改runner阶段内容,解决缓存目录权限并确保启动路径正确:

FROM base AS runner
WORKDIR /app

# 创建pnpm缓存目录并赋予当前用户权限
RUN mkdir -p /home/nextjs/.pnpm-store && chown -R nextjs:nodejs /home/nextjs/.pnpm-store
ENV PNPM_HOME="/home/nextjs/.pnpm-store"
ENV PATH="$PNPM_HOME:$PATH"

# 创建非root用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

# 复制完整的Web应用构建产物
COPY --from=installer --chown=nextjs:nodejs /app/apps/web ./apps/web

# 切换到Web应用目录启动服务
WORKDIR /app/apps/web

CMD ["pnpm", "start"]

API服务Dockerfile修复

同样修改runner阶段:

FROM base AS runner
WORKDIR /app

# 创建pnpm缓存目录并赋予当前用户权限
RUN mkdir -p /home/expressjs/.pnpm-store && chown -R expressjs:expressjs /home/expressjs/.pnpm-store
ENV PNPM_HOME="/home/expressjs/.pnpm-store"
ENV PATH="$PNPM_HOME:$PATH"

# 创建非root用户
RUN addgroup --system --gid 1001 expressjs
RUN adduser --system --uid 1001 expressjs
USER expressjs

# 复制完整的API应用构建产物
COPY --from=installer --chown=expressjs:expressjs /app/apps/api ./apps/api

# 切换到API应用目录启动服务
WORKDIR /app/apps/api

CMD ["pnpm", "start"]

额外注意事项

  • 确保每个应用的package.json中start命令正确:Web应用应为next start,API应用应为node dist/index.js(根据实际编译产物路径调整)
  • 避免复制整个/app目录到runner阶段,仅复制对应应用的内容,减少镜像体积同时避免权限混乱
  • 若使用Docker Compose,确保容器挂载的卷(如果有)权限配置正确

内容的提问来源于stack exchange,提问作者chaso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:27:06