Nest+pm2+Docker+Nginx+PostgreSQL+Prisma+Redis配置

45 阅读2分钟

废话不多数....直接上代码

Dockerfile

# Step 1: Use a Node.js base image
FROM node:18-bullseye

# Step 2: Set the working directory inside the container
WORKDIR /app

# Step 3: Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Step 4: Set registry
RUN npm set registry=https://registry.npmmirror.com

# Step 5: Install pm2 global
RUN npm install pm2 -g

# Step 6: Install project dependencies
RUN npm install --only=production

# generated prisma files
COPY /src/database/prisma ./prisma/

# COPY ENV variable
COPY .env ./

# COPY tsconfig.json file
COPY tsconfig.json ./

# Step 7: Copy the rest of the application code to the working directory
COPY . .

# generate prisma
RUN npx prisma generate

# Step 8: Build the NestJS application
RUN npm run build 

# Step 9: Expose the port the app will run on
EXPOSE 3000

# Step 10: Define the command to run the app
CMD ["pm2-runtime", "start", "ecosystem.config.js"]

docker-compose.yaml

version: "3.9"

services:
  # PostgreSQL 数据库
  postgres:
    image: postgres:latest
    container_name: postgres
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
      POSTGRES_DB: cosette_database
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - cosette-net

  # Redis 缓存
  redis:
    image: redis:latest
    container_name: redis
    ports:
      - "6379:6379"
    restart: always
    volumes:
      - redis_data:/data
    networks:
      - cosette-net

  # NestJS 应用
  server:
    build:
      context: ./
      dockerfile: ./Dockerfile
    container_name: server
    image: server:latest
    restart: always
    ports:
      - "3000:3000"
    networks:
      - cosette-net
    depends_on:
      - postgres
      - redis
    env_file:
      - ./.env

  # Nginx 反向代理
  nginx:
    image: nginx:stable-alpine
    container_name: proxy
    ports:
      - "5000:5000"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    privileged: true
    depends_on:
      - server
    networks:
      - cosette-net

networks:
  cosette-net:
    driver: bridge

volumes:
  postgres_data:
    driver: local
  redis_data:
    driver: local

ecosystem.config.js

module.exports = {
    apps: [
      {
        name: 'cosette-server',
        script: './dist/main.js',
        instances: 2, // 负载均衡实例数
        autorestart: true, // 自动重启
        watch: false, // 监听文件变化
        max_memory_restart: '1G', // 内存超过1G时重启
        env: {
          NODE_ENV: 'production'
        }
      }
    ]
  };

nginx/Dockerfile

FROM nginx:alpine

# Remove any existing config files
RUN rm /etc/nginx/conf.d/*

# Copy config files
# *.conf files in "conf.d/" dir get included in main config
COPY ./nginx/default.conf /etc/nginx/conf.d/

# Expose the listening port
EXPOSE 5000

# Launch NGINX
CMD [ "nginx", "-g", "daemon off;" ]

nginx/default.conf

server {
    listen 5000;
    server_name localhost;

    # Perform reverse proxy when accessing the / path
    location / {
      proxy_pass http://server:3000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      # The backend web server can obtain the user's real IP through X-Forwarded-For
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      # Maximum bytes of the client request body buffered by the proxy
      client_body_buffer_size 128k;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root /usr/share/nginx/html;
    }
}