Гид по технологиям

Docker и Nest.js: развёртывание приложения с Docker Compose

6 min read DevOps Обновлено 26 Dec 2025
Docker + Nest.js: развёртывание с Docker Compose
Docker + Nest.js: развёртывание с Docker Compose

Логотип Docker на тёмном фоне.

“Работает на моём компьютере…” — шуточная фраза разработчиков точно отражает проблему: среда разработки отличается от продакшена. Контейнеризация устраняет эту проблему, упаковывая приложение с нужными зависимостями в единый образ.

В этом материале вы получите понятную пошаговую инструкцию по развёртыванию Nest.js приложения с базой PostgreSQL в двух контейнерах через Docker Compose, а также рекомендации по безопасности, тестированию и публикации образа в Docker Hub.

Что такое Docker и Docker Compose

Docker — открытая платформа для контейнеризации: вы создаёте образы, которые включают приложение и его зависимости. Эти образы запускаются как изолированные контейнеры. Контейнеры даёт предсказуемое поведение приложения в разных средах.

Грузовое судно с сотнями цветных контейнеров

Docker Compose — инструмент для определения и управления многоконтейнерными приложениями. Если ваше приложение состоит из нескольких сервисов (веб-сервер, БД, очередь и т.д.), Compose позволяет описать их в одном файле и запускать как единое целое.

Важно: перед началом установите Docker Desktop и проверьте системные требования в официальной документации.

Что вы получите в руководстве

  • Готовый Dockerfile для Nest.js
  • docker-compose.yml с контейнером PostgreSQL
  • Настройка TypeORM через .env
  • Советы по безопасности и тестированию
  • Шаги для загрузки образа в Docker Hub

Подготовка проекта Nest.js

Это руководство создаёт два контейнера: сервер с Nest.js и контейнер PostgreSQL.

Установите CLI Nest.js:

npm i -g @nestjs/cli

Создайте новый проект:

nest new docker-nest-app

При создании выберите менеджер пакетов (в примере — npm). Затем перейдите в папку проекта и запустите dev-сервер:

cd docker-nest-app
npm run start

Модуль базы данных

Установите зависимости для PostgreSQL и TypeORM:

npm install pg typeorm @nestjs/typeorm @nestjs/config

В корне проекта создайте файл .env и добавьте параметры подключения к базе данных:

DATABASE_HOST="db"
DATABASE_PORT=5432
DATABASE_USER="testUser"
DATABASE_PASSWORD="mypassword123"

Создайте модуль базы данных:

nest g module database

Откройте файл database/database.module.ts и добавьте конфигурацию TypeORM:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot(),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DATABASE_HOST'),
        port: configService.get('DATABASE_PORT'),
        username: configService.get('DATABASE_USER'),
        password: configService.get('DATABASE_PASSWORD'),
        synchronize: true,
      }),
      inject: [ConfigService],
    }),
  ],
})
export class DatabaseModule {}

Пояснение: TypeOrmModule.forRootAsync даёт возможность читать значения из .env через ConfigService и подставлять их при старте приложения.

Обновление AppModule

Добавьте DatabaseModule и настройку ConfigModule в src/app.module.ts:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';

