Skip to Content
Welcome to yujie-code-blogs build by Nextra 4.0 🎉
Docker 部署Next.js 部署

Next.js部署

准备工作

  • 一台服务器
  • node环境
  • 项目

使用Docker封装镜像

  1. 项目编译准备
  • 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*
  1. 打开/安装docker

使用下面指令封装一个可使用的镜像

docker build . -t ghcr.io/gegepos/yujie-mono-docs:0.0.1 --platform linux/amd64

存在问题:

  1. Docker 会墙掉我们的网络,有多种解决方案
    1. 使用科学上网法,但是也不一定能下载相关依赖

    2. 使用渡渡鸟/道客云,搜索渡渡鸟镜像网站,去拉取无法下载的镜像依赖,这里举例,我的docker.io/library/node下不下来,从网站找到相关资源,找到国内镜像地址

      docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node:24.13.0-slim
      1. 拉取后查看拉取的镜像是否安装成功
      docker images | grep node # 结果 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/node 24.13.0-slim 66e04fe4abd0 3 months ago 224MB
      1. 给拉取的本地镜像打成我们需要的标签
      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. 再次调用上述封装镜像代码

    3. 道客云:

      1. https://github.com/DaoCloud/public-image-mirror 
      2. 在里头找文档,查看如何使用,需要拼接他的前缀
      3. 例子
      docker pull m.daocloud.io/docker.io/library/node:24.13.0-slim
      1. 后续同上

镜像上传github

  1. github上settings>Personal Access tokens>Tokens(classic)里头创建新的token(classic)

![image-20260429192847438](/Users/gegepos/Library/Application Support/typora-user-images/image-20260429192847438.png)

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

![image-20260429192924280](/Users/gegepos/Library/Application Support/typora-user-images/image-20260429192924280.png)

  1. 然后复制token密钥,记住要保存起来

  2. 在终端中使用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