логотип PurpleSchool
логотип PurpleSchool

Как развернуть Nuxt приложение в Docker

Автор

Олег Марков

Введение

В современном веб-разработке контейнеризация приложений становится не просто трендом, а стандартом, позволяющим сделать деплой predictible, быстрым и независимым от окружения. Если вы работаете с фреймворком Nuxt, который построен на базе Vue и Node.js, знание того, как развернуть ваше Nuxt-приложение в Docker, сэкономит много времени как на этапе локальной разработки, так и при публикации в облаке или на сервере компании.

В этой статье разберем по шагам, как упаковать Nuxt-приложение в контейнер Docker, настроить зависимости, работу с переменными окружения и запуск приложения в production-режиме. Я отдельно покажу примеры Dockerfile, вариант docker-compose, дам советы по оптимизации образов и разберу, как можно обновлять контейнер без даунтайма. Если вы только начинаете работу с Docker или уже знакомы с ним, но впервые сталкиваетесь с контейнеризацией Nuxt — эта инструкция для вас.

Что такое Docker и зачем он Nuxt-приложению

Docker позволяет запускать приложения в изолированных средах, которые называются контейнерами. Каждый контейнер содержит все, что нужно для работы приложения — код, библиотеки, зависимости и даже нужную версию Node.js. Это значит, что вы получите одинаковое поведение приложения на всех этапах: от разработки до прода.

В случае с Nuxt это дает такие преимущества:

  • Неважно какие версии Node.js или Yarn установлены на вашем сервере/ПК
  • Нет пересечений зависимостей между проектами на одной машине
  • Конфигурации для деплоя становятся унифицированными и простыми
  • Легче масштабировать приложение в Kubernetes, AWS ECS или на любом облаке

Обзор вариантов запуска Nuxt в Docker

У Nuxt две основные модели запуска:

  • Режим разработки (nuxt dev) — для локальной работы, удобен при разработке, но не для продакшна.
  • Сборка и запуск готовой статики (nuxt build
    • nuxt start) — правильный подход для продакшна.

В Docker чаще всего используются два сценария:

  1. Production mode — приложение билдится, собирается один финальный Docker-образ и запускается с помощью nuxt start.
  2. Development mode — меньше оптимизаций, чаще используются volume для "горячей" подгрузки кода.

В этой статье основной акцент будет на production-scenario, потому что именно он нужен для реального деплоя на сервер.

Docker сильно упрощает процесс развертывания, но не решает все проблемы. Чтобы ваше Nuxt-приложение было не только контейнеризировано, но и масштабируемо, производительно и удобно в поддержке, нужно понимать принципы работы Nuxt изнутри. Если вы хотите узнать все тонкости работы с Nuxt, от настройки окружения до server endpoints, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Шаг 1. Подготавливаем проект Nuxt

Для начала, у вас должен быть готов работающий проект Nuxt. Если вы только начинаете и у вас еще нет проекта, сгенерировать новый можно так:

npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev   # для проверки, что проект стартует

Проверьте, что приложение открывается на http://localhost:3000 (стандартный порт Nuxt).

Шаг 2. Базовая структура Dockerfile для Nuxt

Теперь давайте создадим Dockerfile в корне проекта.

Пример простого Dockerfile

# Выбираем официальный Node.js образ. Лучше брать LTS (долгосрочную поддержку)
FROM node:18-alpine

# Создаем рабочую директорию внутри контейнера
WORKDIR /usr/src/app

# Копируем package.json и package-lock.json (или yarn.lock) отдельно, чтобы ускорить сборку через кеширование слоев
COPY package*.json ./

# Устанавливаем зависимости
RUN npm install --production

# Копируем все остальное (кроме того, что в .dockerignore)
COPY . .

# Собираем приложение Nuxt (создается папка .output)
RUN npm run build

# Экспонируем порт (3000 — стандартный у Nuxt, можно другой)
EXPOSE 3000

