Next.js 14独立模式Docker容器部署AWS AppRunner时健康检查失败,但本地运行正常
这种本地跑起来完全没问题,一上云就健康检查失联的情况真的太磨人了!结合你描述的细节和Next.js+AppRunner的常见踩坑点,我整理了几个最可能的突破口,你可以按顺序排查:
1. 90%概率的根因:监听地址环境变量搞混了!
你在Dockerfile里设置的是ENV HOSTNAME=0.0.0.0,但Next.js 14是靠HOST环境变量指定监听地址的,不是HOSTNAME!
Next.js在容器环境里默认可能会绑定到容器的内部私有IP(就是你日志里的ip-[some-generic-ip].aws-region.compute.internal),而不是0.0.0.0。本地Docker运行时,桥接网络会自动帮你转发内部IP的端口请求,但AppRunner的网络隔离更严格,负载均衡器根本没法从容器网络外部访问到这个私有IP。
紧急修复方案:把Dockerfile里的ENV HOSTNAME=0.0.0.0改成ENV HOST=0.0.0.0,重新构建镜像部署试试,这个坑我自己踩过好几次!
2. 检查Standalone模式的文件拷贝逻辑
你的Dockerfile在runner阶段的文件拷贝可能打乱了Next.js Standalone模式的目录结构:
# 你当前的拷贝逻辑 COPY --from=builder --chown=nextjs:nodejs /app/apps/api/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/apps/api/.next/server ./.next/server COPY --from=builder --chown=nextjs:nodejs /app/apps/api/.next/static ./apps/api/.next/static
其实Standalone模式下,.next/standalone目录已经打包了完整的运行环境,包括.next/server的内容,你额外拷贝的./.next/server可能会覆盖或冲突Standalone的预期结构。
建议修正为标准拷贝流程:
FROM base AS runner WORKDIR /app ENV NODE_ENV=production ENV HOST=0.0.0.0 # 重点修正这里 ENV PORT=3000 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # 拷贝Standalone核心运行文件 COPY --from=builder --chown=nextjs:nodejs /app/apps/api/.next/standalone ./ # 拷贝静态资源(如果有public目录也需要加上) COPY --from=builder --chown=nextjs:nodejs /app/apps/api/.next/static ./apps/api/.next/static COPY --from=builder --chown=nextjs:nodejs /app/apps/api/public ./apps/api/public USER nextjs EXPOSE 3000 # 确认server.js的路径和容器内的实际结构匹配 CMD ["node", "apps/api/server.js"]
你可以本地启动容器后,进入容器查看目录结构确认server.js的位置:docker exec -it <容器ID> ls -l /app,如果server.js直接在/app根目录,就把启动命令改成CMD ["node", "server.js"]。
3. AppRunner健康检查的细节补全
就算修复了网络绑定,也要确认这些细节:
- 健康检查路径和本地测试的完全一致(别小看大小写,Linux容器对路径大小写敏感)
- Terraform的AppRunner配置里,明确指定健康检查的端口为3000(虽然AppRunner会读EXPOSE,但手动指定更稳妥)
- 如果用TCP健康检查,确保Terraform的
health_check_config里type = "TCP",端口正确
4. 兜底排查点
- 试试降级Next.js到14.2.10(之前有用户反馈14.2.11+的Standalone模式存在小众的网络绑定bug),或者直接升级到最新版
- 检查Terraform的AppRunner配置,确保
network_configuration的egress_configuration设为PUBLIC(即使不用VPC,容器内部的DNS解析可能需要这个配置)
先优先试修改HOST=0.0.0.0这个点,这绝对是Next.js+AppRunner Standalone模式的Top1坑,好多人都会把HOST和HOSTNAME搞混!
内容来源于stack exchange

