☰
用 Docker 部署 tailwind-nextjs-starter-blog:基于 Next.js Standalone 输出的容器化实战指南
2026/10/2 2:21:46 网站建设 项目流程
  • 前端
  • 示例工程

【免费下载链接】tailwind-nextjs-starter-blog

This is a Next.js, Tailwind CSS blogging starter template. Comes out of the box configured with the latest technologies to make technical writing a breeze. Easily configurable and customizable. Perfect as a replacement to existing Jekyll and Hugo individual blogs.

项目地址:https://gitcode.com/GitHub_Trending/ta/tailwind-nextjs-starter-blog
点击查看免费下载

本篇指南以本仓库 FAQ 文档 faq/deploy-with-docker.md 为核心,讲解如何将基于 Next.js + Tailwind CSS 的博客模板 tailwind-nextjs-starter-blog 通过 Docker 容器化部署到自托管服务器。你将掌握开启 Next.jsstandalone输出、编写多阶段 Dockerfile、构建与运行镜像,以及使用 Docker Compose 管理容器的完整流程。

为什么要用 Docker + Standalone 输出

Docker 可以把应用连同运行环境一起打包,实现"一次构建、随处运行",特别适合在 VPS、私有云等自托管场景中部署博客。而对 Next.js 应用来说,容器化部署的关键是开启Standalone 输出模式:

  • Next.js 的output: 'standalone'会启用自动输出追踪,只把运行应用真正需要的文件(server.js、精简后的node_modules、必要的静态资源)输出到.next/standalone目录,大幅减小镜像体积;
  • 生成的server.js是一个独立的 Node.js 服务器入口,配合极小的运行时依赖,可以直接node server.js启动,不需要再安装完整依赖、也不需要next start。

对照本仓库的 next.config.js 可以看到,当前配置中:

const output = process.env.EXPORT ? 'export' : undefined

即:默认(不设置EXPORT环境变量)时output为undefined,应用以标准 Next.js 服务器模式运行(对应package.json中的"serve": "next start");设置EXPORT=1时则输出纯静态out目录。而 Docker 部署要做的,就是显式开启standalone输出。

第一步:修改 next.config.js 开启 Standalone

原 FAQ 文档给出的核心配置如下(见 faq/deploy-with-docker.md):

// next.config.js module.exports = { // ... rest of the configuration. output: 'standalone', }

需要结合本仓库的实际情况说明:这个项目的 next.config.js 并不是简单的对象导出,而是通过withContentlayer、withBundleAnalyzer两个插件组合后返回配置的函数式写法。因此开启 standalone 的正确方式是:保留现有插件组合,在最终返回的配置对象中加入output: 'standalone',大致如下:

