Skip to content

Commit f612305

Browse files
committed
chore: dockerfile error
1 parent 2c78bd2 commit f612305

File tree

1 file changed

+62
-38
lines changed

1 file changed

+62
-38
lines changed

Dockerfile

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,90 @@
1-
# syntax=docker.io/docker/dockerfile:1
2-
1+
# 指定基础镜像版本,确保每次构建都是幂等的
32
FROM node:18-alpine AS base
43

5-
# Install dependencies only when needed
6-
FROM base AS deps
4+
FROM base AS builder
5+
76
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
87
RUN apk add --no-cache libc6-compat
8+
9+
# Node v16.13 开始支持 corepack 用于管理第三方包管理器
10+
# 锁定包管理器版本,确保 CI 每次构建都是幂等的
11+
# RUN corepack enable && corepack prepare pnpm@latest --activate
12+
RUN corepack enable && corepack prepare [email protected] --activate
13+
914
WORKDIR /app
1015

11-
# Install dependencies based on the preferred package manager
12-
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
13-
RUN \
14-
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
15-
elif [ -f package-lock.json ]; then npm ci; \
16-
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
17-
else echo "Lockfile not found." && exit 1; \
18-
fi
16+
# pnpm fetch does require only lockfile
17+
# 注意还需要复制 `.npmrc`,因为里面可能包含 npm registry 等配置,下载依赖需要用到
18+
COPY pnpm-lock.yaml ./
1919

20+
# 推荐使用 pnpm fetch 命令下载依赖到 virtual store,专为 docker 构建优化
21+
# 参考:https://pnpm.io/cli/fetch
22+
RUN pnpm fetch
2023

21-
# Rebuild the source code only when needed
22-
FROM base AS builder
23-
WORKDIR /app
24-
COPY --from=deps /app/node_modules ./node_modules
24+
# 将本地文件复制到构建上下文
2525
COPY . .
2626

27-
# Next.js collects completely anonymous telemetry data about general usage.
28-
# Learn more here: https://nextjs.org/telemetry
2927
# Uncomment the following line in case you want to disable telemetry during the build.
30-
# ENV NEXT_TELEMETRY_DISABLED=1
28+
ENV NEXT_TELEMETRY_DISABLED 1
3129

32-
RUN \
33-
if [ -f yarn.lock ]; then yarn run build; \
34-
elif [ -f package-lock.json ]; then npm run build; \
35-
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
36-
else echo "Lockfile not found." && exit 1; \
37-
fi
30+
# 基于 virtual store 生成 node_modules && 打包构建
31+
# 此处不需要与 package registry 进行通信,因此依赖安装速度极快
32+
# 注意 PNPM v8.4.0 版本有一个 breaking change
33+
# 当 `node_modules` 存在,运行 `pnpm install` 会出现命令行交互操作,导致 CI 挂掉
34+
# 这里加上 `--force` 参数,关闭命令行交互操作
35+
RUN pnpm install --offline --force && pnpm build
3836

39-
# Production image, copy all the files and run next
4037
FROM base AS runner
41-
WORKDIR /app
4238

43-
ENV NODE_ENV=production
44-
# Uncomment the following line in case you want to disable telemetry during runtime.
45-
# ENV NEXT_TELEMETRY_DISABLED=1
39+
# RUN apk update && apk add --no-cache git
40+
RUN apk add --no-cache curl
41+
42+
# 如果需要是用 TZ 环境变量 实现时区控制,需要安装 tzdata 这个包
43+
# debian 的基础镜像默认情况下已经安装了 tzdata,而 ubuntu 并没有
44+
# RUN apk add --no-cache tzdata
4645

46+
ARG RUNTIME_ENV
47+
ENV RUNTIME_ENV=$RUNTIME_ENV
48+
ENV NODE_ENV production
49+
50+
# Docker 容器不推荐用 root 身份运行
51+
# 这边先建立一个特定的用户和用户组,为它分配必要的权限,使用 USER 切换到这个用户
52+
# 注意,如果不是 root 权限,对于可执行文件,需要修改权限,确保文件可以执行
4753
RUN addgroup --system --gid 1001 nodejs
4854
RUN adduser --system --uid 1001 nextjs
4955

50-
COPY --from=builder /app/public ./public
56+
# 设置时区
57+
# 在使用 Docker 容器时,系统默认的时区就是 UTC 时间(0 时区),和我们实际需要的北京时间相差八个小时
58+
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
59+
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
60+
61+
WORKDIR /app
62+
63+
# PNPM 有一个全局 store,项目中的 node_modules 实际上是全局 store 的 symlink
64+
# 正常需要从上一阶段同时复制 `node_modules` 和全局 store,这样才能正常运行
65+
# 但是由于 `standalone` 目录里面包含所有运行时依赖,且都是独立目录
66+
# 因此可以直接复制该目录,无需复制全局 store(如果复制还会增加镜像体积)
67+
# 另外运行需要的配置文件、dotfile 也都在 `standalone` 目录里面,无需单独复制
5168

52-
# Automatically leverage output traces to reduce image size
53-
# https://nextjs.org/docs/advanced-features/output-file-tracing
69+
# `standalone` 模式打包,默认包含服务端代码,没有客户端代码
70+
# 因为官方建议通过 CDN 托管,但也可以手动复制 `public`、`.next/static` 目录
71+
COPY --from=builder /app/public ./public
5472
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
5573
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
5674

75+
# 注意,`standalone` 目录下已经包含了服务端代码,无需再复制 `.next/server`
76+
# COPY --from=builder /app/.next/server ./.next/server
77+
5778
USER nextjs
5879

59-
EXPOSE 3000
80+
# Uncomment the following line in case you want to disable telemetry during runtime.
81+
ENV NEXT_TELEMETRY_DISABLED 1
82+
ENV PORT 3000
6083

61-
ENV PORT=3000
84+
# 默认暴露 80 端口
85+
EXPOSE 3000
6286

63-
# server.js is created by next build from the standalone output
64-
# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output
65-
ENV HOSTNAME="0.0.0.0"
87+
# 用 standalone 模式打包后,生成的 `standalone/node_modules` 目录下缺少 `.bin` 目录
88+
# 导致无法用 `next` 命令启动项目,但可以用 `node server.js` 启动
89+
# 参考:https://nextjs.org/docs/advanced-features/output-file-tracing
6690
CMD ["node", "server.js"]

0 commit comments

Comments
 (0)