Next.js部署
准备工作
- 一台服务器
- node环境
- 项目
使用Docker封装镜像
- 项目编译准备
- Dockerfile文件写入根目录
# ============================================
# Stage 1: Dependencies Installation Stage
# ============================================
# IMPORTANT: Node.js Version Maintenance
# This Dockerfile uses Node.js 24.13.0-slim, which was the latest LTS version at the time of writing.
# To ensure security and compatibility, regularly update the NODE_VERSION ARG to the latest LTS version.
ARG NODE_VERSION=24.13.0-slim
FROM node:${NODE_VERSION} AS dependencies
# Set working directory
WORKDIR /app
# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
# Install project dependencies with frozen lockfile for reproducible builds
RUN --mount=type=cache,target=/root/.npm \
--mount=type=cache,target=/usr/local/share/.cache/yarn \
--mount=type=cache,target=/root/.local/share/pnpm/store \
if [ -f package-lock.json ]; then \
npm ci --no-audit --no-fund; \
elif [ -f yarn.lock ]; then \
corepack enable yarn && yarn install --frozen-lockfile --production=false; \
elif [ -f pnpm-lock.yaml ]; then \
corepack enable pnpm && pnpm install --frozen-lockfile; \
else \
echo "No lockfile found." && exit 1; \
fi
# ============================================
# Stage 2: Build Next.js application in standalone mode
# ============================================
FROM node:${NODE_VERSION} AS builder
# Set working directory
WORKDIR /app
# Copy project dependencies from dependencies stage
COPY --from=dependencies /app/node_modules ./node_modules
# Copy application source code
COPY . .
ENV NODE_ENV=production
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED=1
# Build Next.js application
# If you want to speed up Docker rebuilds, you can cache the build artifacts
# by adding: --mount=type=cache,target=/app/.next/cache
# This caches the .next/cache directory across builds, but it also prevents
# .next/cache/fetch-cache from being included in the final image, meaning
# cached fetch responses from the build won't be available at runtime.
RUN if [ -f package-lock.json ]; then \
npm run build; \
elif [ -f yarn.lock ]; then \
corepack enable yarn && yarn build; \
elif [ -f pnpm-lock.yaml ]; then \
corepack enable pnpm && pnpm build; \
else \
echo "No lockfile found." && exit 1; \
fi
# ============================================
# Stage 3: Run Next.js application
# ============================================
FROM node:${NODE_VERSION} AS runner
# Set working directory
WORKDIR /app
# Set production environment variables
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the run time.
# ENV NEXT_TELEMETRY_DISABLED=1
# Copy production assets
COPY --from=builder --chown=node:node /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown node:node .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=node:node /app/.next/standalone ./
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
# If you want to persist the fetch cache generated during the build so that
# cached responses are available immediately on startup, uncomment this line:
# COPY --from=builder --chown=node:node /app/.next/cache ./.next/cache
# Switch to non-root user for security best practices
USER node
# Expose port 3000 to allow HTTP traffic
EXPOSE 3000
# Start Next.js standalone server
CMD ["node", "server.js"]- .dockerignore
############################################################
# Production-ready .dockerignore for a Next.js (Vercel-style) app
# Keeps Docker builds fast, lean, and free of development files.
############################################################
# Dependencies (installed inside Docker, never copied)
node_modules/
.pnpm-store/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Next.js build outputs (always generated during `next build`)
.next/
out/
dist/
build/
.vercel/
# Tests and testing output (not needed in production images)
coverage/
.nyc_output/
__tests__/
__mocks__/
jest/
cypress/
cypress/screenshots/
cypress/videos/
playwright-report/
test-results/
.vitest/
vitest.config.*
jest.config.*
cypress.config.*
playwright.config.*
*.test.*
*.spec.*
# Local development and editor files
.git/
.gitignore
.gitattributes
.vscode/
.idea/
*.swp
*.swo
*~
*.log
# Environment variables (only commit template files)
.env
.env*.local
.env.development
.env.test
.env.production.local
# Docker configuration files (not needed inside build context)
Dockerfile*
.dockerignore
compose.yaml
compose.yml
docker-compose*.yaml
docker-compose*.yml
# Documentation
*.md
docs/
# CI/CD configuration files
.github/
.gitlab-ci.yml
.travis.yml
.circleci/
Jenkinsfile
# Cache directories and temporary data
.cache/
.parcel-cache/
.eslintcache
.stylelintcache
.swc/
.turbo/
.tmp/
.temp/
# TypeScript build metadata
*.tsbuildinfo
# Sensitive or unnecessary configuration files
*.pem
.editorconfig
.prettierrc*
prettier.config.*
.eslintrc*
eslint.config.*
.stylelintrc*
stylelint.config.*
.babelrc*
*.iml
*.ipr
*.iws
# OS-specific junk
.DS_Store
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
Desktop.ini
# AI/ML tool metadata and configs
.cursor/
.cursorrules
.copilot/
.copilotignore
.github/copilot/
.gemini/
.anthropic/
.kiro
.claude
AGENTS.md
.agents/
# AI-generated temp files
*.aider*
*.copilot*
*.chatgpt*
*.claude*
*.gemini*
*.openai*
*.anthropic*- 打开/安装docker
使用下面指令封装一个可使用的镜像
docker build . -t ghcr.io/gegepos/yujie-mono-docs:0.0.1 --platform linux/amd64存在问题:
- Docker 会墙掉我们的网络,有多种解决方案
使用科学上网法,但是也不一定能下载相关依赖
使用渡渡鸟/道客云,搜索渡渡鸟镜像网站,去拉取无法下载的镜像依赖,这里举例,我的docker.io/library/node下不下来,从网站找到相关资源,找到国内镜像地址
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:24.13.0-slim
- 拉取后查看拉取的镜像是否安装成功
docker images | grep node # 结果 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node 24.13.0-slim 66e04fe4abd0 3 months ago 224MB
- 给拉取的本地镜像打成我们需要的标签
docker tag <实际镜像名> node:24.13.0-slim # 例子 docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:24.13.0-slim node:24.13.0-slim这样 Dockerfile 中的 FROM node:24.13.0-slim 就会使用本地镜像 3. 再次调用上述封装镜像代码
道客云:
- https://github.com/DaoCloud/public-image-mirror
- 在里头找文档,查看如何使用,需要拼接他的前缀
- 例子
docker pull m.daocloud.io/docker.io/library/node:24.13.0-slim
- 后续同上
镜像上传github
- github上settings>Personal Access tokens>Tokens(classic)里头创建新的token(classic)

- 需要选上write和read Packges权限就可以了

-
然后复制token密钥,记住要保存起来
-
在终端中使用docker上传到github
# 登录github
docker login ghcr.io
# 输入你的github用户名和刚才记录的token密钥(作为Password)
# 登录成功后
# docker push ghcr.io/xxx(github用户名小写)/镜像名:版本号
docker push ghcr.io/gegepos/yujie-mono-docs:0.0.1服务器部署
- Docker安装(使用ubantu的服务演示,不同系统指令不一样)
# 更新 apt-get
sudo apt-get update
# 安装 docker
sudo apt-get install docker.io
# 检查版本
docker -v- 登录镜像仓库
sudo docker login ghcr.io
# 跟之前一样输入github账号名称和token密钥- 启动
# 去拉取并启动镜像
sudo docker run -d --name yujie-docs -e KEY:Value -p 80:3000 ghcr.io/gegepos/yujie-mono-docs:0.0.1