module.exports = () => { const plugins = [withContentlayer, withBundleAnalyzer] return plugins.reduce((acc, next) => next(acc), { output: 'standalone', // 开启 standalone 输出(Docker 部署) // ... rest of the configuration(reactStrictMode、trailingSlash、pageExtensions 等保持原样) }) }

需要注意两点:

  1. 不要与EXPORT环境变量混用:当前配置中output = process.env.EXPORT ? 'export' : undefined,如果构建 Docker 镜像时设置了EXPORT=1,会与手动指定的'standalone'冲突。构建镜像时应保持EXPORT未设置;
  2. 本项目yarn build之后还会执行 scripts/postbuild.mjs 中的 RSS 生成任务,scripts/rss.mjs 第 10 行const outputFolder = process.env.EXPORT ? 'out' : 'public'表明:非EXPORT模式下 RSS 文件(feed.xml及按标签生成的 RSS)会写入public目录,而public目录会被打包进 standalone 产物,因此容器内 RSS 功能可以正常工作。

第二步:准备 Dockerfile 与 .dockerignore

原文档提到"把官方 Next.js with-docker 示例中的Dockerfile复制到项目根目录"。参照官方示例的**多阶段构建(multi-stage build)**思路,结合本项目使用yarn(见 package.json 中"packageManager": "yarn@3.6.1")与 Node.js 技术栈,可编写如下 Dockerfile 示例:

# 阶段一:安装依赖 FROM node:20-alpine AS deps WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile # 阶段二:构建应用 FROM node:20-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . # 构建并运行 postbuild.mjs 生成 RSS(写入 public) RUN yarn build # 阶段三:运行时镜像 FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production # 以非 root 用户运行,提升安全性(依据官方示例惯例) RUN addgroup --system --gid 1001 nodejs \ && adduser --system --uid 1001 nextjs # 只拷贝 standalone 产物与必要静态资源 COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/public ./public USER nextjs EXPOSE 3000 ENV PORT=3000 # standalone 服务器需要监听所有网卡,容器内才能对外提供访问 ENV HOSTNAME=0.0.0.0 CMD ["node", "server.js"]

说明:node:20-alpine为示例基础镜像,实际版本请以你部署环境兼容的 Node 版本为准(本项目 package.json 未声明engines字段,建议对照你本机node -v验证过的主力版本)。

同时在项目根目录添加.dockerignore(典型内容如下),避免把node_modules、.next、.git、out等目录打进构建上下文,显著加快构建速度并减小镜像:

node_modules .next out .git .gitignore README.md yarn.lock

注意:不要把yarn.lock加进.dockerignore(上述为示意,锁文件应保留用于yarn install --frozen-lockfile的确定性安装)。

第三步:构建镜像并运行容器

完成配置与 Dockerfile 之后,按原文档给出的命令构建并运行:

docker build -t nextjs-docker . docker run -p 3000:3000 nextjs-docker

逐条解释:

  • docker build -t nextjs-docker .:基于当前目录构建镜像,-t指定镜像名为nextjs-docker。构建过程中会执行yarn build,产出.next/standalone等产物;
  • docker run -p 3000:3000 nextjs-docker:运行容器,-p 3000:3000把宿主机 3000 端口映射到容器内 3000 端口,之后访问http://localhost:3000即可看到博客。

构建完成后可验证容器状态与页面响应:

docker ps # 查看运行中的容器 curl -I http://localhost:3000 # 检查 HTTP 响应

环境变量传递注意:本项目 data/siteMetadata.js 中引用了若干环境变量,例如:

  • process.env.NEXT_UMAMI_ID(Umami 统计站点 ID)
  • process.env.NEXT_PUBLIC_GISCUS_REPO、NEXT_PUBLIC_GISCUS_REPOSITORY_ID、NEXT_PUBLIC_GISCUS_CATEGORY、NEXT_PUBLIC_GISCUS_CATEGORY_ID(giscus 评论配置)

其中以NEXT_PUBLIC_开头的变量在 Next.js 中属于构建期内联变量,必须在docker build阶段(通过--build-arg或构建环境的 export)注入;而像NEXT_UMAMI_ID这类非NEXT_PUBLIC_变量则可以在docker run时通过-e传入,例如:

docker run -p 3000:3000 -e NEXT_UMAMI_ID=your-umami-id nextjs-docker

第四步(可选):使用 Docker Compose

原文档还提到可以参照 with-docker-compose 示例使用 Docker Compose 管理部署。参考该方式,可在项目根目录新建docker-compose.yml:

services: web: build: . image: nextjs-docker ports: - "3000:3000" environment: - NODE_ENV=production

然后一条命令完成构建与启动:

docker compose up -d --build

Compose 的优点是配置可声明化、便于与其他服务(如反向代理 Nginx、Caddy)编排;停止服务用docker compose down,查看日志用docker compose logs -f。

实践要点与注意事项

  1. standalone 与静态导出(EXPORT=1)的区别:本项目也支持静态导出部署(见 README.md 的 "Static hosting services" 一节,EXPORT=1 UNOPTIMIZED=1 yarn build生成out目录),但纯静态导出无法使用服务端功能。而 standalone 模式保留 Node 服务器能力,例如本仓库的 app/api/newsletter/route.ts(Newsletter API 路由)这类服务端功能可以在容器中正常工作——这也是自托管选择 Docker + standalone 的关键价值;
  2. 安全响应头会自动生效:next.config.js 中的async headers()会为所有路由注入 CSP、X-Frame-Options、HSTS等安全头,standalone 服务器同样适用,无需额外配置;
  3. 镜像瘦身:standalone 产物只包含运行必需文件,是控制镜像体积的基础;配合.dockerignore与多阶段构建,镜像体积通常可以控制在很小的范围(具体大小取决于依赖树,不做夸大承诺);
  4. 生产环境建议:正式部署建议在容器前再加一层反向代理(Nginx/Caddy/Traefik)负责 TLS 终止与静态资源缓存,并将docker run/Compose 中的端口映射调整为仅内网可达。

小结

通过开启output: 'standalone'、编写多阶段 Dockerfile、构建并运行镜像,即可把 tailwind-nextjs-starter-blog 完整部署到任意支持 Docker 的服务器上,且保留 RSS 生成、API 路由等服务端能力。全文以 FAQ 文档 faq/deploy-with-docker.md 的步骤为主线,并结合 next.config.js、package.json、scripts/postbuild.mjs、data/siteMetadata.js 等仓库实际文件做了深化,确保每一处命令与配置都可直接落地复现。

  • 前端
  • 示例工程

【免费下载链接】tailwind-nextjs-starter-blog

This is a Next.js, Tailwind CSS blogging starter template. Comes out of the box configured with the latest technologies to make technical writing a breeze. Easily configurable and customizable. Perfect as a replacement to existing Jekyll and Hugo individual blogs.

项目地址:https://gitcode.com/GitHub_Trending/ta/tailwind-nextjs-starter-blog
点击查看免费下载
上一篇:使用 vLLM-Omni 离线运行 MiMo-Audio:TTS、语音理解与多轮对话的端到端推理实战
下一篇:零基础入门网络安全:Security-101 课程体系、模块脉络与学习路线全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询