Запуск приложения на основе фреймворка Nest (NestJS) на Dockhost
В данной статье мы рассмотрим деплой приложения, написанного на TypeScript (JavaScript) c использованием фреймворка Nest (NestJS).
В качестве примера возьмём небольшое приложение, состоящее из нескольких простых контроллеров. Исходный код данного приложения можно посмотреть здесь: example-nestjs.
Деплой приложения будет производиться на платформе Dockhost. В рамках примера предполагаем, что у пользователя есть учётная запись на платформе.
Подключение репозитория Git
Перед подключением репозитория, в корневой директории необходимо создать Dockerfile со следующим содержимым:
# Build stage
FROM node:lts-alpine AS builder
USER node
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY --chown=node:node . .
RUN npm run build && npm prune --omit=dev
# Final run stage
FROM node:lts-alpine
ENV NODE_ENV=production
USER node
WORKDIR /app
COPY --from=builder --chown=node:node /app/package*.json .
COPY --from=builder --chown=node:node /app/node_modules/ ./node_modules
COPY --from=builder --chown=node:node /app/dist/ ./dist
CMD ["node", "dist/main.js"]
Данный Dockerfile использует Multi-stage builds и базовый образ node:lts-alpine. На первом этапе устанавливаются все зависимости командой npm ci и производится сборка приложения командой npm run build, далее на следующем этапе копируются установленные зависимости и собранное приложение в директорию /app.
В качестве основной команды будет использоваться node dist/main.js. Данная команда запустит приложение, которое будет слушать 3000 порт.
Или таким Dockerfile:
FROM node:lts-alpine
WORKDIR /app
# Install app dependencies
COPY package*.json .
RUN npm ci
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN npm run build
CMD ["npm", "run", "start:prod"]
Данный Dockerfile устанавливает все зависимости командой npm ci и производит сборку приложения командой npm run build. В качестве основной команды будет использоваться npm run start:prod. Данная команда запустит приложение, которое будет слушать 3000 порт.
Вы можете добавить файл .dockerignore и указать в нём файлы или папки, которые не должны быть скопированы в контейнер.
Теперь в Вашем репозитории есть Dockerfile, и Вы можете подключить его (репозиторий) к платформе Dockhost. Для этого в проекте my-project (проект может быть любым, для примера мы будем использовать my-project, который создаётся по умолчанию при регистрации на платформе) необходимо перейти в раздел «Репозитории Git» и добавить репозиторий.
В нашем примере Git-репозиторий является публичным и не требует авторизации. Для того чтобы подключить приватный Git-репозиторий, необходимо указать имя пользователя и пароль в разделе «Авторизация».
Для подключения приватного репозитория GitHub необходимо вместо пароля использовать Personal access tokens.
Далее нажмите на кнопку «Применить» и дождитесь завершения процесса подключения репозитория и первой сборки контейнера из репозитория.
Как только процесс сборки будет завершён, в разделе «Контейнеры» появится контейнер приложения.
В логах контейнера будет запись об успешном старте приложения.
Настройка портов контейнера
Приложения Nest (NestJS) могут быть как сервисами (например, боты или консьюмеры), так и MVC-приложениями, которые принимают и обрабатывают различный HTTP-трафик. В нашем примере приложение является MVC, для его работы необходимо указать порт, который слушает приложение, для этого нажмите на кнопку «Управлять», чтобы перейти в раздел просмотра контейнера и на открывшейся странице нажмите на кнопку «Редактировать».
В открывшемся модальном окне, в разделе «Порты», добавьте новый порт 3000.
Далее нажмите на кнопку «Применить» и дождитесь завершения процесса перезапуска контейнера.
Настройка домена и маршрута
Теперь контейнер настроен и готов принимать входящий трафик на порт 3000. Для доступа к контейнеру из Интернета добавим динамический домен и настроим маршрутизацию трафика.
Для создания или подключения домена необходимо перейти в раздел «Сетевые сервисы», подраздел «Домены» и добавить домен.
Далее нажмите на кнопку «Применить» и дождитесь завершения процесса создания домена.
В нашем примере описывается динамический домен, который использует домен 3 уровня от платформы Dockhost. При необходимости Вы можете подключить свой домен.
Как только домен будет создан, необходимо настроить маршрутизацию трафика, для этого перейдите в раздел «Сетевые сервисы», подраздел «Маршруты» и добавьте новый маршрут.
Далее нажмите на кнопку «Применить» и дождитесь завершения процесса запуска сервиса маршрутизации.
При первом добавлении маршрута может потребоваться 1-2 минуты для запуска и настройки сервиса.
Вы можете увидеть карту сети проекта, если перейдёте в раздел «Сетевые сервисы», подраздел «Карта сети»:
Для получения IP-адреса пользователя используйте заголовок request.headers['x-real-ip']
Теперь приложение полностью настроено и запущено, а благодаря настройке деплоя через Push, при изменении кода, платформа Dockhost будет автоматически собирать и запускать новую версию приложения.
В дальнейшем Вы можете взять за основу наш репозиторий example-nestjs и расширить функционал, при необходимости добавив новые команды и функции.
Если у Вас уже есть свой проект, написанный на Node.js, Вы можете так же просто запустить его на платформе Dockhost, используя пошаговый алгоритм из нашей статьи. Для этого воспользуйтесь примерами Dockerfile и придерживайтесь описанной последовательности действий.
FAQ
- Как получить IP-адрес пользователя?
Так как запросы будут проходить через балансировщик платформы Dockhost, то для получения IP-адреса пользователя необходимо использовать заголовок x-real-ip.
const ip = request.headers['x-real-ip'];
Также можно настроить expressjs
app.set('trust proxy', ['loopback', 'uniquelocal']);
или fastify
const fastify = Fastify({ trustProxy: '127.0.0.1,10.0.0.0/8' });