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

Next.js应用部署K8s后无法找到静态资源问题排查

Next.js部署K8s后静态资源(JS/CSS)无法加载的问题解决

核心疑问解答:为什么浏览器请求_next而容器里是.next?

.next是Next.js构建后在服务器端存储编译产物、静态资源的内部工作目录,不会直接对外暴露。浏览器请求的/_next/*是Next.js服务器预设的路由路径,服务器会自动将这个请求映射到.next目录下的对应资源(比如.next/static里的文件),完全不需要手动创建_next文件夹——你之前复制.next到_next的操作是错误的,不符合Next.js的路由映射逻辑。

问题原因分析

从你的Dockerfile和报错信息来看,问题根源是静态资源的路径映射异常,结合你使用的Next.js standalone输出模式,可能的触发点包括:

  • Dockerfile中静态资源的复制路径不符合standalone模式的要求
  • K8s的Ingress/Service未正确转发/_next/*路径的请求
  • Next.js配置文件(next.config.js)存在错误(如basePath、assetPrefix设置不当)

分步解决方案

1. 确保Next.js配置开启standalone模式

检查你的next.config.js是否添加了output: 'standalone'配置,这是Dockerfile使用standalone模式的前提:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
  // 其他自定义配置...
}

module.exports = nextConfig

2. 修正Dockerfile的资源复制逻辑

调整runner阶段的文件复制步骤,确保静态资源被放到Next.js服务器期望的位置(原Dockerfile中手动创建.next目录的步骤可以删除):

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

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

# 复制standalone编译产物到工作目录
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
# 复制静态资源到服务器期望的路径
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# 复制public目录
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs

EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

3. 检查K8s的Ingress/Service配置

确保Ingress规则正确转发所有路径(包括/_next/*)到你的应用Service:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextjs-app-ingress
spec:
  rules:
  - host: your-domain.com # 替换为你的域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nextjs-app-service # 替换为你的Service名称
            port:
              number: 80

(如果使用裸IP访问,确保Service正确暴露了Pod的3000端口,且Ingress没有路径过滤限制)

4. 验证与排查

  • 重新构建镜像并更新K8s Deployment,等待Pod重启
  • 进入Pod执行ls -la ./.next/static,确认静态资源目录存在且有内容
  • 查看Pod日志:kubectl logs <你的Pod名称>,检查是否有静态资源加载的错误日志

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:35:08