Ultimate NestJS Dockfile для оптимизированного производственного образа и локальной разработки
27 апреля 2023 г.В этой статье
- 🚢 Вместе напишем многоэтапную сборку докера.
- 🎉 Мы узнаем, как использовать файл docker в разработке и производстве.
- ✨ Мы будем применять некоторые рекомендации, рекомендованные командой Docker.
Поехали.
Во-первых, давайте подумаем о вариантах использования для разработки сборки Docker:
* Чтобы установить все зависимости для поддержки локального сервера разработки. * Для запуска рабочего сервера с оптимизированным пакетом.
Чтобы охватить оба варианта использования, мы будем использовать многоэтапные сборки Docker и разделить сборка в 3 этапа:
* 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. * После завершения сборки мы установим зависимости только для рабочей среды и очистим кэш пряжи а>. Это уменьшит размер пакета. п
# Dockerfile
#
# 🏡 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
Этап "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
построит тот же образ.
Ссылки
- Справочник по файлу Compose версии 3 – Docker Docs
- Разработка с помощью Docker — Документация по Docker
- Многоэтапные сборки — Документация по Docker
- Узел — Docker Hub
- node:alpine — GitHub
- NestCLI и скрипты — NestJS
- ПОЛЬЗОВАТЕЛЬ — Docker Docs
- yarn.lock — Пряжа
- кэш пряжи — пряжа
:::информация Эта статья изначально была опубликована на веб-сайт Доу-Чи.
:::
Оригинал