Перейти к содержимому

23. Деплой

Nuxt 3 построен на Nitro — универсальном серверном движке, который поддерживает деплой на десятки платформ с единым кодом. От serverless до Docker — выбор за вами.


Vercel — самый простой деплой для Nuxt 3 без единой строки конфигурации:

Окно терминала
npm i -g vercel
vercel
# или через Git интеграцию — просто подключить репозиторий
// nuxt.config.ts — Vercel пресет (устанавливается автоматически)
export default defineNuxtConfig({
nitro: {
preset: 'vercel' // или 'vercel-edge'
}
})
// vercel.json — дополнительные настройки
{
"buildCommand": "nuxt build",
"outputDirectory": ".output/public",
"framework": "nuxtjs",
"functions": {
"server/**/*.js": {
"memory": 1024,
"maxDuration": 30
}
}
}

Возможности Vercel:

  • ✅ Автоматический HTTPS
  • ✅ Edge Functions с preset: 'vercel-edge'
  • ✅ Preview Deployments для каждого PR
  • ✅ ISR (Incremental Static Regeneration)
  • ✅ Analytics и мониторинг

Окно терминала
# Деплой через Netlify CLI
npm i -g netlify-cli
netlify deploy --build
netlify.toml
[build]
command = "npm run build"
publish = ".output/public"
[build.environment]
NODE_VERSION = "20"
NITRO_PRESET = "netlify"
[[plugins]]
package = "@netlify/plugin-nextjs"
[[headers]]
for = "/_nuxt/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'netlify'
}
})

Классический деплой на собственный сервер:

Окно терминала
# Сборка для Node.js
npm run build
# Запуск
node .output/server/index.mjs
nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'node-server'
}
})

Структура после сборки:

.output/
├── server/
│ └── index.mjs # точка входа
├── public/ # статические файлы
└── nitro.json # мета-информация

Окно терминала
# Установка PM2
npm install -g pm2
# Запуск с PM2
pm2 start .output/server/index.mjs --name "nuxt-app"
# Автозапуск при перезагрузке
pm2 startup
pm2 save
// ecosystem.config.js
module.exports = {
apps: [{
name: 'nuxt-app',
script: '.output/server/index.mjs',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 3000,
DATABASE_URL: 'postgresql://...'
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_date_format: 'YYYY-MM-DD HH:mm Z'
}]
}
Окно терминала
pm2 start ecosystem.config.js --env production
pm2 monit # Мониторинг

Nuxt Nitro в standalone-режиме идеален для Docker:

# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production образ
FROM node:20-alpine AS runner
WORKDIR /app
# Копируем только output (standalone)
COPY --from=builder /app/.output /app/.output
ENV HOST=0.0.0.0
ENV PORT=3000
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]
docker-compose.yml
version: '3.8'
services:
nuxt-app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- NUXT_PUBLIC_API_URL=${API_URL}
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
depends_on:
- nuxt-app

Для edge-деплоя с минимальной задержкой:

Окно терминала
# Установка Wrangler
npm install -g wrangler
wrangler login
nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages'
}
})
wrangler.toml
name = "nuxt-app"
compatibility_date = "2024-01-01"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".output/public"
[vars]
NUXT_PUBLIC_API_URL = "https://api.example.com"
Окно терминала
# Деплой на Cloudflare Pages
wrangler pages deploy .output/public

ПресетПлатформаКоманда
vercelVercel FunctionsАвто
vercel-edgeVercel EdgeNITRO_PRESET=vercel-edge
netlifyNetlify FunctionsАвто
cloudflare-pagesCloudflare Pageswrangler pages deploy
node-serverNode.jsnode .output/server/index.mjs
bunBun runtimebun .output/server/index.mjs
deno-serverDeno runtimedeno run
aws-lambdaAWS LambdaSAM/CDK
firebaseFirebase Functionsfirebase deploy
herokuHerokugit push heroku main

nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Только сервер
databaseUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET,
// Клиент + сервер
public: {
apiUrl: process.env.NUXT_PUBLIC_API_URL || 'https://api.example.com',
appName: process.env.NUXT_PUBLIC_APP_NAME || 'MyApp'
}
}
})
Окно терминала
# .env (локальная разработка)
DATABASE_URL=postgresql://localhost:5432/mydb
JWT_SECRET=my-secret-key
NUXT_PUBLIC_API_URL=http://localhost:3001
NUXT_PUBLIC_APP_NAME=MyApp Dev

nginx.conf
server {
listen 80;
server_name myapp.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# Статические файлы с долгим кешем
location /_nuxt/ {
proxy_pass http://nuxt-app:3000;
expires 1y;
add_header Cache-Control "public, immutable";
}
# API без кеша
location /api/ {
proxy_pass http://nuxt-app:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Cache-Control "no-store";
}
# Всё остальное
location / {
proxy_pass http://nuxt-app:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
}