嘿那裡!我很高興與您分享如何配置 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,並將一般流量路由至連接埠 3000 上的 Next.js 前端,而對 /api 的任何請求都會轉送至連接埠 3010 上的 Nest.js 後端。
由於我們使用相同的主機,我們需要 NestJs 在 /apipath 上可用。為此,我們需要 setGlobalPrefix — 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 路徑呼叫。
cd 前端
npm run dev
cd ../後端
npm run start:dev
cd ../
docker-compose -f docker-compose.dev.yml up -d
現在,我們可以透過在瀏覽器中開啟 localhost 來檢查我們的網站。在範例中,我們在伺服器上有 1 個請求,在客戶端上有另一個請求。這兩個請求都是從 Next.Js 呼叫並由 Nest.Js 處理。
本文探討如何使用 Docker 註冊表和 GitHub Actions 將專案部署到伺服器。這個過程首先在 Docker 註冊表中為後端和前端建立 Docker 映像。之後,您需要設定 GitHub 儲存庫並配置無縫部署所需的機密:
DOCKERHUB_USERNAME
DOCKERHUB_TOKEN
DOCKER_FRONTEND_IMAGE
DOCKER_BACKEND_IMAGE
REMOTE_SERVER_HOST
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’)
它可以透過指定提交訊息來僅重建您關注的圖像。
File: ./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=
Repository: https://github.com/xvandevx/blog-examples/tree/main/nextjs-nestjs-deploy
This article is a hands-on guide to deploying Next.js and Nest.js together on a single server, making it a go-to solution for developers who want a streamlined setup. By combining the strengths of Next.js for frontend and Nest.js for backend, I showed how to efficiently manage both parts of your application using Docker and GitHub Actions. It simplifies the deployment process, allowing you to focus on building your app rather than juggling multiple configurations. Perfect for those looking to get a full-stack project up and running quickly with minimal hassle.
以上是將 NextJs 和 NestJs 部署為單一應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!