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

如何在Dockerfile中基于Turborepo构建Astro.build应用

问题

我的Dockerfile配置如下:

FROM node:lts-alpine AS base

FROM base AS builder
RUN apk update && apk add --no-cache libc6-compat
# Set working directory
WORKDIR /repo
RUN npm install -g turbo
COPY . .
COPY ./apps/page/.env.docker ./apps/page/.env

RUN turbo prune --scope=@myturborepo/page --docker

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

# First install the dependencies (as they change less often)
COPY --from=builder /repo/out/json/ .
COPY --from=builder /repo/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN corepack enable
RUN pnpm install --frozen-lockfile

COPY --from=builder /repo/out/full/ .

RUN pnpm dlx turbo run build --filter=@myturborepo/page

FROM base AS production
WORKDIR /app

ENV NODE_ENV=production

COPY --from=installer /repo/apps/page/astro.config.mjs .
COPY --from=installer /repo/apps/page/package.json .
COPY --from=installer /repo/apps/page/node_modules .
COPY --from=installer /repo/apps/page/dist ./dist

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

USER astrojs

ARG PORT=4321
ENV PORT=$PORT
ENV HOST="0.0.0.0"

CMD ["node", "dist/server/entry.mjs"]

参考Next.js示例编写,但运行时提示找不到已在package.json中声明的react包。查看容器内文件发现,node_modules中的符号链接指向../../node_modules,因turbo prune等操作导致该路径不存在。尝试全量复制应用构建虽能运行,但镜像体积达700MB左右,而同类Next.js镜像仅约190MB。请问遗漏了哪些步骤或操作有误?

解决方案

问题根源

  • pnpm软链接失效:pnpm采用 workspace 级共享依赖策略,apps/page/node_modules里的依赖是指向仓库根目录../../node_modules的软链接。但生产阶段只复制了apps/page/node_modules,根目录的依赖文件夹不存在,导致软链接失效,找不到react这类共享依赖。
  • 镜像未精简依赖:全量复制会带上devDependencies和未用到的冗余依赖,直接导致镜像体积暴涨。

修复步骤

1. 生成独立的生产依赖目录

在installer阶段完成构建后,进入apps/page目录单独安装仅生产依赖,规避软链接问题:

# 在installer阶段的build命令后新增以下内容
WORKDIR /repo/apps/page
RUN pnpm install --prod --frozen-lockfile

2. 调整生产镜像的文件复制逻辑

生产阶段直接复制installer阶段中page目录下的独立生产依赖,而非原workspace的软链接依赖:

FROM base AS production
WORKDIR /app

ENV NODE_ENV=production

# 直接从installer的page目录复制文件,确保依赖路径有效
COPY --from=installer /repo/apps/page/astro.config.mjs .
COPY --from=installer /repo/apps/page/package.json .
COPY --from=installer /repo/apps/page/node_modules ./node_modules
COPY --from=installer /repo/apps/page/dist ./dist

# 后续用户权限配置不变
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 astrojs

USER astrojs

ARG PORT=4321
ENV PORT=$PORT
ENV HOST="0.0.0.0"

CMD ["node", "dist/server/entry.mjs"]

3. 额外体积精简技巧(可选)

  • 清理apk缓存:在每个apk命令后追加&& rm -rf /var/cache/apk/*,减少镜像层体积。
  • 用pnpm prune --prod替代单独安装:在installer阶段构建完成后,执行pnpm prune --prod清理dev依赖,再复制到生产镜像。

完整修复后的Dockerfile

FROM node:lts-alpine AS base

FROM base AS builder
RUN apk update && apk add --no-cache libc6-compat && rm -rf /var/cache/apk/*
WORKDIR /repo
RUN npm install -g turbo
COPY . .
COPY ./apps/page/.env.docker ./apps/page/.env

RUN turbo prune --scope=@myturborepo/page --docker

FROM base AS installer
RUN apk update && apk add --no-cache libc6-compat && rm -rf /var/cache/apk/*
WORKDIR /repo

COPY --from=builder /repo/out/json/ .
COPY --from=builder /repo/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN corepack enable
RUN pnpm install --frozen-lockfile

COPY --from=builder /repo/out/full/ .
RUN pnpm dlx turbo run build --filter=@myturborepo/page

# 生成page的独立生产依赖目录
WORKDIR /repo/apps/page
RUN pnpm install --prod --frozen-lockfile

FROM base AS production
WORKDIR /app

ENV NODE_ENV=production

COPY --from=installer /repo/apps/page/astro.config.mjs .
COPY --from=installer /repo/apps/page/package.json .
COPY --from=installer /repo/apps/page/node_modules ./node_modules
COPY --from=installer /repo/apps/page/dist ./dist

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 astrojs

USER astrojs

ARG PORT=4321
ENV PORT=$PORT
ENV HOST="0.0.0.0"

CMD ["node", "dist/server/entry.mjs"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:31:05