# Стартуем приложение
CMD [ "npm", "run", "start" ]

Советы по Dockerfile

  • Используйте .dockerignore, чтобы не копировать node_modules, .git и лишние файлы — это ускоряет сборку и уменьшает размер образа.
  • Если используете Yarn или pnpm — меняйте команды установки зависимостей.

Пример .dockerignore

Создайте файл .dockerignore рядом с Dockerfile:

node_modules
.git
.dockerignore
Dockerfile
npm-debug.log
dist
coverage

Это поможет избежать лишних файлов в docker-образе.

Шаг 3. Оптимизация Dockerfile — multi-stage build

Смотрите, я покажу вам, как уменьшить размер итогового образа за счет так называемой "многоступенчатой сборки" — multi-stage build. Обычно это полезно для production-сценария.

# Первая стадия — билд приложения
FROM node:18-alpine AS build

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install

COPY . .
RUN npm run build   # Сборка Nuxt-приложения

# Вторая стадия — только для запуска (тут меньше всего файлов!)
FROM node:18-alpine AS production

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production

# Копируем собранную папку .output из стадии build
COPY --from=build /usr/src/app/.output ./.output
COPY --from=build /usr/src/app/public ./public

EXPOSE 3000
CMD [ "npm", "run", "start" ]

Обратите внимание, что тут в финальный образ попадет минимум файлов, то есть node_modules только прод-зависимости, и собранный билд.

Шаг 4. Поддержка переменных окружения

Nuxt поддерживает переменные окружения (например, разные API адреса или ключи), которые можно менять без rebuild контейнера.

Как использовать переменные окружения

В nuxt.config.ts или nuxt.config.js можно обращаться к переменным так:

export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      apiBase: process.env.API_BASE || 'http://localhost:1337'
    }
  }
})

Теперь вы можете запускать контейнер так:

docker run -p 3000:3000 --env API_BASE=https://my-api.example.com my-nuxt-app

Если запускаете через Docker Compose, переменные можно хранить в .env или прописывать явно.

Особенности работы переменных

  • Значения переменных доступных через runtimeConfig.public будут проброшены на клиент.
  • Секретные значения кладите в runtimeConfig (без "public"!), они будут доступны только на сервере.

Шаг 5. Docker Compose — расширенная конфигурация

Если у вас несколько сервисов (например, вы используете отдельную БД или бекенд), удобнее применять docker-compose.yml.

Пример docker-compose.yml

version: '3.8'
services:
  nuxt:
    build: .
    ports:
      - '3000:3000'
    environment:
      API_BASE: 'http://backend:8080'
    depends_on:
      - backend

  backend:
    image: mycompany/backend:latest
    ports:
      - '8080:8080'

Теперь оба сервиса стартуют командой:

docker compose up --build

Если вы разрабатываете, добавьте volume для "живой" перезагрузки (hot reload), и поменяйте команду запуска на npm run dev.

Шаг 6. Дополнительные настройки и рекомендации

1. Работа с портами

По умолчанию Nuxt слушает порт 3000 внутри контейнера. При запуске или в compose всегда указывайте проброс портов в формате "ХОСТ:КОНТЕЙНЕР", например, -p 8000:3000.

2. Использование Docker Secrets

Если нужно хранить секретные ключи, используйте Docker Secrets (в Swarm или Compose v3.7+). Для обычной разработки хватит переменных окружения, но никогда не оставляйте секреты в nuxt.config.* или прямо в коде.

3. Использование node_modules

Docker-образ содержит свои node_modules, не используйте volume с node_modules между хостом и контейнером (это разные окружения и могут быть несовместимости).

4. Nginx для статики и реверс-прокси

Иногда Nuxt-приложение можно запускать за nginx. Страницы SSR рендерит Nuxt, а статику (картинки, fonts) — nginx. Это может добавить производительности.

Пример конфигурации:

