feat(services): add unified Docker deployment system
- Add docker-compose.yml for all 11 backend services - Add deploy.sh automation script with install/build/up/down commands - Add init-databases.sh for PostgreSQL multi-database initialization - Add .env.example template with secure key placeholders - Fix empty Dockerfiles for admin/referral/reporting/wallet services Services included: - identity-service (:3000) - wallet-service (:3001) - backup-service (:3002) - planting-service (:3003) - referral-service (:3004) - reward-service (:3005) - mpc-service (:3006) - leaderboard-service (:3007) - reporting-service (:3008) - authorization-service (:3009) - admin-service (:3010) Infrastructure: PostgreSQL, Redis, Kafka/Zookeeper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7d257cd35f
commit
f99cac21cf
|
|
@ -0,0 +1,32 @@
|
|||
# =============================================================================
|
||||
# RWA Backend Services - Environment Configuration Template
|
||||
# =============================================================================
|
||||
# Copy this file to .env and fill in the values
|
||||
# WARNING: Never commit .env to version control!
|
||||
# =============================================================================
|
||||
|
||||
# PostgreSQL Database
|
||||
POSTGRES_USER=rwa_user
|
||||
POSTGRES_PASSWORD=your_secure_password_here
|
||||
|
||||
# Redis (leave empty for no password)
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# JWT Configuration (generate with: openssl rand -base64 32)
|
||||
JWT_SECRET=your_jwt_secret_here
|
||||
|
||||
# Service-to-Service Authentication
|
||||
SERVICE_JWT_SECRET=your_service_jwt_secret_here
|
||||
|
||||
# Wallet Encryption Salt
|
||||
WALLET_ENCRYPTION_SALT=your_wallet_salt_here
|
||||
|
||||
# Backup Encryption Key (256-bit hex: openssl rand -hex 32)
|
||||
BACKUP_ENCRYPTION_KEY=your_64_char_hex_key_here
|
||||
|
||||
# MPC Share Master Key (256-bit hex: openssl rand -hex 32)
|
||||
SHARE_MASTER_KEY=your_64_char_hex_key_here
|
||||
|
||||
# MPC System Address (running on 192.168.1.100)
|
||||
MPC_COORDINATOR_URL=http://192.168.1.100:8081
|
||||
MPC_MESSAGE_ROUTER_URL=ws://192.168.1.100:8082
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Environment files (contain secrets)
|
||||
.env
|
||||
.env.local
|
||||
.env.production.local
|
||||
|
||||
# Docker volumes (if local)
|
||||
postgres_data/
|
||||
redis_data/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
# RWA Backend Services
|
||||
|
||||
统一部署管理 RWA 后端微服务。
|
||||
|
||||
## 架构概览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 192.168.1.100 (Gateway) │
|
||||
│ ┌─────────────┐ ┌─────────────────────────────────────────┐ │
|
||||
│ │ Nginx │ │ MPC-System (Go) │ │
|
||||
│ │ (Reverse │ │ - session-coordinator (:8081) │ │
|
||||
│ │ Proxy) │ │ - message-router (:8082) │ │
|
||||
│ │ │ │ - server-party-1/2/3 (:8083-8085) │ │
|
||||
│ └─────────────┘ │ - account-service (:8080) │ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ Internal Network
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 192.168.1.111 (Backend) │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Docker Compose Services │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ PostgreSQL │ │ Redis │ │ Kafka │ │ │
|
||||
│ │ │ (:5432) │ │ (:6379) │ │ (:9092) │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ identity │ │ wallet │ │ backup │ │ │
|
||||
│ │ │ (:3000) │ │ (:3001) │ │ (:3002) │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ planting │ │ referral │ │ reward │ │ │
|
||||
│ │ │ (:3003) │ │ (:3004) │ │ (:3005) │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ mpc │ │ leaderboard │ │ reporting │ │ │
|
||||
│ │ │ (:3006) │ │ (:3007) │ │ (:3008) │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │authorization│ │ admin │ │ │
|
||||
│ │ │ (:3009) │ │ (:3010) │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 首次安装
|
||||
|
||||
```bash
|
||||
# 进入服务目录
|
||||
cd ~/rwadurian/backend/services
|
||||
|
||||
# 运行安装(自动生成安全密钥)
|
||||
./deploy.sh install
|
||||
```
|
||||
|
||||
### 2. 构建镜像
|
||||
|
||||
```bash
|
||||
./deploy.sh build
|
||||
```
|
||||
|
||||
### 3. 启动服务
|
||||
|
||||
```bash
|
||||
./deploy.sh up
|
||||
```
|
||||
|
||||
### 4. 检查状态
|
||||
|
||||
```bash
|
||||
./deploy.sh status
|
||||
./deploy.sh health
|
||||
```
|
||||
|
||||
## 常用命令
|
||||
|
||||
| 命令 | 说明 |
|
||||
|------|------|
|
||||
| `./deploy.sh install` | 首次安装,生成配置 |
|
||||
| `./deploy.sh build` | 构建所有 Docker 镜像 |
|
||||
| `./deploy.sh up` | 启动所有服务 |
|
||||
| `./deploy.sh down` | 停止所有服务 |
|
||||
| `./deploy.sh restart` | 重启所有服务 |
|
||||
| `./deploy.sh status` | 查看服务状态 |
|
||||
| `./deploy.sh health` | 检查服务健康 |
|
||||
| `./deploy.sh logs` | 查看所有日志 |
|
||||
| `./deploy.sh logs <service>` | 查看指定服务日志 |
|
||||
| `./deploy.sh migrate` | 运行数据库迁移 |
|
||||
| `./deploy.sh rebuild-svc <name>` | 重建指定服务 |
|
||||
|
||||
## 服务列表
|
||||
|
||||
| 服务 | 端口 | 说明 |
|
||||
|------|------|------|
|
||||
| identity-service | 3000 | 身份认证服务 |
|
||||
| wallet-service | 3001 | 钱包账本服务 |
|
||||
| backup-service | 3002 | MPC 备份服务 |
|
||||
| planting-service | 3003 | 认种服务 |
|
||||
| referral-service | 3004 | 推荐系统服务 |
|
||||
| reward-service | 3005 | 奖励服务 |
|
||||
| mpc-service | 3006 | MPC 中间层服务 |
|
||||
| leaderboard-service | 3007 | 排行榜服务 |
|
||||
| reporting-service | 3008 | 报表服务 |
|
||||
| authorization-service | 3009 | 授权服务 |
|
||||
| admin-service | 3010 | 管理后台服务 |
|
||||
|
||||
## 基础设施
|
||||
|
||||
| 服务 | 端口 | 说明 |
|
||||
|------|------|------|
|
||||
| PostgreSQL | 5432 | 主数据库 |
|
||||
| Redis | 6379 | 缓存/会话 |
|
||||
| Kafka | 9092 | 消息队列 |
|
||||
| Zookeeper | 2181 | Kafka 协调 |
|
||||
|
||||
## 环境配置
|
||||
|
||||
配置文件 `.env` 由 `./deploy.sh install` 自动生成,包含:
|
||||
|
||||
- 数据库密码
|
||||
- JWT 密钥
|
||||
- 加密密钥
|
||||
- MPC 系统地址
|
||||
|
||||
**重要**: `.env` 文件包含敏感信息,请勿提交到 Git!
|
||||
|
||||
## 与 MPC-System 集成
|
||||
|
||||
mpc-service 需要连接到运行在 192.168.1.100 上的 MPC-System:
|
||||
|
||||
- Session Coordinator: `http://192.168.1.100:8081`
|
||||
- Message Router: `ws://192.168.1.100:8082`
|
||||
|
||||
确保 192.168.1.111 能够访问 192.168.1.100 的这些端口。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 查看服务日志
|
||||
|
||||
```bash
|
||||
./deploy.sh logs identity-service
|
||||
```
|
||||
|
||||
### 重建单个服务
|
||||
|
||||
```bash
|
||||
./deploy.sh rebuild-svc mpc-service
|
||||
```
|
||||
|
||||
### 数据库连接问题
|
||||
|
||||
```bash
|
||||
# 进入 postgres 容器
|
||||
docker exec -it rwa-postgres psql -U rwa_user -d rwa_identity
|
||||
```
|
||||
|
||||
### 清理重新开始
|
||||
|
||||
```bash
|
||||
./deploy.sh clean # 删除所有容器和数据
|
||||
./deploy.sh install
|
||||
./deploy.sh build
|
||||
./deploy.sh up
|
||||
```
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# =============================================================================
|
||||
# Admin Service Dockerfile
|
||||
# =============================================================================
|
||||
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tsconfig*.json ./
|
||||
COPY nest-cli.json ./
|
||||
|
||||
# Copy Prisma schema if exists
|
||||
COPY prisma ./prisma/ 2>/dev/null || true
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Generate Prisma client if schema exists
|
||||
RUN if [ -f "prisma/schema.prisma" ]; then npx prisma generate; fi
|
||||
|
||||
# Copy source code
|
||||
COPY src ./src
|
||||
|
||||
# Build TypeScript
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install production dependencies only
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy Prisma schema and generate client if exists
|
||||
COPY prisma ./prisma/ 2>/dev/null || true
|
||||
RUN if [ -f "prisma/schema.prisma" ]; then npx prisma generate; fi
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nestjs -u 1001
|
||||
|
||||
# Switch to non-root user
|
||||
USER nestjs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3010
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:3010/health || exit 1
|
||||
|
||||
# Start service
|
||||
CMD ["node", "dist/main.js"]
|
||||
|
|
@ -0,0 +1,470 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# RWA Backend Services - Deployment Script
|
||||
# =========================================
|
||||
#
|
||||
# Usage:
|
||||
# ./deploy.sh install # First time setup (generate secrets, init databases)
|
||||
# ./deploy.sh up # Start all services
|
||||
# ./deploy.sh down # Stop all services
|
||||
# ./deploy.sh restart # Restart all services
|
||||
# ./deploy.sh status # Show service status
|
||||
# ./deploy.sh logs [svc] # View logs (optional: specific service)
|
||||
# ./deploy.sh build # Rebuild all images
|
||||
# ./deploy.sh migrate # Run database migrations
|
||||
# ./deploy.sh health # Check health of all services
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# ===========================================================================
|
||||
# Configuration
|
||||
# ===========================================================================
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENV_FILE="$SCRIPT_DIR/.env"
|
||||
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
|
||||
|
||||
# ===========================================================================
|
||||
# Helper Functions
|
||||
# ===========================================================================
|
||||
|
||||
generate_random_password() {
|
||||
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32
|
||||
}
|
||||
|
||||
generate_hex_key() {
|
||||
openssl rand -hex 32
|
||||
}
|
||||
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed. Please install Docker first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker compose version &> /dev/null; then
|
||||
log_error "Docker Compose is not installed. Please install Docker Compose first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Docker version: $(docker --version)"
|
||||
log_info "Docker Compose version: $(docker compose version --short)"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Install / Initialize
|
||||
# ===========================================================================
|
||||
|
||||
install() {
|
||||
log_step "Installing RWA Backend Services..."
|
||||
|
||||
check_docker
|
||||
|
||||
# Generate .env file if not exists
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
log_step "Generating secure configuration..."
|
||||
|
||||
POSTGRES_PASSWORD=$(generate_random_password)
|
||||
JWT_SECRET=$(generate_random_password)
|
||||
SERVICE_JWT_SECRET=$(generate_random_password)
|
||||
WALLET_ENCRYPTION_SALT=$(generate_random_password)
|
||||
BACKUP_ENCRYPTION_KEY=$(generate_hex_key)
|
||||
SHARE_MASTER_KEY=$(generate_hex_key)
|
||||
|
||||
cat > "$ENV_FILE" << EOF
|
||||
# =============================================================================
|
||||
# RWA Backend Services - Production Environment Configuration
|
||||
# =============================================================================
|
||||
# Generated: $(date)
|
||||
# WARNING: Keep this file secure! Do not commit to version control!
|
||||
# =============================================================================
|
||||
|
||||
# PostgreSQL Database
|
||||
POSTGRES_USER=rwa_user
|
||||
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
|
||||
# Redis (leave empty for no password)
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# JWT Configuration
|
||||
JWT_SECRET=${JWT_SECRET}
|
||||
|
||||
# Service-to-Service Authentication
|
||||
SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET}
|
||||
|
||||
# Wallet Encryption
|
||||
WALLET_ENCRYPTION_SALT=${WALLET_ENCRYPTION_SALT}
|
||||
|
||||
# Backup Encryption (256-bit hex key)
|
||||
BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY}
|
||||
|
||||
# MPC Share Master Key (256-bit hex key)
|
||||
SHARE_MASTER_KEY=${SHARE_MASTER_KEY}
|
||||
|
||||
# MPC System Address (on 192.168.1.100)
|
||||
MPC_COORDINATOR_URL=http://192.168.1.100:8081
|
||||
MPC_MESSAGE_ROUTER_URL=ws://192.168.1.100:8082
|
||||
EOF
|
||||
|
||||
chmod 600 "$ENV_FILE"
|
||||
log_info "Environment file created: $ENV_FILE"
|
||||
log_info "Secrets have been auto-generated"
|
||||
else
|
||||
log_info "Environment file already exists: $ENV_FILE"
|
||||
fi
|
||||
|
||||
# Create scripts directory
|
||||
mkdir -p "$SCRIPT_DIR/scripts"
|
||||
|
||||
# Create database init script
|
||||
create_db_init_script
|
||||
|
||||
log_info "Installation complete!"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info " 1. Review and edit .env if needed"
|
||||
log_info " 2. Run: ./deploy.sh build"
|
||||
log_info " 3. Run: ./deploy.sh up"
|
||||
}
|
||||
|
||||
create_db_init_script() {
|
||||
cat > "$SCRIPT_DIR/scripts/init-databases.sh" << 'DBSCRIPT'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Function to create database if not exists
|
||||
create_database() {
|
||||
local database=$1
|
||||
echo "Creating database: $database"
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||
SELECT 'CREATE DATABASE $database'
|
||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$database')\gexec
|
||||
EOSQL
|
||||
}
|
||||
|
||||
# Create all required databases
|
||||
for db in rwa_identity rwa_wallet rwa_mpc rwa_backup rwa_planting rwa_referral rwa_reward rwa_leaderboard rwa_reporting rwa_authorization; do
|
||||
create_database "$db"
|
||||
done
|
||||
|
||||
echo "All databases created successfully!"
|
||||
DBSCRIPT
|
||||
|
||||
chmod +x "$SCRIPT_DIR/scripts/init-databases.sh"
|
||||
log_info "Database init script created"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Docker Compose Operations
|
||||
# ===========================================================================
|
||||
|
||||
up() {
|
||||
log_step "Starting RWA Backend Services..."
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
log_error "Environment file not found. Run './deploy.sh install' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start infrastructure first
|
||||
log_info "Starting infrastructure services..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d postgres redis zookeeper kafka
|
||||
|
||||
# Wait for infrastructure
|
||||
log_info "Waiting for infrastructure to be ready..."
|
||||
sleep 10
|
||||
|
||||
# Start application services
|
||||
log_info "Starting application services..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d
|
||||
|
||||
log_info "All services started!"
|
||||
log_info ""
|
||||
log_info "Check status with: ./deploy.sh status"
|
||||
log_info "View logs with: ./deploy.sh logs"
|
||||
}
|
||||
|
||||
down() {
|
||||
log_step "Stopping RWA Backend Services..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down
|
||||
log_info "All services stopped"
|
||||
}
|
||||
|
||||
restart() {
|
||||
log_step "Restarting RWA Backend Services..."
|
||||
down
|
||||
sleep 3
|
||||
up
|
||||
}
|
||||
|
||||
build() {
|
||||
log_step "Building Docker images..."
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
log_error "Environment file not found. Run './deploy.sh install' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" build --parallel
|
||||
log_info "All images built successfully"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Status and Monitoring
|
||||
# ===========================================================================
|
||||
|
||||
status() {
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "RWA Backend Services Status"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "Service Health Check"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
health
|
||||
}
|
||||
|
||||
health() {
|
||||
local services=(
|
||||
"identity-service:3000"
|
||||
"wallet-service:3001"
|
||||
"backup-service:3002"
|
||||
"planting-service:3003"
|
||||
"referral-service:3004"
|
||||
"reward-service:3005"
|
||||
"mpc-service:3006"
|
||||
"leaderboard-service:3007"
|
||||
"reporting-service:3008"
|
||||
"authorization-service:3009"
|
||||
"admin-service:3010"
|
||||
)
|
||||
|
||||
for svc in "${services[@]}"; do
|
||||
name="${svc%%:*}"
|
||||
port="${svc##*:}"
|
||||
|
||||
if curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port/health" 2>/dev/null | grep -q "200"; then
|
||||
echo -e "${GREEN}[OK]${NC} $name (port $port)"
|
||||
else
|
||||
echo -e "${RED}[FAIL]${NC} $name (port $port)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# Infrastructure health
|
||||
echo "Infrastructure:"
|
||||
|
||||
if docker exec rwa-postgres pg_isready -U rwa_user &>/dev/null; then
|
||||
echo -e " ${GREEN}[OK]${NC} PostgreSQL"
|
||||
else
|
||||
echo -e " ${RED}[FAIL]${NC} PostgreSQL"
|
||||
fi
|
||||
|
||||
if docker exec rwa-redis redis-cli ping &>/dev/null; then
|
||||
echo -e " ${GREEN}[OK]${NC} Redis"
|
||||
else
|
||||
echo -e " ${RED}[FAIL]${NC} Redis"
|
||||
fi
|
||||
|
||||
if docker exec rwa-kafka kafka-topics --bootstrap-server localhost:9092 --list &>/dev/null; then
|
||||
echo -e " ${GREEN}[OK]${NC} Kafka"
|
||||
else
|
||||
echo -e " ${RED}[FAIL]${NC} Kafka"
|
||||
fi
|
||||
}
|
||||
|
||||
logs() {
|
||||
local service="$1"
|
||||
|
||||
if [ -n "$service" ]; then
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f "$service"
|
||||
else
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f
|
||||
fi
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Database Operations
|
||||
# ===========================================================================
|
||||
|
||||
migrate() {
|
||||
log_step "Running database migrations..."
|
||||
|
||||
local services=(
|
||||
"identity-service"
|
||||
"wallet-service"
|
||||
"backup-service"
|
||||
"planting-service"
|
||||
"referral-service"
|
||||
"reward-service"
|
||||
"mpc-service"
|
||||
"leaderboard-service"
|
||||
"reporting-service"
|
||||
"authorization-service"
|
||||
)
|
||||
|
||||
for svc in "${services[@]}"; do
|
||||
log_info "Running migrations for $svc..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec "$svc" npx prisma migrate deploy 2>/dev/null || \
|
||||
log_warn "Migration skipped for $svc (no migrations or service not running)"
|
||||
done
|
||||
|
||||
log_info "Migrations complete"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Cleanup
|
||||
# ===========================================================================
|
||||
|
||||
clean() {
|
||||
log_warn "This will remove all containers, volumes, and images!"
|
||||
read -p "Are you sure? (y/N): " confirm
|
||||
|
||||
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
|
||||
log_step "Cleaning up..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down -v --rmi all
|
||||
log_info "Cleanup complete"
|
||||
else
|
||||
log_info "Cleanup cancelled"
|
||||
fi
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Single Service Operations
|
||||
# ===========================================================================
|
||||
|
||||
start_service() {
|
||||
local service="$1"
|
||||
if [ -z "$service" ]; then
|
||||
log_error "Please specify a service name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Starting $service..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d "$service"
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
local service="$1"
|
||||
if [ -z "$service" ]; then
|
||||
log_error "Please specify a service name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Stopping $service..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" stop "$service"
|
||||
}
|
||||
|
||||
rebuild_service() {
|
||||
local service="$1"
|
||||
if [ -z "$service" ]; then
|
||||
log_error "Please specify a service name"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Rebuilding $service..."
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" build "$service"
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d "$service"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Main
|
||||
# ===========================================================================
|
||||
|
||||
case "${1:-}" in
|
||||
install)
|
||||
install
|
||||
;;
|
||||
up|start)
|
||||
up
|
||||
;;
|
||||
down|stop)
|
||||
down
|
||||
;;
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
build)
|
||||
build
|
||||
;;
|
||||
status|ps)
|
||||
status
|
||||
;;
|
||||
health)
|
||||
health
|
||||
;;
|
||||
logs)
|
||||
logs "$2"
|
||||
;;
|
||||
migrate)
|
||||
migrate
|
||||
;;
|
||||
clean)
|
||||
clean
|
||||
;;
|
||||
start-svc)
|
||||
start_service "$2"
|
||||
;;
|
||||
stop-svc)
|
||||
stop_service "$2"
|
||||
;;
|
||||
rebuild-svc)
|
||||
rebuild_service "$2"
|
||||
;;
|
||||
*)
|
||||
echo "RWA Backend Services Deployment Script"
|
||||
echo ""
|
||||
echo "Usage: $0 <command> [options]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " install - First time setup (generate secrets, create configs)"
|
||||
echo " up/start - Start all services"
|
||||
echo " down/stop - Stop all services"
|
||||
echo " restart - Restart all services"
|
||||
echo " build - Build all Docker images"
|
||||
echo " status/ps - Show service status"
|
||||
echo " health - Check health of all services"
|
||||
echo " logs [svc] - View logs (optionally for specific service)"
|
||||
echo " migrate - Run database migrations"
|
||||
echo " clean - Remove all containers, volumes, and images"
|
||||
echo ""
|
||||
echo "Single Service Commands:"
|
||||
echo " start-svc <name> - Start a specific service"
|
||||
echo " stop-svc <name> - Stop a specific service"
|
||||
echo " rebuild-svc <name> - Rebuild and restart a specific service"
|
||||
echo ""
|
||||
echo "Services:"
|
||||
echo " identity-service, wallet-service, backup-service, planting-service,"
|
||||
echo " referral-service, reward-service, mpc-service, leaderboard-service,"
|
||||
echo " reporting-service, authorization-service, admin-service"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 install # First time setup"
|
||||
echo " $0 build # Build images"
|
||||
echo " $0 up # Start all services"
|
||||
echo " $0 logs identity-service # View identity-service logs"
|
||||
echo " $0 rebuild-svc mpc-service # Rebuild specific service"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
# =============================================================================
|
||||
# RWA Backend Services - Docker Compose
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# ./deploy.sh up # Start all services
|
||||
# ./deploy.sh down # Stop all services
|
||||
# ./deploy.sh logs # View logs
|
||||
# ./deploy.sh status # Check status
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
# ===========================================================================
|
||||
# Infrastructure Services
|
||||
# ===========================================================================
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: rwa-postgres
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-rwa_user}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-rwa_secure_password}
|
||||
POSTGRES_MULTIPLE_DATABASES: rwa_identity,rwa_wallet,rwa_mpc,rwa_backup,rwa_planting,rwa_referral,rwa_reward,rwa_leaderboard,rwa_reporting,rwa_authorization
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./scripts/init-databases.sh:/docker-entrypoint-initdb.d/init-databases.sh:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-rwa_user}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: rwa-redis
|
||||
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
zookeeper:
|
||||
image: confluentinc/cp-zookeeper:7.5.0
|
||||
container_name: rwa-zookeeper
|
||||
environment:
|
||||
ZOOKEEPER_CLIENT_PORT: 2181
|
||||
ZOOKEEPER_TICK_TIME: 2000
|
||||
healthcheck:
|
||||
test: ["CMD", "nc", "-z", "localhost", "2181"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
kafka:
|
||||
image: confluentinc/cp-kafka:7.5.0
|
||||
container_name: rwa-kafka
|
||||
depends_on:
|
||||
zookeeper:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "9092:9092"
|
||||
environment:
|
||||
KAFKA_BROKER_ID: 1
|
||||
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
|
||||
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,PLAINTEXT_HOST://0.0.0.0:9092
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
||||
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
|
||||
healthcheck:
|
||||
test: ["CMD", "kafka-topics", "--bootstrap-server", "localhost:9092", "--list"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
# ===========================================================================
|
||||
# Application Services
|
||||
# ===========================================================================
|
||||
|
||||
identity-service:
|
||||
build:
|
||||
context: ./identity-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-identity-service
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3000
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_identity?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- JWT_ACCESS_EXPIRES_IN=2h
|
||||
- JWT_REFRESH_EXPIRES_IN=30d
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=0
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=identity-service
|
||||
- KAFKA_GROUP_ID=identity-service-group
|
||||
- WALLET_ENCRYPTION_SALT=${WALLET_ENCRYPTION_SALT}
|
||||
- MPC_SERVICE_URL=http://mpc-service:3006
|
||||
- MPC_MODE=remote
|
||||
- BACKUP_SERVICE_URL=http://backup-service:3002
|
||||
- BACKUP_SERVICE_ENABLED=true
|
||||
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
wallet-service:
|
||||
build:
|
||||
context: ./wallet-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-wallet-service
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3001
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_wallet?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=1
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=wallet-service
|
||||
- KAFKA_GROUP_ID=wallet-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3001/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
backup-service:
|
||||
build:
|
||||
context: ./backup-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-backup-service
|
||||
ports:
|
||||
- "3002:3002"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3002
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_backup?schema=public
|
||||
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET}
|
||||
- ALLOWED_SERVICES=identity-service,recovery-service
|
||||
- BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY}
|
||||
- BACKUP_ENCRYPTION_KEY_ID=key-v1
|
||||
- MAX_RETRIEVE_PER_DAY=3
|
||||
- MAX_STORE_PER_MINUTE=10
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3002/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
planting-service:
|
||||
build:
|
||||
context: ./planting-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-planting-service
|
||||
ports:
|
||||
- "3003:3003"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3003
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_planting?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=2
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=planting-service
|
||||
- KAFKA_GROUP_ID=planting-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3003/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
referral-service:
|
||||
build:
|
||||
context: ./referral-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-referral-service
|
||||
ports:
|
||||
- "3004:3004"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3004
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_referral?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=3
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=referral-service
|
||||
- KAFKA_GROUP_ID=referral-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3004/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
reward-service:
|
||||
build:
|
||||
context: ./reward-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-reward-service
|
||||
ports:
|
||||
- "3005:3005"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3005
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_reward?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=4
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=reward-service
|
||||
- KAFKA_GROUP_ID=reward-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3005/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
mpc-service:
|
||||
build:
|
||||
context: ./mpc-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-mpc-service
|
||||
ports:
|
||||
- "3006:3006"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3006
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_mpc?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=5
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=mpc-service
|
||||
- KAFKA_GROUP_ID=mpc-service-group
|
||||
- MPC_COORDINATOR_URL=http://192.168.1.100:8081
|
||||
- MPC_MESSAGE_ROUTER_WS_URL=ws://192.168.1.100:8082
|
||||
- SHARE_MASTER_KEY=${SHARE_MASTER_KEY}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3006/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
leaderboard-service:
|
||||
build:
|
||||
context: ./leaderboard-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-leaderboard-service
|
||||
ports:
|
||||
- "3007:3007"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3007
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_leaderboard?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=6
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=leaderboard-service
|
||||
- KAFKA_GROUP_ID=leaderboard-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3007/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
reporting-service:
|
||||
build:
|
||||
context: ./reporting-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-reporting-service
|
||||
ports:
|
||||
- "3008:3008"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3008
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_reporting?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=7
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=reporting-service
|
||||
- KAFKA_GROUP_ID=reporting-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3008/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
authorization-service:
|
||||
build:
|
||||
context: ./authorization-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-authorization-service
|
||||
ports:
|
||||
- "3009:3009"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3009
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_authorization?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=8
|
||||
- KAFKA_BROKERS=kafka:29092
|
||||
- KAFKA_CLIENT_ID=authorization-service
|
||||
- KAFKA_GROUP_ID=authorization-service-group
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
kafka:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3009/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
admin-service:
|
||||
build:
|
||||
context: ./admin-service
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-admin-service
|
||||
ports:
|
||||
- "3010:3010"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3010
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_identity?schema=public
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||
- REDIS_DB=9
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3010/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
# ===========================================================================
|
||||
# Volumes
|
||||
# ===========================================================================
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
|
||||
# ===========================================================================
|
||||
# Networks
|
||||
# ===========================================================================
|
||||
networks:
|
||||
rwa-network:
|
||||
driver: bridge
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# =============================================================================
|
||||
# Referral Service Dockerfile
|
||||
# =============================================================================
|
||||
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tsconfig*.json ./
|
||||
COPY nest-cli.json ./
|
||||
|
||||
# Copy Prisma schema
|
||||
COPY prisma ./prisma/
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Generate Prisma client
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy source code
|
||||
COPY src ./src
|
||||
|
||||
# Build TypeScript
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install production dependencies only
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy Prisma schema and generate client
|
||||
COPY prisma ./prisma/
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nestjs -u 1001
|
||||
|
||||
# Switch to non-root user
|
||||
USER nestjs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3004
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:3004/health || exit 1
|
||||
|
||||
# Start service
|
||||
CMD ["node", "dist/main.js"]
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# =============================================================================
|
||||
# Reporting Service Dockerfile
|
||||
# =============================================================================
|
||||
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tsconfig*.json ./
|
||||
COPY nest-cli.json ./
|
||||
|
||||
# Copy Prisma schema
|
||||
COPY prisma ./prisma/
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Generate Prisma client
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy source code
|
||||
COPY src ./src
|
||||
|
||||
# Build TypeScript
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install production dependencies only
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy Prisma schema and generate client
|
||||
COPY prisma ./prisma/
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nestjs -u 1001
|
||||
|
||||
# Switch to non-root user
|
||||
USER nestjs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3008
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:3008/health || exit 1
|
||||
|
||||
# Start service
|
||||
CMD ["node", "dist/main.js"]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Function to create database if not exists
|
||||
create_database() {
|
||||
local database=$1
|
||||
echo "Creating database: $database"
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||
SELECT 'CREATE DATABASE $database'
|
||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$database')\gexec
|
||||
EOSQL
|
||||
}
|
||||
|
||||
# Create all required databases
|
||||
for db in rwa_identity rwa_wallet rwa_mpc rwa_backup rwa_planting rwa_referral rwa_reward rwa_leaderboard rwa_reporting rwa_authorization; do
|
||||
create_database "$db"
|
||||
done
|
||||
|
||||
echo "All databases created successfully!"
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# =============================================================================
|
||||
# Wallet Service Dockerfile
|
||||
# =============================================================================
|
||||
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY tsconfig*.json ./
|
||||
COPY nest-cli.json ./
|
||||
|
||||
# Copy Prisma schema
|
||||
COPY prisma ./prisma/
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Generate Prisma client
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy source code
|
||||
COPY src ./src
|
||||
|
||||
# Build TypeScript
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install production dependencies only
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy Prisma schema and generate client
|
||||
COPY prisma ./prisma/
|
||||
RUN npx prisma generate
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nestjs -u 1001
|
||||
|
||||
# Switch to non-root user
|
||||
USER nestjs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3001
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:3001/health || exit 1
|
||||
|
||||
# Start service
|
||||
CMD ["node", "dist/main.js"]
|
||||
Loading…
Reference in New Issue