逃离 Vercel:Next.js Docker 自托管完全指南

上个月底,我照例打开 Vercel 的账单页面。$47.32。
盯着这个数字看了三秒,脑子里快速计算:这个月博客流量也就多了 20%,怎么账单直接翻倍了?点开详细账单,才发现问题出在 serverless function 的调用次数上——一个 API 路由因为没做好缓存,每次页面刷新都要跑三次。
说实话,Vercel 的开发体验确实丝滑:git push 就自动部署,边缘网络全球加速,还有各种开箱即用的功能。但当你的项目流量稍微上去一点,账单就像坐火箭。$20 的 Pro 套餐只是起步价,真正烧钱的是那些按量计费的部分。
那一瞬间我突然意识到:是时候把这个项目搬出去了。
这篇文章记录了我把 Next.js 项目从 Vercel 迁移到 Docker 自托管的完整过程。踩过的坑、查过的文档、试过的配置,我都整理在这里了。如果你也在考虑自托管,或者已经尝试过但遇到了各种奇怪的问题(比如静态资源 404、流式渲染不工作),希望这篇能帮到你。
为什么要逃离 Vercel?
先说清楚,我不是要黑 Vercel。对于很多场景,它依然是最优解——尤其是企业级项目、需要全球边缘网络、或者团队没有运维能力的情况。但对于个人项目和小团队来说,成本确实是个硬伤。
Vercel 的定价逻辑
免费套餐看起来挺慷慨:100GB 带宽、100 万次 Edge Requests。问题是这些额度一个稍微有点流量的项目就不够用。一旦升级到 Pro($20/month),你会发现这只是入场券:
- Serverless Function 调用:超过 100 万次后按量计费
- 边缘函数执行时间:超过 100 万 GB-s 后加钱
- 图片优化:超过 5000 次后按次收费
- 带宽:超过 1TB 后每 GB 计费
最坑的是,这些用量很难提前预估。一个没做好缓存的 API 路由、一个被爬虫狂爬的页面,账单就会飙升。
自托管能省多少钱?
我算了笔账。我的项目在 Vercel 上每月大概 $35-50,波动取决于流量。迁移到 DigitalOcean 的 $12/month 服务器后:
- 服务器:$12/month(2核4GB,足够跑两三个 Next.js 应用)
- Cloudflare CDN:免费(反正也在用)
- 额外存储:$0(本地磁盘够用)
月省 $25-40,一年就是 $300-500。更重要的是,这个成本是固定的,不会因为流量突增而暴涨。
什么时候适合自托管?
不是所有人都该自托管。我觉得符合以下条件的可以考虑:
- ✅ 已经有一定的 Linux/Docker 基础
- ✅ 项目流量相对稳定,不需要全球边缘网络
- ✅ 可以接受 5-10 分钟的手动部署流程
- ✅ 预算敏感(个人项目、创业早期)
反过来,如果你是这些情况,还是老实用 Vercel:
- ❌ 团队没有运维能力,也不想学
- ❌ 流量波动巨大,需要自动扩缩容
- ❌ 需要 Vercel 的 Analytics、Edge Config 等专有功能
- ❌ 预算充足,开发效率更重要
想清楚再动手,别为了省钱把自己折腾得够呛。
Next.js Docker 部署核心配置
好,进入正题。Next.js 的 Docker 部署有三个核心配置点,搞定这三个,基本就不会出大问题。
1. Standalone 输出模式
这是最关键的一步。默认情况下,next build 会生成一堆文件,包括完整的 node_modules。放到 Docker 里体积巨大,启动也慢。
在 next.config.js 里加这一行:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfig跑 npm run build 后,你会看到 .next/standalone 目录。这个目录里有:
server.js:启动脚本- 精简过的
node_modules:只包含运行时需要的包 - 应用代码
关键点:standalone 模式不会自动复制 public 和 .next/static。这俩必须手动复制到 standalone 目录里,不然静态资源全 404。这个坑我踩了两天才发现。
2. 多阶段 Dockerfile
直接贴我在用的 Dockerfile,注释写得很清楚了:
# ============ 阶段 1: 依赖安装 ============
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# 只复制依赖清单,利用 Docker 缓存
COPY package.json package-lock.json ./
RUN npm ci
# ============ 阶段 2: 构建应用 ============
FROM node:20-alpine AS builder
WORKDIR /app
# 复制依赖和源码
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# 构建时的环境变量(如果需要)
ENV NEXT_TELEMETRY_DISABLED=1
# 构建
RUN npm run build
# ============ 阶段 3: 生产运行 ============
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# 创建非 root 用户(安全实践)
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# 复制 public 文件夹(静态资源)
COPY --from=builder /app/public ./public
# 复制 standalone 输出
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
# 复制 static 文件(CSS/JS 等构建产物)
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# 启动命令
CMD ["node", "server.js"]重点解释:
- 三阶段构建:依赖安装、构建、运行分开,最终镜像只包含运行时需要的文件,体积能从 1.5GB 降到 200MB
COPY --from=builder /app/public:别忘了这个,不然 favicon、robots.txt 都访问不到COPY ./.next/static:这个更关键,没有它所有 JS/CSS 都 404- 非 root 用户:安全实践,生产环境别用 root 跑应用
3. 环境变量的坑
这个我也踩了。Next.js 的环境变量分两种:
- 构建时变量:以
NEXT_PUBLIC_开头,会被编译进代码 - 运行时变量:服务端用的,比如数据库地址
Standalone 模式下,runtimeConfig 不工作。官方推荐用 App Router 的方式:
// app/api/example/route.ts
export async function GET() {
// 直接从 process.env 读取
const dbUrl = process.env.DATABASE_URL
// ...
}Docker 运行时传环境变量:
docker run -p 3000:3000 \
-e DATABASE_URL="postgres://..." \
-e API_KEY="xxx" \
your-image-name或者用 docker-compose.yml:
version: '3.8'
services:
nextjs:
image: your-image-name
ports:
- "3000:3000"
environment:
DATABASE_URL: "postgres://..."
API_KEY: "xxx"
restart: unless-stopped注意:NEXT_PUBLIC_ 开头的变量必须在构建时就设置好,运行时改不了。如果需要运行时动态配置,只能用服务端环境变量。
反向代理配置要点
你可以直接把 Next.js 容器暴露到公网,但真别这么干。裸奔的 Node.js 应用面对各种恶意请求、慢速攻击,扛不住多久。反向代理不是可选项,是必需品。
为什么需要反向代理?
- 安全防护:拦截恶意请求、限流、防 DDoS
- HTTPS 支持:统一管理 SSL 证书
- 多应用部署:一台服务器跑多个项目,通过域名/路径区分
- 静态资源缓存:减轻应用服务器压力
我用的是 Nginx,稳定可靠。如果你想要更简单的配置,Caddy 也不错(自动 HTTPS,配置文件更人性化)。
Nginx 配置示例
server {
listen 80;
server_name yourdomain.com;
# 强制跳转 HTTPS(如果配置了 SSL)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
# SSL 证书配置(Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# 反向代理到 Next.js 容器
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
# 必需的请求头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 关键:关闭缓冲,支持流式渲染
proxy_buffering off;
proxy_cache off;
proxy_set_header X-Accel-Buffering no;
# WebSocket 支持(如果需要)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 静态资源缓存(可选但推荐)
location /_next/static/ {
proxy_pass http://localhost:3000;
proxy_cache_valid 200 60m;
add_header Cache-Control "public, max-age=3600, immutable";
}
}三个关键配置:
proxy_buffering off:关闭缓冲,不然流式输出会卡住X-Accel-Buffering: no:明确告诉 Nginx 别缓冲响应体- WebSocket 支持:如果你用了 Socket.io 或实时功能,
Upgrade头必须加
Caddy 的简化配置
如果觉得 Nginx 配置太繁琐,试试 Caddy:
yourdomain.com {
reverse_proxy localhost:3000 {
# Caddy 默认就不缓冲,不用特殊配置
}
}没了。Caddy 会自动申请和续期 Let’s Encrypt 证书,配置文件就这么简单。
Docker Compose 集成
把 Nginx 也容器化,管理更方便:
version: '3.8'
services:
nextjs:
build: .
restart: unless-stopped
environment:
DATABASE_URL: "postgres://..."
# 不暴露到宿主机,只让 nginx 访问
expose:
- "3000"
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./certs:/etc/letsencrypt
depends_on:
- nextjs
networks:
- app-network
networks:
app-network:
driver: bridge注意 nextjs 服务用的是 expose 而不是 ports,这样只有同一网络内的容器能访问,更安全。
流式渲染失效问题解决
这个问题困扰了我整整一天。本地开发完全正常的 AI 聊天功能,部署到 Docker 后,流式输出直接失效——要么等半天一次性出来,要么直接卡住。
问题表现
典型的症状:
- OpenAI/Anthropic API 的流式响应不工作
- Server-Sent Events (SSE) 不实时推送
- 页面要等很久才突然刷新,没有逐字输出的效果
本地 npm run dev 完全正常,一到生产环境就出问题。
根本原因
两个地方会导致这个问题:
- 反向代理缓冲:Nginx 默认会缓冲响应体,等完整内容到达才发送给客户端
- Next.js Runtime:非 Edge Runtime 的 API 路由在某些情况下不支持流式输出
解决方案 1: Nginx 配置
前面反向代理章节提到的三行代码,再强调一次:
proxy_buffering off;
proxy_cache off;
proxy_set_header X-Accel-Buffering no;这三行必须加到 location / 配置块里。改完后重启 Nginx:
nginx -t # 测试配置语法
nginx -s reload # 重载配置解决方案 2: 使用 Edge Runtime
如果你的 API 路由是用来做流式输出的(比如 AI 聊天),在文件顶部加这一行:
// app/api/chat/route.ts
export const runtime = 'edge'
export async function POST(req: Request) {
const stream = new ReadableStream({
async start(controller) {
// 你的流式逻辑
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [...],
stream: true,
})
for await (const chunk of response) {
controller.enqueue(chunk.choices[0]?.delta?.content || '')
}
controller.close()
},
})
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
})
}Edge Runtime 是轻量级运行时,专门为流式响应优化过,在 Docker 环境下表现更稳定。
验证是否修复
用 curl 测试,能看到逐行输出就说明成功了:
curl -N http://yourdomain.com/api/chat \
-X POST \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}'-N 参数关闭缓冲,你应该能看到内容一点点出来,而不是等很久突然全出来。
还是不行?检查这些
- Cloudflare 代理:如果用了 CF 的橙色云朵,它也会缓冲响应。要么关掉(灰色云朵),要么升级到 Pro 套餐(支持 Streaming)
- Docker 健康检查:某些健康检查配置可能干扰流式连接,检查
docker-compose.yml里的healthcheck配置 - 负载均衡器:如果前面还有 Load Balancer,它也可能缓冲响应,需要单独配置
常见问题诊断与修复
整理了几个我踩过的坑和群友经常问的问题,基本涵盖了 80% 的部署失败场景。
问题 1: 静态资源 404
症状:页面能打开,但样式全乱,控制台一堆 404 错误,路径都是 /_next/static/...
原因:Dockerfile 里没有正确复制 .next/static 文件夹。
修复:检查你的 Dockerfile,确保有这两行:
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public如果已经有了还是 404,检查文件权限:
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static问题 2: Docker 构建失败
症状:docker build 时报错 “Could not find a production build in the ‘.next’ directory”
原因:.dockerignore 配置不当,或者构建顺序有问题。
修复:创建 .dockerignore 文件,排除不必要的目录:
.next
node_modules
.git
.env*.local
out
.DS_Store
*.log注意:.next 要排除,因为我们是在 Docker 容器里重新构建的。
问题 3: 环境变量不生效
症状:代码里读取 process.env.DATABASE_URL 返回 undefined
原因:环境变量传递方式不对,或者构建时 vs 运行时搞混了。
修复:
运行时变量(数据库地址、API 密钥等),用
docker run -e或docker-compose.yml传递:docker run -e DATABASE_URL="..." your-image构建时变量(
NEXT_PUBLIC_开头的),必须在docker build时传递:docker build --build-arg NEXT_PUBLIC_API_URL="https://api.example.com" .Dockerfile 里要声明:
ARG NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
问题 4: 内存不足导致构建失败
症状:构建到一半卡住或报错 “JavaScript heap out of memory”
原因:Node.js 默认内存限制不够,Next.js 大项目构建很吃内存。
修复:在 Dockerfile 的构建阶段增加内存:
# 在 builder 阶段
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN npm run build或者用 Docker BuildKit 限制资源:
docker build --memory=8g --memory-swap=8g -t your-image .问题 5: 容器启动后访问不了
症状:容器运行正常,但访问 http://localhost:3000 连接被拒绝。
原因:Next.js 默认监听 127.0.0.1,在 Docker 容器内部无法被外部访问。
修复:在 Dockerfile 里设置:
ENV HOSTNAME="0.0.0.0"
ENV PORT=3000或者启动时传递:
docker run -p 3000:3000 -e HOSTNAME="0.0.0.0" your-image快速诊断命令
遇到问题先跑这几个命令排查:
# 1. 检查容器是否在运行
docker ps
# 2. 查看容器日志
docker logs <container-id>
# 3. 进入容器查看文件结构
docker exec -it <container-id> sh
ls -la .next/
ls -la public/
# 4. 测试容器内部服务是否正常
docker exec -it <container-id> wget -O- http://localhost:3000
# 5. 检查端口映射
docker port <container-id>结论
从 Vercel 迁移到 Docker 自托管,说实话没有想象中那么可怕。前期配置确实要花点时间,但一旦跑通了,后续维护成本很低。我现在的状态是:每月固定 $12 服务器费用,跑着三个 Next.js 项目,完全不用担心账单暴涨。
这篇文章的三个核心配置再总结一下:
- Standalone 模式 -
next.config.js加一行,记得手动复制public和.next/static - 多阶段 Dockerfile - 三阶段构建,最终镜像 200MB 左右,启动快
- 反向代理 - Nginx 必须关闭缓冲(
proxy_buffering off),不然流式渲染废掉
如果你卡在流式渲染问题上,99% 的情况是反向代理缓冲导致的,加上 export const runtime = 'edge' 基本能解决。
Vercel vs 自托管对比
| 维度 | Vercel | Docker 自托管 |
|---|---|---|
| 部署速度 | ⚡️ git push 即部署 | 🐢 5-10分钟手动操作 |
| 开发体验 | 🌟 预览环境、日志、Analytics | 🔧 需要自己配置监控 |
| 成本 | 💸 $20+/月,流量大了更贵 | 💰 $12/月固定(可跑多个项目) |
| 扩展性 | 📈 自动扩缩容 | 📊 手动调整资源 |
| 控制权 | ⚠️ 受限于平台规则 | ✅ 完全掌控 |
| 适用场景 | 企业项目、全球服务 | 个人项目、小团队、预算有限 |
最后的建议:
- 如果你是个人开发者,有多个 side project,自托管能省不少钱
- 如果团队没有运维能力,或者项目流量波动很大,老实用 Vercel
- 技术选型没有对错,只有适不适合
完整的配置文件和更多细节,我放在了 GitHub 仓库(仓库占位,实际使用时替换)。有问题欢迎留言讨论,踩过的坑就别让后面的人再踩了。
Next.js Docker 自托管完整部署流程
从配置 standalone 模式到部署上线的完整步骤,包含反向代理和流式渲染修复
⏱️ 预计耗时: 2 小时
- 1
步骤1: 配置 Standalone 输出模式
在 next.config.js 中启用 standalone 模式:
1. 打开 next.config.js 文件
2. 添加配置:output: 'standalone'
3. 运行构建:npm run build
4. 检查输出:确认 .next/standalone 目录已生成
关键点:
• standalone 模式不会自动复制 public 和 .next/static
• 这两个目录必须在 Dockerfile 中手动复制
• 否则静态资源会全部 404
配置示例:
```javascript
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfig
``` - 2
步骤2: 创建多阶段 Dockerfile
编写三阶段构建的 Dockerfile:
阶段1 - 依赖安装:
• 使用 node:20-alpine 作为基础镜像
• 只复制 package.json 和 package-lock.json
• 运行 npm ci 安装依赖(利用 Docker 缓存)
阶段2 - 构建应用:
• 从阶段1复制 node_modules
• 复制所有源码
• 运行 npm run build 构建应用
阶段3 - 生产运行:
• 创建非 root 用户(安全实践)
• 复制 public 文件夹(静态资源)
• 复制 .next/standalone 输出
• 复制 .next/static 文件(CSS/JS 构建产物)
• 设置 HOSTNAME="0.0.0.0" 和 PORT=3000
• 启动命令:node server.js
关键点:
• 三阶段构建可将镜像从 1.5GB 降到 200MB
• 必须复制 public 和 .next/static,否则静态资源 404
• 使用非 root 用户运行,提升安全性 - 3
步骤3: 配置 Nginx 反向代理
设置 Nginx 反向代理并关闭缓冲:
1. 安装 Nginx(或使用 Caddy)
2. 配置 SSL 证书(Let's Encrypt)
3. 创建 Nginx 配置文件
关键配置(必须添加):
• proxy_buffering off;(关闭缓冲)
• proxy_cache off;(关闭缓存)
• proxy_set_header X-Accel-Buffering no;(明确告诉 Nginx 不缓冲)
必需请求头:
• proxy_set_header Host $host;
• proxy_set_header X-Real-IP $remote_addr;
• proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
• proxy_set_header X-Forwarded-Proto $scheme;
WebSocket 支持(如需要):
• proxy_set_header Upgrade $http_upgrade;
• proxy_set_header Connection "upgrade";
测试配置:
```bash
nginx -t # 测试语法
nginx -s reload # 重载配置
```
注意:如果不关闭缓冲,流式渲染会失效 - 4
步骤4: 处理环境变量
区分构建时和运行时环境变量:
构建时变量(NEXT_PUBLIC_ 开头):
• 必须在 docker build 时传递
• 使用 --build-arg 参数
• Dockerfile 中声明:ARG NEXT_PUBLIC_API_URL
• 设置环境变量:ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
运行时变量(服务端使用):
• 使用 docker run -e 传递
• 或在 docker-compose.yml 中配置
• 代码中直接从 process.env 读取
Standalone 模式下:
• runtimeConfig 不工作
• 必须使用 App Router 方式读取环境变量
• 服务端代码:const dbUrl = process.env.DATABASE_URL
示例:
```bash
# 构建时
docker build --build-arg NEXT_PUBLIC_API_URL="https://api.example.com" .
# 运行时
docker run -e DATABASE_URL="postgres://..." your-image
``` - 5
步骤5: 修复流式渲染问题
解决流式渲染失效(AI 聊天、SSE 等):
问题表现:
• 流式输出不工作,等很久才一次性出来
• Server-Sent Events 不实时推送
解决方案1 - Nginx 配置(必须):
• 确保已添加 proxy_buffering off
• 确保已添加 X-Accel-Buffering: no
• 重启 Nginx 服务
解决方案2 - 使用 Edge Runtime:
• 在 API 路由文件顶部添加:export const runtime = 'edge'
• Edge Runtime 专门为流式响应优化
• 在 Docker 环境下表现更稳定
验证修复:
```bash
curl -N http://yourdomain.com/api/chat \
-X POST \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}'
```
使用 -N 参数关闭缓冲,应该能看到逐行输出
其他检查:
• Cloudflare 代理:如果用了橙色云朵,也会缓冲(需关闭或升级 Pro)
• Docker 健康检查:可能干扰流式连接
• 负载均衡器:如果前面还有 LB,需要单独配置 - 6
步骤6: 部署和验证
构建镜像并部署:
1. 构建 Docker 镜像:
```bash
docker build -t nextjs-app .
```
2. 运行容器:
```bash
docker run -d \
-p 3000:3000 \
-e DATABASE_URL="postgres://..." \
-e API_KEY="xxx" \
--name nextjs-app \
nextjs-app
```
3. 验证部署:
• 检查容器状态:docker ps
• 查看日志:docker logs nextjs-app
• 测试访问:curl http://localhost:3000
• 检查静态资源:访问 /_next/static/ 路径
4. 配置 Nginx 并重启:
• 确保反向代理配置正确
• 测试 HTTPS 访问
• 验证流式渲染功能
5. 监控和维护:
• 设置容器自动重启:--restart unless-stopped
• 定期查看日志排查问题
• 监控服务器资源使用情况
常见问题排查:
• 静态资源 404:检查 Dockerfile 是否复制了 public 和 .next/static
• 环境变量不生效:区分构建时和运行时变量
• 容器无法访问:检查 HOSTNAME 是否设为 0.0.0.0
常见问题
自托管能省多少钱?成本对比如何?
为什么静态资源会 404?怎么修复?
• COPY --from=builder /app/public ./public
• COPY --from=builder /app/.next/static ./.next/static
如果还是 404,检查文件权限,使用 --chown=nextjs:nodejs 设置正确的所有者。
流式渲染不工作怎么办?
1) Nginx 配置必须添加:proxy_buffering off; proxy_set_header X-Accel-Buffering no;
2) API 路由使用 Edge Runtime:export const runtime = 'edge'
3) 检查 Cloudflare 代理(如果使用):关闭橙色云朵或升级 Pro 套餐
4) 验证:使用 curl -N 测试,应该能看到逐行输出
环境变量不生效怎么办?
• NEXT_PUBLIC_ 开头:必须在 docker build 时用 --build-arg 传递,Dockerfile 中声明 ARG 和 ENV
• 运行时变量:用 docker run -e 或 docker-compose.yml 传递,代码中从 process.env 读取
• Standalone 模式下 runtimeConfig 不工作,必须使用 App Router 方式读取环境变量
Docker 镜像太大怎么办?
• 阶段1:只安装依赖(利用 Docker 缓存)
• 阶段2:构建应用
• 阶段3:只复制运行时需要的文件(standalone 输出、public、static)
• 最终镜像可从 1.5GB 降到 200MB
• 使用 node:20-alpine 基础镜像进一步减小体积
什么时候适合自托管?什么时候用 Vercel?
适合 Vercel:团队无运维能力、流量波动大需要自动扩缩容、需要全球边缘网络、需要 Vercel 专有功能(Analytics、Edge Config)、预算充足更看重开发效率。
容器启动后无法访问怎么办?
1) HOSTNAME 必须设为 0.0.0.0(不能是 127.0.0.1),在 Dockerfile 中设置 ENV HOSTNAME="0.0.0.0"
2) 端口映射是否正确:docker run -p 3000:3000
3) 容器是否在运行:docker ps
4) 查看容器日志:docker logs <container-id>
5) 测试容器内部:docker exec -it <container-id> wget -O- http://localhost:3000
12 分钟阅读 · 发布于: 2025年12月20日 · 修改于: 2026年1月22日
相关文章
Next.js 电商实战:购物车与 Stripe 支付完整实现指南

Next.js 电商实战:购物车与 Stripe 支付完整实现指南
Next.js 文件上传完整指南:S3/七牛云预签名URL直传实战

Next.js 文件上传完整指南:S3/七牛云预签名URL直传实战
Next.js 单元测试实战:Jest + React Testing Library 完整配置指南


评论
使用 GitHub 账号登录后即可评论