location /_nuxt/ {
    alias /usr/src/app/.output/public/_nuxt/;
    access_log off;
    expires max;
}
location / {
    proxy_pass http://localhost:3000; # Туда, где Nuxt слушает запросы
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

Пример полного цикла: сборка, запуск и обновление

1. Сборка образа

docker build -t my-nuxt-app .

2. Запуск контейнера

docker run -d --name nuxt-container -p 3000:3000 my-nuxt-app

3. Остановка и обновление контейнера

Чтобы обновить приложение:

  • Скачайте новые изменения кода
  • Повторно соберите образ
  • Остановите и удалите старый контейнер
  • Запустите новый контейнер на том же порте
docker stop nuxt-container
docker rm nuxt-container
docker build -t my-nuxt-app .
docker run -d --name nuxt-container -p 3000:3000 my-nuxt-app

Как видите, весь процесс контролируется пара команд.

Развертывание в Docker — это лишь один из этапов жизненного цикла приложения. Чтобы создавать полноценные, готовые к production проекты на Nuxt, необходимо освоить все аспекты фреймворка, от роутинга и стилизации до работы с данными и авторизацией. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.

Частозадаваемые технические вопросы

Как выкатить Nuxt-приложение с build-time переменными окружения?

Env-переменные, прочитанные через process.env внутри nuxt.config.js, "замораживаются" на этапе сборки. Если вы хотите обновлять переменные без rebuild, используйте runtimeConfig. Для правильной работы используйте только runtimeConfig.public, чтобы переменные шли на клиент, а если только серверу — без "public".

Как добавить HTTPS или переслать трафик на 443 порт?

Nuxt сам по себе не работает как HTTPS-сервер, особенно в production. Используйте внешние прокси (nginx, traefik) и настройте SSL на них, а Nuxt слушает внутри только 3000.

Как настроить hot-reload при разработке в контейнере?

Используйте volume для кода, например: ```yaml services: nuxt: build: . command: npm run dev ports:

  - "3000:3000"
volumes:
  - .:/usr/src/app
  - /usr/src/app/node_modules   # чтобы не пересекались node_modules с хостом

``` Это даст live reload изменений в коде.

Можно ли делать multi-stage build с Yarn/pnpm?

Да, просто поменяйте все npm install на yarn install --frozen-lockfile или pnpm install --frozen-lockfile на всех этапах Dockerfile.

Как деплоить Nuxt-приложение на сервер с помощью Docker?

Соберите образ на вашем CI/CD или локально, загрузите его в реестр (Docker Hub, GitHub Packages), подключитесь к серверу, скачайте и запустите через docker run или docker-compose. Проверьте проброс портов, настроив firewall и reverse proxy.

Стрелочка влевоКак отлавливать и обрабатывать ошибки в NuxtРуководство по развертыванию приложений в Nuxt CloudСтрелочка вправо

Постройте личный план изучения Nuxt до уровня Middle — бесплатно!

Nuxt — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtГенерация статического сайта с помощью NuxtРуководство по получению данных с Fetch в NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак запустить Nuxt-приложение в productionКак работает Server-Side Rendering SSR в NuxtНастройка и оптимизация серверной части Nuxt-приложенияРуководство по настройке маршрутизации в NuxtКакие проекты разумно реализовывать на NuxtИнструкция по управлению пакетами NPM в NuxtИнтеграция Node.js для Nuxt-приложенияНастройка мета-тегов для SEO в NuxtНастройка и использование HTTPS в NuxtКак отлавливать и обрабатывать ошибки в NuxtКак развернуть Nuxt приложение в DockerРуководство по развертыванию приложений в Nuxt CloudКак оптимизировать сборку на NuxtИнтеграция Laravel и Nuxt
Открыть базу знаний

Лучшие курсы по теме

Иконка ракетыСкоро!
изображение курса

Nuxt

Антон Ларичев
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий