ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

create-t3-app Docker 部署实战:从多阶段 Dockerfile 到 Docker Compose 与 Railway

create-t3-app Docker 部署实战:从多阶段 Dockerfile 到 Docker Compose 与 Railway 开发工具CLI代码生成【免费下载链接】create-t3-appThe best way to start a full-stack, typesafe Next.js app项目地址https://gitcode.com/gh_mirrors/cr/create-t3-app点击查看免费下载本篇技术指南围绕 create-t3-app 官方文档《Utrulling med DockerDocker 部署》展开完整讲解如何将 create-t3-app 生成的全栈 Next.js 应用容器化从开启 Next.js 的standalone输出、编写多阶段Dockerfile、通过docker-compose编排运行再到一键部署到 Railway 这类 PaaS 平台。读完本文你将掌握一套可复制、可运行的 Docker 部署方案并理解构建期build time与运行期runtime环境变量在容器化中的关键差异。Docker 部署的整体思路create-t3-app 生成的 Next.js 全栈应用含 tRPC、Prisma/Drizzle、NextAuth 等可选能力可以整体容器化部署方式有两种单个容器直接用docker build构建镜像再用docker run启动容器组用docker-compose将应用与数据库等依赖编排为多容器服务。官方文档还给出了一个基于本文档的示例仓库ajcwebdev/ct3a-docker可供对照学习。在动手写Dockerfile之前最需要先厘清的是 Next.js 对两类环境变量的不同处理方式。部署前的关键认知构建期与运行期环境变量Next.js 对变量的处理分为两个完全不同的阶段这直接决定了它们在Dockerfile和docker-compose.yml中的位置变量用途注入时机DATABASE_URL服务器端使用数据库连接运行期runtime运行时注入NEXT_PUBLIC_CLIENTVAR客户端使用浏览器可访问构建期build time构建时内联进前端产物NEXT_PUBLIC_前缀的变量会在构建阶段被 Next.js 直接内联inline到客户端 JavaScript 包中因此必须在docker build时通过--build-arg传入而DATABASE_URL这类服务器端变量只在容器启动时读取应在docker run -e或 compose 的environment中注入。两者的位置一旦放错应用要么构建失败要么运行时拿不到数据库连接。与 T3 Env 校验机制的联动create-t3-app 使用t3-oss/env-nextjs zod 在运行时和构建时双重校验环境变量校验逻辑集中在 src/env.js。其核心代码import { createEnv } from t3-oss/env-nextjs; import { z } from zod; export const env createEnv({ server: { NODE_ENV: z.enum([development, test, production]), }, client: { // NEXT_PUBLIC_CLIENTVAR: z.string(), }, runtimeEnv: { NODE_ENV: process.env.NODE_ENV, }, skipValidation: !!process.env.SKIP_ENV_VALIDATION, emptyStringAsUndefined: true, });注意skipValidation: !!process.env.SKIP_ENV_VALIDATION这一行只要构建命令带上SKIP_ENV_VALIDATION1所有环境变量 schema 的构建期校验就会被跳过。这正是 Docker 构建的关键——因为我们没有把服务器端环境变量传入构建阶段如果不跳过校验next build会因为缺少DATABASE_URL等变量而直接失败。有关 T3 Env 的完整用法server/client/runtimeEnv的划分、类型强转z.coerce等可进一步阅读 环境变量文档。第一步在 next.config.js 中开启 standalone 输出为了让镜像足够精简需要让 Next.js 使用Output File Tracing输出文件追踪特性只打包运行应用真正需要的文件。在项目的next.config.js中添加output: standaloneexport default defineNextConfig({ reactStrictMode: true, swcMinify: true, output: standalone, });当前仓库中的基础模板 next.config.js 实际内容为/** type {import(next).NextConfig} */ const config { reactStrictMode: true, i18n: { locales: [en], defaultLocale: en, }, }; export default config;可以推断启用output: standalone后next build会在.next/standalone目录下生成一份自包含的、最小化的服务端代码含server.js后续Dockerfile的 RUNNER 阶段正是直接拷贝这个目录。如果你使用的是 App RouterappDir变体仓库还提供了不带i18n的 next-config-appdir.js 作为对照。第二步创建 .dockerignore为避免把本地依赖、构建产物和敏感文件尤其是.env打进构建上下文在项目根目录创建.dockerignore.env Dockerfile .dockerignore node_modules npm-debug.log README.md .next .git排除.env的意义不仅在于减小上下文体积更在于防止数据库密码等密钥被写入镜像层——这也呼应了前文服务器端变量运行时再注入的设计。第三步编写多阶段 Dockerfile官方文档强调由于容器构建阶段不携带服务器端环境变量环境变量校验 必然失败因此所有构建命令都必须加上SKIP_ENV_VALIDATION1。完整的Dockerfile如下多阶段构建依赖安装 → 构建 → 运行##### AVHENGIGHETER依赖 FROM --platformlinux/amd64 node:16-alpine3.17 AS deps RUN apk add --no-cache libc6-compat openssl WORKDIR /app # 安装 Prisma 客户端 —— 如果不使用 Prisma 请删除本行 COPY prisma ./ # 根据项目使用的包管理器安装依赖 COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ RUN \ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ elif [ -f package-lock.json ]; then npm ci; \ elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm pnpm i; \ else echo Lockfile not found. exit 1; \ fi ##### BUILDER构建 FROM --platformlinux/amd64 node:16-alpine3.17 AS builder ARG DATABASE_URL ARG NEXT_PUBLIC_CLIENTVAR WORKDIR /app COPY --fromdeps /app/node_modules ./node_modules COPY . . # ENV NEXT_TELEMETRY_DISABLED 1 RUN \ if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION1 yarn build; \ elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION1 npm run build; \ elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm SKIP_ENV_VALIDATION1 pnpm run build; \ else echo Lockfile not found. exit 1; \ fi ##### RUNNER运行 FROM --platformlinux/amd64 node:16-alpine3.17 AS runner WORKDIR /app ENV NODE_ENV production # ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --frombuilder /app/next.config.js ./ COPY --frombuilder /app/public ./public COPY --frombuilder /app/package.json ./package.json COPY --frombuilder --chownnextjs:nodejs /app/.next/standalone ./ COPY --frombuilder --chownnextjs:nodejs /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT 3000 CMD [node, server.js]三个阶段的职责拆解DEPS 阶段安装全部依赖。libc6-compat是 Alpine 下运行某些原生模块如 Node 编译产物所需的 glibc 兼容层openssl则是 Prisma 引擎等组件的运行依赖。COPY prisma ./是为了提前生成 Prisma 客户端。安装逻辑按锁文件自动识别包管理器yarn / npm / pnpm找不到锁文件则报错退出。BUILDER 阶段ARG DATABASE_URL与ARG NEXT_PUBLIC_CLIENTVAR声明了两个构建参数——NEXT_PUBLIC_CLIENTVAR会在构建时被内联进前端代码而DATABASE_URL仅用于占位声明其真实值由运行时注入规避构建期校验。构建命令统一带上SKIP_ENV_VALIDATION1。RUNNER 阶段以非 root 用户nextjs运行addgroup/adduser创建 uid/gid 均为 1001 的用户只拷贝standalone产物、public静态目录与next.config.js最终以node server.js启动监听 3000 端口。官方文档的补充说明--platformlinux/amd64模拟如果使用 Node 18 及以上的基础镜像架构模拟可能不再必要可按需移除libc6-compatAlpine 镜像与 glibc 兼容层的配合是官方推荐做法可避免运行时出现动态链接库缺失错误Alpine 与 Prisma 的兼容性基于 Alpine 3.17 的镜像在某些 Prisma 版本下可能引发引擎问题可通过engineType binary解决但会带来性能开销生产环境也可改用 Debian 系镜像规避遥测Next.js 会收集匿名使用数据。Dockerfile中有两行被注释的ENV NEXT_TELEMETRY_DISABLED 1取消第一行的注释可禁用构建期遥测取消第二行的注释可禁用运行期遥测。版本说明以当前仓库为准本文档基础镜像写于早期版本node:16-alpine3.17原文中的apline为笔误。当前仓库 基础模板 package.json 已升级到next^15.5.9、react^19.2.3仓库内更新的 英文版 Docker 文档 已改用node:20-alpine作为 deps/builder 镜像并将 runner 替换为gcr.io/distroless/nodejs20-debian12命令相应简化为CMD [server.js]。实际使用时建议以 Node 20 LTS 及以上版本、与你项目依赖锁文件匹配的包管理器为准其余结构与参数完全一致。本地构建与运行镜像在项目根目录执行docker build -t ct3a-docker --build-arg NEXT_PUBLIC_CLIENTVARclientvar . docker run -p 3000:3000 -e DATABASE_URLdatabase_url_her ct3a-dockerdocker build通过--build-arg NEXT_PUBLIC_CLIENTVARclientvar把客户端变量注入构建期docker run通过-e DATABASE_URL...在容器启动时注入服务器端变量-p 3000:3000将容器 3000 端口映射到宿主机。启动成功后打开 localhost:3000 即可访问应用。使用 Docker Compose 编排运行当应用需要与数据库等更多服务协同运行时可以用 Docker Compose 定义整个服务组。在完成上述 1–4 步后创建docker-compose.ymlversion: 3.9 services: app: platform: linux/amd64 build: context: . dockerfile: Dockerfile args: NEXT_PUBLIC_CLIENTVAR: clientvar working_dir: /app ports: - 3000:3000 image: t3-app environment: - DATABASE_URLdatabase_url_her注意变量位置与单容器方式一脉相承build.args中传入NEXT_PUBLIC_CLIENTVAR构建期、客户端environment中传入DATABASE_URL运行期、服务器端platform: linux/amd64与Dockerfile中的--platform保持一致。执行以下命令构建并启动docker compose up再次访问 localhost:3000 验证应用运行状态。部署到 RailwayPaaS 平台如果你不想自己维护服务器可以使用 Railway 这类 PaaS 平台的自动化 Dockerfile 部署。安装 Railway CLI 后按顺序执行railway login railway init railway link railway up railway open随后在 Railway 控制台完成两步配置进入Variables粘贴DATABASE_URL以及其余服务器端环境变量进入Settings选择Generate Domain生成公网访问域名。官方文档基于本文档提供了一个名为ct3a-docker的 Railway 示例应用可对照其实际运行效果验证你的部署。开发环境中的 Dockerstart-database.sh除了部署场景create-t3-app 仓库内部还内置了用 Docker 启动本地开发数据库的辅助脚本与本文部署主题同属 Docker 实践一并说明当你在脚手架中选择 MySQL 或 PostgreSQL 时项目会生成 mysql.sh 或 postgres.sh。脚本会从.env中的DATABASE_URL解析出密码、端口与库名自动检查端口占用与容器状态甚至会在检测到默认密码时提示生成随机密码。其生成逻辑在 dbContainer.ts 中实现安装器读取对应模板脚本并将占位符替换为经过 Docker 命名规范清洗非法字符转下划线、统一小写的项目名。这意味着你的项目从本地开发数据库到生产容器镜像可以全程使用 Docker 工作流。有用的参考资源官方文档在末尾列出了一组权威参考资源可作为进一步深入的方向此处仅整理主题不再给出外链主题内容Dockerfile 参考Docker 官方 Builder 指令参考覆盖FROM/RUN/COPY/ARG等全部指令Compose file 参考Compose v3 文件格式与字段services/build/environment/ports说明Docker CLI 参考docker build/docker run/docker compose等命令的完整用法Next.js 官方部署文档Docker Image 一节含 Output File Tracing 与 standalone 输出的官方说明Next.js in Docker 文章社区关于 Next.js 容器化踩坑的实践文章Next.js with Docker 示例Vercel 官方仓库中的 with-docker 示例项目构建 Next.js Docker 镜像教程社区从零构建 Next.js 镜像的分步教程小结将 create-t3-app 应用容器化的核心可以概括为三句话构建期只注入NEXT_PUBLIC_客户端变量并用SKIP_ENV_VALIDATION1跳过环境校验运行期再注入DATABASE_URL等服务器端变量RUNNER 阶段只保留.next/standalone产物并以非 root 用户运行。配合多阶段构建、.dockerignore排除敏感文件以及 Docker Compose 或 Railway 的编排部署你就能获得一套体积小、可复现、便于迁移的容器化发布流程。赞分享开发工具CLI代码生成【免费下载链接】create-t3-appThe best way to start a full-stack, typesafe Next.js app项目地址https://gitcode.com/gh_mirrors/cr/create-t3-app点击查看免费下载相关推荐网盘直链下载助手告别限速九大网盘高速下载完整指南网盘直链下载助手告别限速九大网盘高速下载完整指南 还在为网盘下载速度只有几十KB而烦恼吗 网盘直链下载助手 是一款基于JavaScript的开源工具能够开发工具CLI代码生成create-t3-app 项目 Docker 容器化部署实战多阶段构建、Docker Compose 编排与 Railway 发布create t3 app 项目 Docker 容器化部署实战多阶段构建、Docker Compose 编排与 Railway 发布 本文围绕 create开发工具CLI代码生成create-t3-app Docker 部署完整指南从多阶段构建到 Railway 上线create t3 app Docker 部署完整指南从多阶段构建到 Railway 上线 create t3 app 生成的 Next.js 全栈项目可以轻开发工具CLI代码生成创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表