Ускорение деплоя NestJS и Angular с помощью общественных Github-раннеров и создания промежуточных Docker-образов
В этом посте я настрою сборку Docker-образов:
- Билдер NestJS и Angular приложений;
- Мигратор баз данных с помощью Flyway;
- Тест-раннер для запуска фронтенд и бэкенд E2E-тестов;
- Nginx c встроенной статикой Angular приложения;
- NestJS приложение.
1. Создаем Docker-образ со всеми зависимостями
В данном посте код и Docker-образа будут собираться на публичных раннерах, которые имеют лимит в месяц по общему времени выполнения и при интенсивной разработке этот лимит можно легко исчерпать, так что нужно быть готовыми переехать на собственный раннер.
В предыдущем посте зависимости устанавливались на хост машину в которой и происходила сборка кода, это было сделано в качестве примера того как можно, но так делать не нужно.
На хост машину нужно ставить минимальное количество программ и библиотек, так как любой сторонний софт может нести в себе вредоносное ПО, поэтому сборку кода нужно производить внутри специализированного Docker-контейнера.
Так как зависимости мы устанавливаем редко, то можно создать специальный Docker-образ который будет использоваться при сборке кода.
Папка с исходными файлами для сборки и папка для собранных файлов монтируется как volume
в контейнер при запуске.
Пересборка данного Docker-образа будет происходить при смене версии корневого package.json
.
Создаем файл .docker/builder.Dockerfile
FROM node:20.16.0-alpine AS builder
WORKDIR /usr/src/app
# Copy all files in repository to image
COPY --chown=node:node . .
# Install utils
RUN apk add dumb-init
# Clean up
RUN rm -rf /var/cache/apk/*
# Install deps
RUN npm install --prefer-offline --no-audit --progress=false
# Some utilities require a ".env" file
RUN echo '' > .env
FROM node:20.16.0-alpine
WORKDIR /usr/src/app
# Disable nx daemon
ENV NX_DAEMON=false
# Disable the statics server built into NestJS
ENV DISABLE_SERVE_STATIC=true
# Copy node_modules
COPY --from=builder /usr/src/app/node_modules /usr/src/app/node_modules
# Copy utility for "To work as a PID 1"
COPY --from=builder /usr/bin/dumb-init /usr/bin/dumb-init
# Copy the settings
COPY --from=builder /usr/src/app/.docker/.dockerignore /usr/src/app/.dockerignore
COPY --from=builder /usr/src/app/.docker/nx.json /usr/src/app/nx.json
COPY --from=builder /usr/src/app/package.json /usr/src/app/package.json
COPY --from=builder /usr/src/app/rucken.json /usr/src/app/rucken.json
COPY --from=builder /usr/src/app/tsconfig.base.json /usr/src/app/tsconfig.base.json
COPY --from=builder /usr/src/app/.env /usr/src/app/.env
# Copy the settings for linting
COPY --from=builder /usr/src/app/.nxignore /usr/src/app/.nxignore
COPY --from=builder /usr/src/app/.eslintrc.json /usr/src/app/.eslintrc.json
COPY --from=builder /usr/src/app/.eslintignore /usr/src/app/.eslintignore
COPY --from=builder /usr/src/app/.prettierignore /usr/src/app/.prettierignore
COPY --from=builder /usr/src/app/.prettierrc /usr/src/app/.prettierrc
COPY --from=builder /usr/src/app/jest.config.ts /usr/src/app/jest.config.ts
COPY --from=builder /usr/src/app/jest.preset.js /usr/src/app/jest.preset.js
# Install java
RUN apk add openjdk11-jre
# Clean up
RUN rm -rf /var/cache/apk/*
# We build the source code as the "node" user
# and set permissions for new files: full access from outside the container
CMD npm run build:prod
Для сборки кода, необходимо запустить контейнер с данным образом и смонтировать директории apps
, libs
и dist
.
Пример запуска:
docker run -v ./dist:/usr/src/app/dist -v ./apps:/usr/src/app/apps -v ./libs:/usr/src/app/libs ghcr.io/nestjs-mod/nestjs-mod-fullstack-builder:latest