«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Разверните NextJ и NestJ как одно приложение.

Разверните NextJ и NestJ как одно приложение.

Опубликовано 8 ноября 2024 г.
Просматривать:178

Привет! Я рад поделиться тем, как вы можете настроить NestJS для бесперебойной работы на одном хосте. Но сначала позвольте мне объяснить, почему эта установка так долго была моим лучшим выбором для управления как интерфейсом, так и сервером.

Next.js — это мощный инструмент для запуска новых проектов. Он оснащен такими функциями, как встроенная маршрутизация, серверный рендеринг (SSR) и кэширование, которые помогут вам сразу же приступить к работе. Кроме того, Next.js имеет собственные внутренние возможности API, позволяющие управлять такими задачами, как кэширование и подготовка данных, прямо в рамках платформы. Это означает, что вы можете больше сосредоточиться на создании приложения, а не на настройке инфраструктуры.

Но иногда для сервера нужно что-то помощнее. Вот тут-то и вступает в игру Nest.js. Эта платформа настолько мощная, что может выполнять не только функции промежуточного программного обеспечения между вашим серверным и внешним интерфейсом, но также может выступать в качестве надежного серверного решения сама по себе. Поэтому NestJS в данном случае является хорошим дополнением к Next.js, позволяя использовать один язык программирования для внешнего и внутреннего интерфейса.

Почему один хост?

Проще говоря, это невероятно удобно. Всего лишь git pull и docker-compose up -d, и все готово. Нет необходимости беспокоиться о CORS или перетасовке портов. Кроме того, это упрощает процесс доставки, делая все более плавным и эффективным. В качестве недостатка могу отметить то, что это не подходит для больших проектов с высокой нагрузкой.

1. Для начала давайте определим структуру папок вашего репозитория.

Deploy NextJs and NestJs as a single application

2. Объявим докер-файл для сервера

Файл: ./docker-compose.yml

services:
    nginx:
        image: nginx:alpine
        ports:
            - "80:80"
        volumes:
            - "./docker/nginx/conf.d:/etc/nginx/conf.d"
        depends_on:
            - frontend
            - backend
        networks:
            - internal-network
            - external-network

    frontend:
        image: ${FRONTEND_IMAGE}
        restart: always
        networks:
            - internal-network

    backend:
        image: ${BACKEND_IMAGE}
        environment:
            NODE_ENV: ${NODE_ENV}
            POSTGRES_HOST: ${POSTGRES_HOST}
            POSTGRES_USER: ${POSTGRES_USER}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
            POSTGRES_DB: ${POSTGRES_DB}
        depends_on:
            - postgres
        restart: always
        networks:
            - internal-network

    postgres:
        image: postgres:12.1-alpine
        container_name: postgres
        volumes:
            - "./docker/postgres:/var/lib/postgresql/data"
        environment:
            POSTGRES_USER: ${POSTGRES_USER}
            POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
            POSTGRES_DB: ${POSTGRES_DB}
        ports:
            - "5432:5432"

networks:
    internal-network:
        driver: bridge

    external-network:
        driver: bridge

Проще говоря, это невероятно удобно. Всего лишь git pull и docker-compose up -d, и все готово. Нет необходимости беспокоиться о CORS или перетасовке портов. Кроме того, это упрощает процесс доставки, делая все более плавным и эффективным. В качестве недостатка могу отметить то, что это не подходит для больших проектов с высокой нагрузкой.

3. Еще один докер-файл для режима разработки.

В режиме разработки нам не нужен контейнерный сервис для серверной и внешней части, поскольку мы будем запускать их локально.

Файл: ./docker-compose.dev.yml

version: '3'

services:
    nginx:
        image: nginx:alpine
        ports:
            - "80:80"
        volumes:
            - "./docker/nginx/conf.d:/etc/nginx/conf.d"

    postgres:
        image: postgres:12.1-alpine
        container_name: postgres
        volumes:
            - "./docker/postgres:/var/lib/postgresql/data"
        environment:
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: postgres
            POSTGRES_DB: postgres
        ports:
            - "5432:5432"

4. Docker-файл для бэкенда

Файл: ./backend/Dockerfile

FROM node:18-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json ./
RUN  npm install

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1

RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

RUN mkdir -p /app/backups && chown -R nextjs:nodejs /app/backups && chmod -R 777 /app/backups

USER nextjs

EXPOSE 3010

ENV PORT 3010

CMD ["node", "dist/src/main"]

## 5. Docker file for frontend
File: ./frontend/Dockerfile

FROM node:18-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json ./
RUN  npm install

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1

RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["npm", "start"]

6. Конфигурация Ngnix

На этом этапе мы настраиваем Nginx в качестве обратного прокси-сервера для нашего внешнего интерфейса Next.js и внутреннего интерфейса Nest.js. Конфигурация Nginx позволяет беспрепятственно маршрутизировать запросы между интерфейсом и сервером, обслуживая их с одного и того же хоста.

Файл: /docker/nginx/conf.d/default.conf

