Nuxt 3 服务端渲染项目如何用 Docker 容器化部署

文章导读
Nuxt 3 服务端渲染项目必须使用包含 Node.js 运行环境的 Docker 镜像部署,不能仅复制静态文件。推荐采用多阶段构建方案,先将构建产物输出到 .output 目录,再将其复制到精简的运行镜像中,同时需明确暴露 3000 端口并配置 HOST 为 0.0.0.0 以确保外部可访问。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Nuxt 3 服务端渲染项目必须使用包含 Node.js 运行环境的 Docker 镜像部署,不能仅复制静态文件。推荐采用多阶段构建方案,先将构建产物输出到 .output 目录,再将其复制到精简的运行镜像中,同时需明确暴露 3000 端口并配置 HOST 为 0.0.0.0 以确保外部可访问。

先说结论:Nuxt 3 SSR 部署依赖 Node 运行时,Docker 多阶段构建能显著减小镜像体积并隔离环境。

  • 适合:需要环境一致性、快速回滚及避免服务器依赖冲突的 SSR 项目。
  • 先准备:确认本地 Node 版本与镜像一致,清理旧的 .output 和 node_modules 目录。
  • 验收:容器启动后通过 curl 访问健康检查接口,确认状态码为 200。

命令速用版

以下 Dockerfile 配置适用于大多数 Nuxt 3 项目,基于 node:18-alpine 镜像构建:

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci `--omit`=dev
COPY . .
RUN npm run build

FROM node:18-alpine
ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=3000
WORKDIR /app
COPY `--from`=builder /app/.output ./
COPY `--from`=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "./server/index.mjs"]

构建与运行命令:

docker build -t nuxt3-app .
docker run -d -p 3000:3000 `--name` nuxt3-container nuxt3-app

为什么会这样

Nuxt 3 的 SSR 特性决定了服务端需要执行 Node.js 代码来渲染页面,而非单纯托管静态资源。传统 PM2 部署容易受服务器全局 Node 版本和依赖影响,导致“本地正常线上报错”。Docker 容器将 Node 版本、系统依赖和代码打包成独立单元,确保开发、测试和生产环境完全一致。多阶段构建则能将最终镜像体积从 1GB 以上降低至 200MB 左右,因为运行阶段不再包含构建工具和源码。

分步处理

1. 本地构建环境优化
在打包前,清理旧的构建产物以避免缓存干扰。国内网络环境下建议配置 .npmrc 使用镜像源加速依赖安装。

rm -rf .output node_modules .nuxt
npm install `--registry`=https://registry.npmmirror.com
npm run build

2. 编写 Dockerfile
使用多阶段构建,第一阶段安装依赖并构建,第二阶段仅复制 .output 目录和必要的 node_modules。确保设置 ENV HOST=0.0.0.0,否则容器内服务可能仅监听 localhost 导致外部无法访问。

Nuxt 3 服务端渲染项目如何用 Docker 容器化部署

3. 构建与推送镜像
在项目根目录执行 docker build。若使用服务器面板如 1Panel 或宝塔,可直接上传构建好的镜像或通过 Dockerfile 在线构建。

4. 配置反向代理(可选)
若需通过 80/443 端口访问,建议在 Docker 外配置 Nginx 反向代理,将域名请求转发至容器的 3000 端口。

怎么验证是否生效

容器启动后,首先检查容器状态是否为 Up,其次验证服务响应。执行 docker ps 确认容器运行正常,查看日志 docker logs nuxt3-container 确认无报错。

在服务器内部或外部执行 curl 命令测试接口:

curl -I http://localhost:3000/
curl http://localhost:3000/health

若配置了健康检查路由,/health 接口应返回状态码 200 及 JSON 状态信息。若使用 1Panel 等面板,可在容器详情页查看实时日志和端口映射状态。

Nuxt 3 服务端渲染项目如何用 Docker 容器化部署

常见坑

1. 端口映射错误
容器内暴露 3000 端口,宿主机映射也需对应,如 -p 3000:3000。若 HOST 未设置为 0.0.0.0,外部请求会被拒绝。

2. 构建产物缺失
Nuxt 3 构建后核心文件在 .output 目录,Dockerfile 中 COPY 路径必须指向 .output/server/index.mjs 而非根目录。

3. 依赖安装失败
某些 npm 包可能需要编译工具,Alpine 镜像可能缺少 python 或 make。若构建报错,需在 builder 阶段安装 apk add `--no-cache` python3 make g++。

常见问题

PM2 和 Docker 部署 Nuxt 3 有什么区别?

PM2 依赖服务器全局 Node 环境,适合单机快速部署;Docker 隔离环境,适合多机器一致性和自动化流程。

静态生成(SSG)项目需要 Docker 吗?

纯静态生成项目只需 Nginx 托管 html 文件,不需要 Node 运行时,因此无需 Docker 运行 Node 服务。

如何更新已部署的容器?

构建新镜像后,停止并删除旧容器,使用新镜像启动同名容器,或配合 Docker Compose 执行 up -d。

参考来源

  • 告别 PM2!用 Docker 容器化部署 Nuxt3 SSR 项目的完整避坑指南 (附 Dockerfile 配置)
  • 前端项目不只是 npm run build:我把 Nuxt3 项目第一次装进了 Docker
  • Nuxt3 项目 Docker 化部署实战:1Plane 面板避坑指南 (2024 最新版)
  • 部署 Nuxt3 项目 (含 PM2、Docker 部署,及配合 jenkins 实现自动化部署)