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

NextJS 13.5.3 Docker构建失败:JSON输入意外结束错误求助

问题

本地执行yarn build完全正常,但Docker构建时失败,报错核心信息:

45.12    Collecting page data ...
46.10 SyntaxError: Unexpected end of JSON input

使用NextJS版本:13.5.3

完整Docker构建日志:

[+] Building 120.9s (12/12) FINISHED                                                    docker:desktop-linux
 => [internal] load .dockerignore                                                                       0.0s
 => => transferring context: 111B                                                                       0.0s
 => [internal] load build definition from Dockerfile                                                    0.0s
 => => transferring dockerfile: 2.21kB                                                                  0.0s
 => [internal] load metadata for docker.io/library/node:alpine                                          3.3s
 => [auth] library/node:pull token for registry-1.docker.io                                             0.0s
 => [1/7] FROM docker.io/library/node:alpine@sha256:37750e51d61bef92165b2e29a77da4277ba0777258446b7a9c  0.0s
 => [internal] load build context                                                                       0.1s
 => => transferring context: 215.17kB                                                                   0.1s
 => CACHED [2/7] WORKDIR /app                                                                           0.0s
 => [3/7] RUN apk add yarn                                                                              3.1s
 => [4/7] COPY package.json yarn.lock ./                                                                0.0s
 => [5/7] RUN yarn install                                                                             67.4s
 => [6/7] COPY . .                                                                                      0.1s 
 => ERROR [7/7] RUN yarn build                                                                         46.9s 
------                                                                                                       
 > [7/7] RUN yarn build:                                                                                     
0.725 yarn run v1.22.19                                                                                      
0.762 $ next build                                                                                           
1.357 Attention: Next.js now collects completely anonymous telemetry regarding usage.                        
1.357 This information is used to shape Next.js' roadmap and prioritize features.                            
1.357 You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
1.357 https://nextjs.org/telemetry
1.357 
1.445    Creating an optimized production build ...
34.52  ✓ Compiled successfully
34.53    Linting and checking validity of types ...
36.95  ⨯ ESLint: Failed to load config "prettier" to extend from. Referenced from: /app/.eslintrc.json
45.12    Collecting page data ...
46.10 SyntaxError: Unexpected end of JSON input
46.10     at JSON.parse (<anonymous>)
46.10     at 1634 (/app/.next/server/chunks/1669.js:1:162)
46.10     at t (/app/.next/server/webpack-runtime.js:1:143)
46.10     at 4582 (/app/.next/server/app/api/articles/[articleId]/questions/[descriptorId]/route.js:1:1251)
46.10     at t (/app/.next/server/webpack-runtime.js:1:143)
46.10     at t (/app/.next/server/app/api/articles/[articleId]/questions/[descriptorId]/route.js:1:3287)
46.10     at /app/.next/server/app/api/articles/[articleId]/questions/[descriptorId]/route.js:1:3350
46.10     at t.X (/app/.next/server/webpack-runtime.js:1:1275)
46.10     at /app/.next/server/app/api/articles/[articleId]/questions/[descriptorId]/route.js:1:3300
46.10     at Object.<anonymous> (/app/.next/server/app/api/articles/[articleId]/questions/[descriptorId]/route.js:1:3377)
46.11 
46.11 > Build error occurred
46.12 Error: Failed to collect page data for /api/articles/[articleId]/questions/[descriptorId]
46.12     at /app/node_modules/next/dist/build/utils.js:1178:15
46.12     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
46.12   type: 'Error'
46.12 }
46.26 error Command failed with exit code 1.
46.26 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
------
Dockerfile:98
--------------------
  96 |     
  97 |     # Build the application
  98 | >>> RUN yarn build
  99 |     
 100 |     # Expose the port
--------------------
ERROR: failed to solve: process "/bin/sh -c yarn build" did not complete successfully: exit code: 1

对应的API路由文件api/articles/questions/[descriptorId]/route.ts代码:

import db from "@/configs/firestore-config";
import * as z from "zod"

import { authOptions } from "@/lib/nextauth";
import { getServerSession } from "next-auth";
import { NextRequest } from "next/server";

const routeContextSchema = z.object({
    params: z.object({
        articleId: z.string(),
        descriptorId: z.string(),
    }),
})

const articleRecordSchema = z.object({
    answer: z.string(),
    timeRecorded: z.number(),
})