server {
    listen 80;

    location / {
        proxy_pass http://host.docker.internal:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /api {
        proxy_pass http://host.docker.internal:3010;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Эта конфигурация прослушивает порт 80 и направляет общий трафик во внешний интерфейс Next.js через порт 3000, а любые запросы к /api перенаправляются во внутренний интерфейс Nest.js через порт 3010.

7. Глобальный префикс NestJs

Поскольку мы используем один и тот же хост, нам необходимо, чтобы NestJ были доступны в /apipath. Для этого нам нужно установитьGlobalPrefix — API.

Файл: ./backend/src/main.js

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { cors: true  });
  app.setGlobalPrefix('api');
  await app.listen(3010);
}
bootstrap();

8. Фронтенд

На внешнем интерфейсе настройка не требуется, но учитывается только то, что все запросы к серверу должны вызываться относительно пути /api.

9. Запускайте локально

интерфейс компакт-диска
npm run dev
компакт-диск ../бэкенд
запуск запуска npm:dev
компакт-диск ../
docker-compose -f docker-compose.dev.yml up -d

Теперь мы можем проверить наш сайт, открыв localhost в браузере. В примере у нас есть 1 запрос на сервере и еще один на клиенте. Оба эти запроса вызываются из Next.J и обрабатываются Nest.Js.

Deploy NextJs and NestJs as a single application

10. Разверните и запустите на сервере через GitHub.

В этой статье рассказывается, как развернуть проект на сервере с помощью реестра Docker и действий GitHub. Процесс начинается с создания образов Docker как для серверной, так и для внешней части в реестре Docker. После этого вам нужно будет настроить репозиторий GitHub и настроить необходимые секреты для беспрепятственного развертывания:

DOCKERHUB_USERNAME
DOCKERHUB_TOKEN
DOCKER_FRONTEND_IMAGE
DOCKER_BACKEND_IMAGE
УДАЛЕННЫЙ_СЕРВЕР_ХОСТ
REMOTE_SERVER_USERNAME
REMOTE_SERVER_SSH_KEY
REMOTE_SERVER_SSH_PORT

Обратной стороной использования одного репозитория для серверной и внешней части является то, что каждый раз, когда вы что-то отправляете, оба образа перестраиваются. Чтобы оптимизировать его, мы можем использовать следующие условия:

if: contains(github.event_name, ‘push’) && !startsWith(github.event.head_commit.message, ‘frontend’)
if: contains(github.event_name, ‘push’) && !startsWith(github.event.head_commit.message, ‘backend’)

Это позволяет перестроить только тот образ, который вы учитываете, указав сообщение фиксации.

Файл: ./github/workflows/deploy.yml

name: deploy nextjs and nestjs to GITHUB

on:
  push:
    branches: [ "main" ]

jobs:
  build-and-push-frontend:
    runs-on: ubuntu-latest

    if: contains(github.event_name, 'push') && !startsWith(github.event.head_commit.message, 'backend')

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push frontend to Docker Hub
        uses: docker/build-push-action@v2
        with:
          context: frontend
          file: frontend/Dockerfile
          push: true
          tags: ${{ secrets.DOCKER_FRONTEND_IMAGE }}:latest

      - name: SSH into the remote server and deploy frontend
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_SERVER_HOST }}
          username: ${{ secrets.REMOTE_SERVER_USERNAME }}
          password: ${{ secrets.REMOTE_SERVER_SSH_KEY }}
          port: ${{ secrets.REMOTE_SERVER_SSH_PORT }}
          script: |
            cd website/
            docker rmi -f ${{ secrets.DOCKER_FRONTEND_IMAGE }}:latest
            docker-compose down
            docker-compose up -d

  build-and-push-backend:
    runs-on: ubuntu-latest

    if: contains(github.event_name, 'push') && !startsWith(github.event.head_commit.message, 'frontend')

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push backend to Docker Hub
        uses: docker/build-push-action@v2
        with:
          context: backend
          file: backend/Dockerfile
          push: true
          tags: ${{ secrets.DOCKER_BACKEND_IMAGE }}:latest

      - name: SSH into the remote server and deploy backend
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_SERVER_HOST }}
          username: ${{ secrets.REMOTE_SERVER_USERNAME }}
          password: ${{ secrets.REMOTE_SERVER_SSH_KEY }}
          port: ${{ secrets.REMOTE_SERVER_SSH_PORT }}
          script: |
            cd website/
            docker rmi -f ${{ secrets.DOCKER_BACKEND_IMAGE }}:latest
            docker-compose down
            docker-compose up -d=

Репозиторий: https://github.com/xvandevx/blog-examples/tree/main/nextjs-nestjs-deploy

Резюме

Эта статья представляет собой практическое руководство по совместному развертыванию Next.js и Nest.js на одном сервере, что делает ее идеальным решением для разработчиков, которым нужна упрощенная настройка. Объединив сильные стороны Next.js для внешнего интерфейса и Nest.js для серверной части, я показал, как эффективно управлять обеими частями вашего приложения с помощью Docker и GitHub Actions. Это упрощает процесс развертывания, позволяя вам сосредоточиться на создании приложения, а не на манипулировании несколькими конфигурациями. Идеально подходит для тех, кто хочет быстро и с минимальными усилиями запустить полнофункциональный проект.

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/xvandev/deploy-nextjs-and-nestjs-as-a-single-application-15mj?1 Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить это
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3