docker部署next.js
,解决 next 命令找不到 + bun 路径报错双问题
=> ERROR [app web-build 4/4] RUN npx next build 1.9s
------
> [app web-build 4/4] RUN npx next build:
1.707 ⨯ Failed to load next.config.ts, see more info here https://nextjs.org/docs/messages/next-config-error
1.708
1.708 > Build error occurred
1.712 Error: ENOENT: no such file or directory, open '/app/VERSION'
1.712 at Object.<anonymous> (next.config.compiled.js:17:47) {
1.712 errno: -2,
1.712 code: 'ENOENT',
1.712 syscall: 'open',
1.712 path: '/app/VERSION'
1.712 }
------
failed to solve: process "/bin/sh -c npx next build" did not complete successfully: exit code: 1
# 报错原因
构建阶段 `web-build` 工作目录是 `/app/web`,但 `next.config.ts` 读取路径写死了 `/app/VERSION`,当前阶段只复制到 `/app/web/VERSION`,根目录 `/app` 不存在这个文件,直接文件找不到。
## 完整修复 Dockerfile
```dockerfile
# 阶段1 bun 安装依赖
FROM oven/bun:1.3.13 AS deps
WORKDIR /app/web
COPY web/package.json web/bun.lock ./
RUN --mount=type=cache,target=/root/.bun/install/cache \
bun install --frozen-lockfile --cache-dir=/root/.bun/install/cache
RUN bun add @ffmpeg/ffmpeg @ffmpeg/util
# 先复制到/app根目录,再拷贝到web内,保证两个路径都有VERSION
COPY VERSION /app/VERSION
COPY CHANGELOG.md /app/CHANGELOG.md
COPY VERSION /app/web/VERSION
COPY CHANGELOG.md /app/web/CHANGELOG.md
COPY web ./
# 阶段2 node 构建层
FROM node:22-bookworm-slim AS web-build
WORKDIR /app/web
# 复制完整工程,包含/app根目录的VERSION文件
COPY --from=deps /app /app
RUN npx next build
# 阶段3 运行镜像
FROM node:22-bookworm-slim
WORKDIR /app
COPY VERSION /app/VERSION
COPY CHANGELOG.md /app/CHANGELOG.md
COPY --from=web-build /app/web/public /app/web/public
COPY --from=web-build /app/web/.next/standalone /app/web
COPY --from=web-build /app/web/.next/static /app/web/.next/static
ENV NODE_ENV=production
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
EXPOSE 3000
CMD ["sh", "-c", "cd /app/web && PORT=3000 node server.js"]
```
## 两处关键修复
1. deps 阶段复制文件时,同时放到 `/app` 根目录和 `/app/web`
```dockerfile
COPY VERSION /app/VERSION
COPY CHANGELOG.md /app/CHANGELOG.md
COPY VERSION /app/web/VERSION
COPY CHANGELOG.md /app/web/CHANGELOG.md
```
2. web-build 复制整层 `/app`,不只是 `/app/web`,保证构建时 `/app/VERSION` 存在
```dockerfile
COPY --from=deps /app /app
```
## 可选优化(推荐改代码根治)
修改 `next.config.ts` 读取 VERSION 的逻辑,改为相对路径,不用绝对 `/app/VERSION`:
```ts
import path from 'path'
const versionPath = path.resolve(__dirname, '../VERSION')
```
改完后就不需要重复复制文件,构建逻辑更干净。