export async function POST(
    req: Request,
    context: z.infer<typeof routeContextSchema>
) {
    try {
        const { params } = routeContextSchema.parse(context)
        const articleId = params.articleId;
        const descriptorId = params.descriptorId;

        const session = await getServerSession(authOptions);
        if (!session) {
            return new Response(JSON.stringify({
                message: 'Unauthorized',
            }), { status: 403 })
        }
        const json = await req.json();
        const body = articleRecordSchema.parse(json);
        const answer = body.answer;
        const timeRecorded = body.timeRecorded;
        console.log('answer', answer);
        console.log('timeRecorded', timeRecorded);

        const userId = session.user.id;
        // get article
        const articleRef = db.collection('articles').doc(articleId);
        const articleSnapshot = await articleRef.get();
        const article = articleSnapshot.data();

        console.log('descriptorId', descriptorId);
        // get question
        const question = article?.questions.multiple_choice_questions.find((question: { descriptor_id: string; }) => question.descriptor_id === descriptorId);

        // get correct answer
        const correctAnswer = question.answers.answer_a;

        // check answer
        const isCorrect = answer === correctAnswer;
        console.log('answer', answer);
        console.log('correctAnswer', correctAnswer);

        // creaet new user-article-record 
        // if user-article-record exists, update it
        const userArticleRecordRef = db.collection('user-article-records').doc(`${userId}-${articleId}`);
        const userArticleRecordSnapshot = await userArticleRecordRef.get();

        const updateRecordData = {
            articleId: articleId,
            userId: userId,
            questions: [
                {
                    descriptorId: descriptorId,
                    isCorrect: isCorrect,
                }
            ],
            timeRecorded: timeRecorded,
            status: 'uncompleted', // uncompleted, completed
            createdAt: new Date(),
            updatedAt: new Date(),
        }
        if (userArticleRecordSnapshot.exists) {
            // update user-article-record
            const userArticleRecord = userArticleRecordSnapshot.data();
            const questions = userArticleRecord?.questions;
            const question = questions.find((question: { descriptorId: string; }) => question.descriptorId === descriptorId);
            if (question) {
                question.isCorrect = isCorrect;
            } else {
                questions.push({
                    descriptorId: descriptorId,
                    isCorrect: isCorrect,
                })
            }
            await userArticleRecordRef.update({
                questions: questions,
                timeRecorded: timeRecorded,
                updatedAt: new Date(),
            });
        } else {
            // create new user-article-record
            await userArticleRecordRef.set(updateRecordData);
        }

        return new Response(JSON.stringify({
            data: {
                isCorrect: isCorrect,
                correctAnswer: correctAnswer,
            }
        }),
            { status: 200 })
    } catch (error) {
        console.log('error', error);
        return new Response(JSON.stringify({
            message: 'Internal server error',
            error: `errors: ${error}`
        }), { status: 500 })

    }
}
解决方案

1. 修复ESLint配置警告

日志中先出现ESLint加载prettier配置失败的警告,虽然不是直接报错原因,但会影响构建环境稳定性:

  • 检查.eslintrc.json的extends数组,确认prettier配置项正确
  • 执行yarn add eslint-config-prettier --dev安装依赖,再重新构建

2. 解决构建阶段API路由的JSON解析错误

核心问题是NextJS构建时会静态分析API路由代码,Docker环境缺少本地的环境变量或数据库连接权限,导致数据异常触发JSON解析失败:

2.1 跳过构建阶段的数据库操作

在API路由的POST函数开头添加判断,避免构建时执行数据库逻辑:

// 构建阶段直接返回,不执行数据库操作
if (process.env.NEXT_PHASE === 'build') {
  return new Response(JSON.stringify({ message: 'Build phase skip' }), { status: 200 });
}

2.2 同步Docker环境变量

本地构建依赖.env.local里的Firestore配置,但Docker构建时未传递这些变量:

  • 在Dockerfile中添加环境变量,或使用docker build --env-file .env传递配置文件
  • 确保Firestore的项目ID、密钥等配置在Docker构建时可用

2.3 补充空值检查避免异常

代码中存在多处未处理的空值访问(如article?.questions、question.answers),构建时数据库返回空数据会触发异常:

// 获取文章后检查是否存在
if (!article) {
  return new Response(JSON.stringify({ message: 'Article not found' }), { status: 404 });
}
// 获取问题后检查是否存在
const question = article.questions?.multiple_choice_questions?.find(q => q.descriptor_id === descriptorId);
if (!question) {
  return new Response(JSON.stringify({ message: 'Question not found' }), { status: 404 });
}
// 检查问题答案是否存在
if (!question.answers) {
  return new Response(JSON.stringify({ message: 'Question answers missing' }), { status: 404 });
}
const correctAnswer = question.answers.answer_a;

2.4 调整Docker构建依赖逻辑

确保Docker构建时安装完整依赖(包括开发依赖):
修改Dockerfile中的安装命令:

RUN yarn install --production=false

3. 本地模拟生产构建验证

执行NODE_ENV=production yarn build,复现Docker构建环境,快速排查问题,无需每次构建镜像

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:57:05