Олег Марков
Как развернуть 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 чаще всего используются два сценария:
- Production mode — приложение билдится, собирается один финальный Docker-образ и запускается с помощью
nuxt start
. - 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 до уровня Middle — бесплатно!
Nuxt — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Nuxt
Лучшие курсы по теме

Nuxt
Антон Ларичев
TypeScript с нуля
Антон Ларичев