Ultimate NestJS Dockfile для оптимизированного производственного образа и локальной разработки

Ultimate NestJS Dockfile для оптимизированного производственного образа и локальной разработки

27 апреля 2023 г.

В этой статье

  • 🚢 Вместе напишем многоэтапную сборку докера.
  • 🎉 Мы узнаем, как использовать файл docker в разработке и производстве.
  • ✨ Мы будем применять некоторые рекомендации, рекомендованные командой Docker.

Поехали.


Во-первых, давайте подумаем о вариантах использования для разработки сборки Docker:

* Чтобы установить все зависимости для поддержки локального сервера разработки. * Для запуска рабочего сервера с оптимизированным пакетом.

Чтобы охватить оба варианта использования, мы будем использовать многоэтапные сборки Docker и разделить сборка в 3 этапа:

Docker stages

* dev: просто установить все зависимости. * сборка: для компиляции рабочей сборки с оптимизированным размером пакета. * prod: для обслуживания рабочей сборки.

Многоэтапная сборка Docker

Этап «Разработка»

Это довольно просто. Все, что нам нужно сделать, это установить зависимости npm и применить некоторые рекомендации:

* Мы будем использовать «node:alpine» в качестве базового образа, чтобы создать изображение минимального размера. * Мы установим отсутствующие общие библиотеки с node:alpine. * Мы назначим Docker пользователя без полномочий root, чтобы ограничить его привилегии. * Мы установим среду «разработка». * Мы установим зависимости на основе файла блокировки пряжи, чтобы добиться единообразной установки на всех компьютерах.

# Dockerfile

#
# 🧑‍💻 Development
#
FROM node:18-alpine as dev
# add the missing shared libraries from alpine base image
RUN apk add --no-cache libc6-compat
# Create app folder
WORKDIR /app

# Set to dev environment
ENV NODE_ENV development

# Create non-root user for Docker
RUN addgroup --system --gid 1001 node
RUN adduser --system --uid 1001 node

# Copy source code into app folder
COPY --chown=node:node . .

# Install dependencies
RUN yarn --frozen-lockfile

# Set Docker as a non-root user
USER node

n Этап сборки

Этап сборки — самый интересный этап. Цель состоит в том, чтобы скомпилировать исходный код и сгенерировать наименьшее количество ресурсов.

* Мы будем использовать тот же базовый образ и рекомендации как этап разработки. * Мы установим среду «производство». * Мы скопируем зависимости, установленные на этапе разработки, для запуска скрипта сборки Nest CLI. * После завершения сборки мы установим зависимости только для рабочей среды и очистим кэш пряжи. Это уменьшит размер пакета. п

Этап "Product"

Теперь, когда у нас есть оптимизированная производственная сборка, мы можем завершить сборку докера, обслуживая сервер NestJS.

* Мы будем использовать тот же базовый образ и рекомендации, что и этап сборки. * Мы скопируем скомпилированный вывод и рабочие модули node_modules со стадии сборки. Это необходимые файлы, которые нам нужны для запуска сервера. * Наконец, запустите сервер с Node. На данном этапе команда «nest start» недоступна, так как интерфейс командной строки Nest зависит от разработчиков.

# Dockerfile

#
# 🚀 Production Server
#
FROM node:18-alpine as prod

WORKDIR /app
RUN apk add --no-cache libc6-compat

# Set to production environment
ENV NODE_ENV production

# Re-create non-root user for Docker
RUN addgroup --system --gid 1001 node
RUN adduser --system --uid 1001 node

# Copy only the necessary files
COPY --chown=node:node --from=build /app/dist dist
COPY --chown=node:node --from=build /app/node_modules node_modules

# Set Docker as non-root user
USER node

CMD ["node", "dist/main.js"]

Полный многоэтапный файл Docker

# Dockerfile

#
# 🧑‍💻 Development
#
FROM node:18-alpine as dev
# add the missing shared libraries from alpine base image
RUN apk add --no-cache libc6-compat
# Create app folder
WORKDIR /app

# Set to dev environment
ENV NODE_ENV dev

# Create non-root user for Docker
RUN addgroup --system --gid 1001 node
RUN adduser --system --uid 1001 node

# Copy source code into app folder
COPY --chown=node:node . .

# Install dependencies
RUN yarn --frozen-lockfile

# Set Docker as a non-root user
USER node

#
# 🏡 Production Build
#
FROM node:18-alpine as build

WORKDIR /app
RUN apk add --no-cache libc6-compat

# Set to production environment
ENV NODE_ENV production

# Re-create non-root user for Docker
RUN addgroup --system --gid 1001 node
RUN adduser --system --uid 1001 node

# In order to run `yarn build` we need access to the Nest CLI.
# Nest CLI is a dev dependency.
COPY --chown=node:node --from=dev /app/node_modules ./node_modules
# Copy source code
COPY --chown=node:node . .

# Generate the production build. The build script runs "nest build" to compile the application.
RUN yarn build

# Install only the production dependencies and clean cache to optimize image size.
RUN yarn --frozen-lockfile --production && yarn cache clean

# Set Docker as a non-root user
USER node

#
# 🚀 Production Server
#
FROM node:18-alpine as prod

WORKDIR /app
RUN apk add --no-cache libc6-compat

# Set to production environment
ENV NODE_ENV production

# Re-create non-root user for Docker
RUN addgroup --system --gid 1001 node
RUN adduser --system --uid 1001 node

# Copy only the necessary files
COPY --chown=node:node --from=build /app/dist dist
COPY --chown=node:node --from=build /app/node_modules node_modules

# Set Docker as non-root user
USER node

CMD ["node", "dist/main.js"]

Как использовать его в локальной разработке

Сложная часть закончена!

Чтобы использовать файл докера для локальной разработки, все, что нам нужно сделать, это создать образ докера с этап разработки. Например, мы можем собрать и запустить сервер NestJS с режимом наблюдения в файле компоновки докеров:

# docker-compose.yml

services:
  api:
    container_name: nestjs
    image: nestjs-dev
    restart: unless-stopped
    build:
      context: .
      dockerfile: Dockerfile
      # ✨ Target the dev stage
      target: dev
    # Mount host directory to docker container to support watch mode
    volumes:
      - .:/app
      # This ensures that the NestJS container manages the node_modules folder
      # rather than synchronizes it with the host machine
      - /app/node_modules
    env_file:
      - docker.env
    ports:
      - 8082:8082
    networks:
      - nest
    depends_on:
      - postgres
    command: npx nest start --watch

  # ...other services

Как использовать его в работе

Вы можете просто создать производственный образ, создав все 3 этапа. Например, мы можем запустить «сборку докеров» в GitHub Actions как часть рабочего процесса развертывания.

# .github/workflows/ci.yml

jobs
  deploy:
    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: '18.x'

      - name: Build NestJS image
        env:
          REGISTRY: nestjs-regiestry
          REPOSITORY: nestjs-example
          IMAGE_TAG: example
        # ✨ target the production stage
        run: docker build . -t $REGISTRY/$REPOSITORY:$IMAGE_TAG --target prod

      # ...rest of the steps


Поскольку «prod» — это последний этап, нам не нужно указывать цель для команды сборки. Бег

docker build . -t $REGISTRY/$REPOSITORY:$IMAGE_TAG

построит тот же образ.

Ссылки


:::информация Эта статья изначально была опубликована на веб-сайт Доу-Чи.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE