Привет! Я рад поделиться тем, как вы можете настроить NestJS для бесперебойной работы на одном хосте. Но сначала позвольте мне объяснить, почему эта установка так долго была моим лучшим выбором для управления как интерфейсом, так и сервером.
Next.js — это мощный инструмент для запуска новых проектов. Он оснащен такими функциями, как встроенная маршрутизация, серверный рендеринг (SSR) и кэширование, которые помогут вам сразу же приступить к работе. Кроме того, Next.js имеет собственные внутренние возможности API, позволяющие управлять такими задачами, как кэширование и подготовка данных, прямо в рамках платформы. Это означает, что вы можете больше сосредоточиться на создании приложения, а не на настройке инфраструктуры.
Но иногда для сервера нужно что-то помощнее. Вот тут-то и вступает в игру Nest.js. Эта платформа настолько мощная, что может выполнять не только функции промежуточного программного обеспечения между вашим серверным и внешним интерфейсом, но также может выступать в качестве надежного серверного решения сама по себе. Поэтому NestJS в данном случае является хорошим дополнением к Next.js, позволяя использовать один язык программирования для внешнего и внутреннего интерфейса.
Проще говоря, это невероятно удобно. Всего лишь git pull и docker-compose up -d, и все готово. Нет необходимости беспокоиться о CORS или перетасовке портов. Кроме того, это упрощает процесс доставки, делая все более плавным и эффективным. В качестве недостатка могу отметить то, что это не подходит для больших проектов с высокой нагрузкой.
Файл: ./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 или перетасовке портов. Кроме того, это упрощает процесс доставки, делая все более плавным и эффективным. В качестве недостатка могу отметить то, что это не подходит для больших проектов с высокой нагрузкой.
В режиме разработки нам не нужен контейнерный сервис для серверной и внешней части, поскольку мы будем запускать их локально.
Файл: ./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"
Файл: ./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"]
На этом этапе мы настраиваем 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.
Поскольку мы используем один и тот же хост, нам необходимо, чтобы 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();
На внешнем интерфейсе настройка не требуется, но учитывается только то, что все запросы к серверу должны вызываться относительно пути /api.
интерфейс компакт-диска
npm run dev
компакт-диск ../бэкенд
запуск запуска npm:dev
компакт-диск ../
docker-compose -f docker-compose.dev.yml up -d
Теперь мы можем проверить наш сайт, открыв localhost в браузере. В примере у нас есть 1 запрос на сервере и еще один на клиенте. Оба эти запроса вызываются из Next.J и обрабатываются Nest.Js.
В этой статье рассказывается, как развернуть проект на сервере с помощью реестра 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. Это упрощает процесс развертывания, позволяя вам сосредоточиться на создании приложения, а не на манипулировании несколькими конфигурациями. Идеально подходит для тех, кто хочет быстро и с минимальными усилиями запустить полнофункциональный проект.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3