Chuyển đến nội dung chính

第 21 課:部署與託管

Nuxt 部署目標(節點、靜態、邊緣)。 Vercel、Netlify、Cloudflare Pages、AWS。 Docker 部署,Dockerfile。 GitHub Actions CI/CD。環境變數管理。

💻 程式設計 — 第 21 課 第 21 課:部署與託管

Vue.js 和 Nuxt:從基礎到高級

第 6 部分:測試、部署和生產

亞洲開發網

1. 部署目標

預設輸出使用案例
節點伺服器Node.js 伺服器VPS、Docker、PM2
靜態。靜態的靜態 HTMLNetlify,GitHub 頁面
cloudflare 頁面邊緣工人雲耀
韋爾塞爾無伺服器韋爾塞爾
網路化無伺服器Netflix
// nuxt.config.ts
export default defineNuxtConfig({
  // Auto-detect hoặc set thủ công
  nitro: {
    preset: 'node-server', // 'cloudflare-pages' | 'vercel' | ...
  },
})

2.Docker部署

# Dockerfile
FROM node:20-alpine AS base
RUN corepack enable

FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

FROM base AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build

FROM base AS runtime
WORKDIR /app
COPY --from=build /app/.output ./.output

ENV NODE_ENV=production
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000
EXPOSE 3000

USER node
CMD ["node", ".output/server/index.mjs"]
# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "3000:3000"
    env_file: .env.production
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 5s
      retries: 3

3. 部署到 Vercel

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel --prod
// vercel.json
{
  "buildCommand": "nuxt build",
  "outputDirectory": ".output",
  "framework": "nuxtjs"
}

4.Cloudflare 頁面

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'cloudflare-pages',
  },
})
# Deploy via Wrangler
npx wrangler pages deploy .output/public

5. 環境變數

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // Server-only (NUXT_ prefix)
    databaseUrl: process.env.NUXT_DATABASE_URL,
    jwtSecret: process.env.NUXT_JWT_SECRET,
    // Public (NUXT_PUBLIC_ prefix)
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE || '/api',
      appName: 'My App',
    },
  },
})
# .env.production
NUXT_DATABASE_URL=postgresql://user:pass@host:5432/db
NUXT_JWT_SECRET=super-secret-key
NUXT_PUBLIC_API_BASE=https://api.example.com

6.GitHub Actions CI/CD

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - run: pnpm install --frozen-lockfile

      - run: pnpm test
        env:
          NUXT_PUBLIC_API_BASE: http://localhost:3000

      - run: pnpm build

      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /app
            docker compose pull
            docker compose up -d --build

7. PM2 產生

// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: 'nuxt-app',
    script: '.output/server/index.mjs',
    instances: 'max',
    exec_mode: 'cluster',
    env_production: {
      NODE_ENV: 'production',
      NUXT_PORT: 3000,
    },
  }],
}
pm2 start ecosystem.config.cjs --env production
pm2 save
pm2 startup

下一篇: 生產監控和最佳實踐 — 哨兵、日誌記錄、安全。