Данная конфигурация представляет собой полный цикл разработки и развертывания серверного Nest.js приложения, начиная от написания кода и заканчивая его публикацией.
Сервер упакован в Docker контейнер, настроенный на работу с реверс прокси Traefik. Имеется два режима запуска проекта — developer и production.
Конфигурация используется в нашем приложении Messenger.
Ниже приведем код docker-compose.yml
(production):
services:
messenger-backend:
container_name: messenger-backend
build:
context: .
target: 'production-stage'
env_file:
- /data/secrets/${SERVER_DOMAIN}/messenger-backend/app.env
- /data/secrets/${SERVER_DOMAIN}/messenger-backend/static.env
environment:
PORT: 5000
NODE_ENV: production
POSTGRES_HOST: postgres
POSTGRES_USER: messenger
POSTGRES_DB: messenger
POSTGRES_PORT: 5432
WEB_CLIENT_URL: https://messenger.${SERVER_DOMAIN}
APP_CLIENT_URL: https://localhost
API_URL: https://msg.${SERVER_DOMAIN}
ACCESS_TOKEN_MAX_AGE: 60d
REFRESH_TOKEN_MAX_AGE: 15m
COOKIE_REFRESH_TOKEN_MAX_AGE: 6048000000
volumes:
- /data/appdata/messenger:/app/static/user
command: ["node", "dist/main.js"]
restart: unless-stopped
networks:
- proxynet
labels:
- "traefik.enable=true"
- "traefik.http.routers.msgbe.rule=Host(`msg.${SERVER_DOMAIN}`)"
- "traefik.http.routers.msgbe.entrypoints=https"
- "traefik.http.routers.msgbe.service=msgbe-service"
- "traefik.http.services.msgbe-service.loadbalancer.server.port=5000"
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
proxynet:
external: true
Для development так же есть свой docker-compose.dev.yml
:
services:
messenger-backend-dev:
container_name: messenger-backend-dev
build:
context: .
target: 'develop-stage'
env_file:
- /data/secrets/${SERVER_DOMAIN}/messenger-backend/app.env
- /data/secrets/${SERVER_DOMAIN}/messenger-backend/static.env
environment:
PORT: 5000
NODE_ENV: development
POSTGRES_HOST: postgres
POSTGRES_USER: messenger
POSTGRES_DB: messenger
POSTGRES_PORT: 5432
WEB_CLIENT_URL: https://messenger.${SERVER_DOMAIN}
APP_CLIENT_URL: https://localhost
API_URL: https://msg.${SERVER_DOMAIN}
ACCESS_TOKEN_MAX_AGE: 365d
REFRESH_TOKEN_MAX_AGE: 365d
COOKIE_REFRESH_TOKEN_MAX_AGE: 6048000000
volumes:
- .:/app:rw
- /data/appdata/messenger:/app/static/user
command: sh -c "npm install && npm run start:dev"
restart: unless-stopped
networks:
- proxynet
labels:
- "traefik.enable=true"
- "traefik.http.routers.msgbe.rule=Host(`msg.${SERVER_DOMAIN}`)"
- "traefik.http.routers.msgbe.entrypoints=https"
- "traefik.http.routers.msgbe.service=msgbe-service"
- "traefik.http.services.msgbe-service.loadbalancer.server.port=5000"
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
proxynet:
external: true
Его содержимое похоже на конфигурацию production, но есть несколько важных отличий:
target: 'develop-stage'
- В
volumes
добавляется еще.:/app:rw
, что позволяет в процессе разработки динамически обновлять файлы проекта в контейнере command: sh -c "npm install && npm run start:dev"
— здесь,npm install
необходимо указать для того, что бы дирекоторияnode_modules
была доступна для отслеживания зависимостей в VS Code.
Dockerfile
Эта конфигурация Dockerfile описывает многоэтапную сборку образа для Node.js приложения:
# develop stage
FROM node:22.8.0-alpine3.20 AS develop-stage
WORKDIR /app
COPY package*.json ./
RUN npm config set fund false --location=global
COPY . .
# build stage
FROM develop-stage AS build-stage
RUN npm install
RUN npm run build
# production stage
FROM node:22.8.0-alpine3.20 AS production-stage
WORKDIR /app
COPY --from=build-stage /app/node_modules /app/node_modules
COPY --from=build-stage /app/dist /app/dist
COPY --from=build-stage /app/static /app/static
COPY package.json ./
CMD ["node", "dist/main.js"]
EXPOSE 5000
Он состоит из трёх основных этапов:
- Разработка (develop stage):
- Базируется на Alpine-образе Node.js для его легковесности и эффективности.
- Устанавливает рабочую директорию
/app
. - Копирует файлы
package.json
иpackage-lock.json
(package*.json
для большей гибкости). - Отключает спам в консоли о финансировании (fund) пакетов в NPM.
- Копирует все остальные файлы приложения в контейнер.
- Сборка (build stage):
- Использует промежуточный образ
develop-stage
как основу. - Устанавливает зависимости с помощью
npm install
. - Запускает процесс сборки приложения с помощью
npm run build
, формируя конечную сборку в директорииdist
.
- Продакшн (production stage):
- Начинается с чистого Node.js Alpine-образа той же версии.
- Устанавливает рабочую директорию
/app
. - Копирует директорию
node_modules
изbuild-stage
для использования в продакшене. - Копирует директории
dist
иstatic
изbuild-stage
, содержащие скомпилированные и статические файлы приложения. - Копирует
package.json
. - Определяет, что при запуске контейнера должен исполняться файл
dist/main.js
через Node.js. - Открывает 5000 порт (в дальнейшем он будет перенаправлен через реверс-прокси Traefik, который позволит управлять SSL сертификатами для обеспечения соединения HTTPS).
Если вам интересен наш проект, есть вопросы, замечания, или предложения — оставляйте комментарии или пишите на почту: checkerwars@mail.ru
Кроме того, автор проекта ищет работу. Мое резюме.