@Module({
  imports: [
    ConfigModule.forRoot({ envFilePath: '.env' }),
    DatabaseModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Dockerfile для Nest.js

Создайте в корне проекта файл Dockerfile со следующим содержимым:

FROM node:16.3.0-alpine3.13
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD [ "npm", "run", "start:dev" ]

Разбор команд:

  • FROM — базовый образ Node.js (alpine для компактного размера).
  • WORKDIR — рабочая директория в контейнере.
  • COPY package*.json ./ — копирование package.json и package-lock.json для установки зависимостей.
  • RUN npm install — установка зависимостей внутри образа.
  • COPY . . — копирование исходников приложения.
  • RUN npm run build — компиляция TypeScript в JavaScript (выход в dist).
  • CMD — команда по умолчанию; здесь запущен dev режим.

Примечание: для production лучше запускать компилированный dist с node, а не start:dev. В dev режиме контейнер удобен для локальной разработки.

docker-compose.yml

Создайте файл docker-compose.yml в корне проекта:

version: '3.9'

services:
  server:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - db
  db:
    image: 'postgres'
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: 'mypassword123'
      POSTGRES_USER: 'testUser'
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data:

Объяснение: Compose описывает два сервиса: server (строится из Dockerfile) и db (использует официальный образ postgres). Volumes сохраняют данные PostgreSQL между запусками.

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

Соберите и запустите стек командой:

docker compose up

После успешного запуска в логе вы увидите информацию о старте PostgreSQL и запуске Nest.js сервера на порту 3000.

Вывод терминала с логами двух запущенных Docker-контейнеров

Теперь можно продолжать разработку: добавлять сущности, репозитории и REST-контроллеры для CRUD.

Публикация образа в Docker Hub

Чтобы распределять образ через Docker Hub, выполните следующие шаги.

  1. Зарегистрируйтесь в Docker Hub и создайте репозиторий (можно публичный или приватный).

Форма создания репозитория образа на Docker Hub

  1. Войдите в Docker из терминала:
docker login
  1. Пометьте образ тегом в формате <ваш_пользователь>/<репозиторий>:
docker tag  /
  1. Отправьте образ в Docker Hub:
docker push /

После этого любой пользователь с доступом сможет загрузить образ через docker pull.

Практические советы и лучшие практики

  • Используйте .env для конфиденциальных данных, но не храните его в публичном репозитории.
  • Для production: используйте multi-stage Dockerfile, чтобы исключить dev-зависимости и уменьшить размер образа.
  • Старайтесь фиксировать версии образов и зависимостей (node:16.3.0-alpine3.13 → node:16-alpine).
  • Не запускайте контейнеры от root-пользователя внутри образа — добавьте непользовательского юзера.
  • Резервируйте volume для данных БД и бэкапов.

Безопасность и конфиденциальность

  • Храните секреты в безопасном хранилище (Vault, AWS Secrets Manager, Docker Secrets), а не в .env в репозитории.
  • Ограничьте сетевой доступ к базе данных: в Docker Compose можно настроить сети и включать контейнеры только в нужные сети.
  • Не публикуйте образы с секретами в Docker Hub.
  • Для соответствия требованиям GDPR: минимизируйте хранение персональных данных в контейнерах, шифруйте данные на уровне БД.

Тестирование и критерии приёмки

Критерии приёмки для рабочего развёртывания:

  • Контейнер server отвечает на / (или на health endpoint) с 200 за < 5 с.
  • Приложение успешно подключается к PostgreSQL и может выполнить простейший CRUD.
  • Volume базы сохранён после перезапуска контейнеров.
  • Логи приложения сохраняются и доступны (через docker logs или централизованную систему).

Минимальные тесты (локально):

  1. docker compose up
  2. Проверить доступность http://localhost:3000
  3. Выполнить HTTP-запросы к API и убедиться в корректности ответов
  4. Остановить контейнеры, удалить server, оставить volume и снова поднять — данные должны сохраниться

Когда контейнеризация не подходит (контрпримеры)

  • Если приложение зависит от аппаратного ускорения (например, GPU) и нет соответствующих драйверов в контейнере.
  • Если требуется тесная интеграция с хостовой ОС (специальные устройства), контейнер может усложнить работу.
  • Для очень простых статических сайтов контейнеризация может быть избыточной.

Альтернативы и эволюция инфраструктуры

  • Podman — альтернатива Docker без демона, совместимая с CLI Docker.
  • Kubernetes — следующий шаг после Docker Compose для оркестрации множества реплик и автоматического масштабирования.
  • Platform-as-a-Service (Heroku, Render) — упрощают деплой без управления контейнерами вручную.

Ментальная модель: Docker — упаковщик + изолятор; Compose — менеджер для локальной мультисервисной среды; Kubernetes — оркестратор для production-кластеров.

Mini-методология: от локального прототипа к production

  1. Локальный прототип с docker-compose и dev-режимом.
  2. Перевести Dockerfile в multi-stage для production.
  3. Обеспечить CI: сборка образа и автотесты в pipeline.
  4. Публикация образа в реестр (Docker Hub/registry).
  5. Развёртывание в оркестраторе (K8s) или PaaS.

Рольные чек-листы

Разработчик:

  • Локально запускает docker compose up
  • Пишет unit- и интеграционные тесты
  • Не хранит секреты в репозитории

DevOps-инженер:

  • Создаёт CI для сборки и проверки образов
  • Настраивает реестр образов и политики тегирования
  • Настраивает мониторинг и backup volume

Тестировщик:

  • Проверяет подключение к БД при рестарте контейнера
  • Тестирует сценарии отказа (упал БД → приложение корректно логирует)

Примеры команд для отладки

  • Просмотр логов сервиса:
docker compose logs -f server
  • Выполнение команд внутри контейнера:
docker compose exec server sh
  • Просмотр запущенных контейнеров:
docker ps

Сценарий отката (грубая инструкция)

  1. Остановить новые контейнеры: docker compose down
  2. Откатить образ на ранее протестированный тег: docker pull /:stable
  3. Обновить docker-compose.yml на нужный тег и поднять стек
  4. Проверить health endpoint и логи

Короткая аннотация для анонса

Запуск Nest.js с PostgreSQL в Docker Compose: быстрое практическое руководство по созданию Dockerfile, подключению TypeORM, публикации образа и рекомендациям по безопасности и тестированию.

Куда двигаться дальше

  • Перевести сборку в CI (GitHub Actions/GitLab CI) и автоматически публиковать образы.
  • Изучить Kubernetes и Helm-чарты для production-окружения.
  • Добавить supervisord/entrypoint-скрипты для миграций БД при старте контейнера.

Резюме

Использование Docker и Docker Compose упрощает переносимость Nest.js приложений между машинами и средами. Правильная конфигурация Dockerfile, docker-compose.yml и безопасное хранение секретов — ключ к стабильному и масштабируемому развёртыванию.

Important: для production переключитесь на multi-stage билды, безопасное хранение секретов и оркестрацию (Kubernetes) при необходимости.

Критерии приёмки выше помогут убедиться, что базовый стек работает корректно и готов к дальнейшей автоматизации.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Стрим Netflix в Discord — полный гид
Руководство

Стрим Netflix в Discord — полный гид

ИИ-озвученные аудиокниги: преимущества и риски
Аудиокниги

ИИ-озвученные аудиокниги: преимущества и риски

Как запускать и вести email‑рассылку
Маркетинг

Как запускать и вести email‑рассылку

Включение Tamper Protection в Microsoft Defender
Кибербезопасность

Включение Tamper Protection в Microsoft Defender

Как вернуть Проводник на панель задач в Windows 11
Windows 11

Как вернуть Проводник на панель задач в Windows 11

Очистка кэша Центра обновления Windows
Windows

Очистка кэша Центра обновления Windows