feat(docker): 添加 2.0 系统 Docker 部署支持
为所有 2.0 服务添加 Dockerfile 和 docker-compose 配置: 后端服务: - contribution-service (3020) - 算力服务 - mining-service (3021) - 挖矿服务 - trading-service (3022) - 交易服务 - mining-admin-service (3023) - 管理后台 API - auth-service (3024) - 用户认证服务 前端服务: - mining-admin-web (3100) - 管理后台前端 Docker 配置: - docker-compose.2.0.yml: 独立的 2.0 系统编排文件 - 多阶段构建优化镜像大小 - 健康检查确保服务可用性 - 服务依赖顺序正确 部署脚本更新: - deploy-mining.sh 使用 docker-compose.2.0.yml - 添加 mining-admin-web 服务别名 (web, admin-web) - 更新服务端口配置 使用方式: cd backend/services docker-compose -f docker-compose.2.0.yml up -d Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
f7278b6196
commit
821c70bf38
|
|
@ -0,0 +1,48 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Auth Service - Dockerfile
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段2: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nestjs
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
RUN chown -R nestjs:nodejs /app
|
||||||
|
USER nestjs
|
||||||
|
|
||||||
|
EXPOSE 3024
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3024/api/v2/health || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Contribution Service - Dockerfile
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段2: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nestjs
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
RUN chown -R nestjs:nodejs /app
|
||||||
|
USER nestjs
|
||||||
|
|
||||||
|
EXPOSE 3020
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3020/health || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
# trading -> trading-service
|
# trading -> trading-service
|
||||||
# admin -> mining-admin-service
|
# admin -> mining-admin-service
|
||||||
# auth -> auth-service
|
# auth -> auth-service
|
||||||
|
# web, admin-web -> mining-admin-web (frontend)
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
@ -48,7 +49,7 @@ set -e
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ENV_FILE="$SCRIPT_DIR/.env"
|
ENV_FILE="$SCRIPT_DIR/.env"
|
||||||
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml"
|
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.2.0.yml"
|
||||||
|
|
||||||
# 2.0 Services
|
# 2.0 Services
|
||||||
MINING_SERVICES=(
|
MINING_SERVICES=(
|
||||||
|
|
@ -57,6 +58,7 @@ MINING_SERVICES=(
|
||||||
"trading-service"
|
"trading-service"
|
||||||
"mining-admin-service"
|
"mining-admin-service"
|
||||||
"auth-service"
|
"auth-service"
|
||||||
|
"mining-admin-web"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Service Aliases
|
# Service Aliases
|
||||||
|
|
@ -67,6 +69,8 @@ declare -A SERVICE_ALIASES=(
|
||||||
["trading"]="trading-service"
|
["trading"]="trading-service"
|
||||||
["admin"]="mining-admin-service"
|
["admin"]="mining-admin-service"
|
||||||
["auth"]="auth-service"
|
["auth"]="auth-service"
|
||||||
|
["web"]="mining-admin-web"
|
||||||
|
["admin-web"]="mining-admin-web"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2.0 Databases
|
# 2.0 Databases
|
||||||
|
|
@ -94,6 +98,7 @@ declare -A SERVICE_PORTS=(
|
||||||
["trading-service"]="3022"
|
["trading-service"]="3022"
|
||||||
["mining-admin-service"]="3023"
|
["mining-admin-service"]="3023"
|
||||||
["auth-service"]="3024"
|
["auth-service"]="3024"
|
||||||
|
["mining-admin-web"]="3100"
|
||||||
)
|
)
|
||||||
|
|
||||||
# CDC Consumer Group
|
# CDC Consumer Group
|
||||||
|
|
@ -871,6 +876,7 @@ show_help() {
|
||||||
echo " trading -> trading-service"
|
echo " trading -> trading-service"
|
||||||
echo " admin -> mining-admin-service"
|
echo " admin -> mining-admin-service"
|
||||||
echo " auth -> auth-service"
|
echo " auth -> auth-service"
|
||||||
|
echo " web, admin-web -> mining-admin-web"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BOLD}Examples:${NC}"
|
echo -e "${BOLD}Examples:${NC}"
|
||||||
echo " $0 up # Start all services"
|
echo " $0 up # Start all services"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
# =============================================================================
|
||||||
|
# RWA Mining Ecosystem 2.0 - Docker Compose
|
||||||
|
# =============================================================================
|
||||||
|
#
|
||||||
|
# 2.0 系统完全独立于 1.0,可随时重置
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# docker-compose -f docker-compose.2.0.yml up -d # 启动所有 2.0 服务
|
||||||
|
# docker-compose -f docker-compose.2.0.yml down # 停止所有 2.0 服务
|
||||||
|
# docker-compose -f docker-compose.2.0.yml up -d mining-admin # 启动单个服务
|
||||||
|
# docker-compose -f docker-compose.2.0.yml logs -f # 查看日志
|
||||||
|
#
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ===========================================================================
|
||||||
|
# Backend Services (2.0)
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
contribution-service:
|
||||||
|
build:
|
||||||
|
context: ./contribution-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-contribution-service
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3020
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@${POSTGRES_HOST:-host.docker.internal}:${POSTGRES_PORT:-5432}/rwa_contribution?schema=public
|
||||||
|
REDIS_HOST: ${REDIS_HOST:-host.docker.internal}
|
||||||
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||||
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-host.docker.internal:9092}
|
||||||
|
CDC_TOPIC_ADOPTIONS: ${CDC_TOPIC_ADOPTIONS:-dbserver1.public.adoptions}
|
||||||
|
CDC_TOPIC_PAYMENTS: ${CDC_TOPIC_PAYMENTS:-dbserver1.public.payment_records}
|
||||||
|
CDC_CONSUMER_GROUP: contribution-service-cdc-group
|
||||||
|
ports:
|
||||||
|
- "3020:3020"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3020/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
mining-service:
|
||||||
|
build:
|
||||||
|
context: ./mining-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-mining-service
|
||||||
|
depends_on:
|
||||||
|
contribution-service:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3021
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@${POSTGRES_HOST:-host.docker.internal}:${POSTGRES_PORT:-5432}/rwa_mining?schema=public
|
||||||
|
REDIS_HOST: ${REDIS_HOST:-host.docker.internal}
|
||||||
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||||
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-host.docker.internal:9092}
|
||||||
|
ports:
|
||||||
|
- "3021:3021"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3021/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
trading-service:
|
||||||
|
build:
|
||||||
|
context: ./trading-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-trading-service
|
||||||
|
depends_on:
|
||||||
|
mining-service:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3022
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@${POSTGRES_HOST:-host.docker.internal}:${POSTGRES_PORT:-5432}/rwa_trading?schema=public
|
||||||
|
REDIS_HOST: ${REDIS_HOST:-host.docker.internal}
|
||||||
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||||
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-host.docker.internal:9092}
|
||||||
|
MINING_SERVICE_URL: http://mining-service:3021
|
||||||
|
ports:
|
||||||
|
- "3022:3022"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3022/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
mining-admin-service:
|
||||||
|
build:
|
||||||
|
context: ./mining-admin-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-mining-admin-service
|
||||||
|
depends_on:
|
||||||
|
contribution-service:
|
||||||
|
condition: service_healthy
|
||||||
|
mining-service:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3023
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@${POSTGRES_HOST:-host.docker.internal}:${POSTGRES_PORT:-5432}/rwa_mining_admin?schema=public
|
||||||
|
REDIS_HOST: ${REDIS_HOST:-host.docker.internal}
|
||||||
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||||
|
CONTRIBUTION_SERVICE_URL: http://contribution-service:3020
|
||||||
|
MINING_SERVICE_URL: http://mining-service:3021
|
||||||
|
TRADING_SERVICE_URL: http://trading-service:3022
|
||||||
|
JWT_SECRET: ${ADMIN_JWT_SECRET:-your-admin-jwt-secret-change-in-production}
|
||||||
|
ports:
|
||||||
|
- "3023:3023"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3023/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
auth-service:
|
||||||
|
build:
|
||||||
|
context: ./auth-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-auth-service
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3024
|
||||||
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@${POSTGRES_HOST:-host.docker.internal}:${POSTGRES_PORT:-5432}/rwa_auth?schema=public
|
||||||
|
REDIS_HOST: ${REDIS_HOST:-host.docker.internal}
|
||||||
|
REDIS_PORT: ${REDIS_PORT:-6379}
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||||
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-host.docker.internal:9092}
|
||||||
|
CDC_TOPIC_USERS: ${CDC_TOPIC_USERS:-dbserver1.public.users}
|
||||||
|
CDC_CONSUMER_GROUP: auth-service-cdc-group
|
||||||
|
JWT_SECRET: ${JWT_SECRET:-your-jwt-secret-change-in-production}
|
||||||
|
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
|
||||||
|
JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-30d}
|
||||||
|
SMS_ACCESS_KEY_ID: ${SMS_ACCESS_KEY_ID:-}
|
||||||
|
SMS_ACCESS_KEY_SECRET: ${SMS_ACCESS_KEY_SECRET:-}
|
||||||
|
SMS_SIGN_NAME: ${SMS_SIGN_NAME:-榴莲生态}
|
||||||
|
SMS_TEMPLATE_CODE: ${SMS_TEMPLATE_CODE:-}
|
||||||
|
ports:
|
||||||
|
- "3024:3024"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3024/api/v2/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Frontend Services (2.0)
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
mining-admin-web:
|
||||||
|
build:
|
||||||
|
context: ../../frontend/mining-admin-web
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: rwa-mining-admin-web
|
||||||
|
depends_on:
|
||||||
|
mining-admin-service:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
PORT: 3100
|
||||||
|
NEXT_PUBLIC_API_URL: http://mining-admin-service:3023
|
||||||
|
NEXT_PUBLIC_APP_NAME: 挖矿管理后台
|
||||||
|
ports:
|
||||||
|
- "3100:3100"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3100/"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- rwa-2.0-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
rwa-2.0-network:
|
||||||
|
driver: bridge
|
||||||
|
name: rwa-2.0-network
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Mining Admin Service - Dockerfile
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 安装必要的构建工具
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
# 复制依赖文件
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# 安装所有依赖(包括 devDependencies)
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# 复制 Prisma schema
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
|
||||||
|
# 生成 Prisma Client
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 构建应用
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段2: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
# 安装必要的运行时依赖
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
# 创建非 root 用户
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nestjs
|
||||||
|
|
||||||
|
# 复制依赖文件并安装生产依赖
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
# 复制 Prisma schema 并生成 client
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
# 复制构建产物
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
# 设置权限
|
||||||
|
RUN chown -R nestjs:nodejs /app
|
||||||
|
USER nestjs
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 3023
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3023/health || exit 1
|
||||||
|
|
||||||
|
# 启动应用
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Mining Service - Dockerfile
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段2: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nestjs
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
RUN chown -R nestjs:nodejs /app
|
||||||
|
USER nestjs
|
||||||
|
|
||||||
|
EXPOSE 3021
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3021/health || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Trading Service - Dockerfile
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段2: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nestjs
|
||||||
|
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY prisma ./prisma/
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
RUN chown -R nestjs:nodejs /app
|
||||||
|
USER nestjs
|
||||||
|
|
||||||
|
EXPOSE 3022
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3022/health || exit 1
|
||||||
|
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
# =============================================================================
|
||||||
|
# Mining Admin Web - Dockerfile (Next.js)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 阶段1: 依赖安装
|
||||||
|
FROM node:20-alpine AS deps
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制依赖文件
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# 阶段2: 构建
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制依赖
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 设置环境变量
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# 构建应用
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 阶段3: 生产运行
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
# 安装 curl 用于健康检查
|
||||||
|
RUN apk add --no-cache curl tzdata
|
||||||
|
|
||||||
|
# 创建非 root 用户
|
||||||
|
RUN addgroup --system --gid 1001 nodejs && \
|
||||||
|
adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
# 复制构建产物
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
# 设置用户
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 3100
|
||||||
|
|
||||||
|
ENV PORT=3100
|
||||||
|
ENV HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3100/ || exit 1
|
||||||
|
|
||||||
|
# 启动应用
|
||||||
|
CMD ["node", "server.js"]
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
|
output: 'standalone',
|
||||||
async rewrites() {
|
async rewrites() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue