Commit 27e24cfb authored by uuo's avatar uuo

chore: 增强配置安全并添加自动化部署脚本

- 移除硬编码的敏感信息,改为从环境变量读取
- 添加 JWT 密钥长度验证和必需环境变量检查
- 创建自动化部署脚本 start.sh 和密钥生成脚本 generate_secrets.py
- 统一 docker-compose 配置,支持环境变量注入
- 更新各服务的配置文件以支持外部化配置
parent 69a4019b
......@@ -7,17 +7,17 @@ services:
container_name: llm-filter-db
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: llm_filter_db
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "5433:5432"
- "${POSTGRES_PORT_EXTERNAL:-5433}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- llm-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin -d llm_filter_db"]
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
......@@ -30,14 +30,18 @@ services:
container_name: llm-filter-auth
restart: always
ports:
- "8081:8081"
- "${AUTH_SERVICE_PORT:-8081}:8081"
environment:
- DB_HOST=postgres
- DB_USER=admin
- DB_PASSWORD=password
- DB_NAME=llm_filter_db
- DB_PORT=5432
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- JWT_SECRET=${JWT_SECRET}
- ADMIN_USERNAME=${ADMIN_USERNAME}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- ADMIN_EMAIL=${ADMIN_EMAIL}
- TZ=${TZ}
depends_on:
postgres:
condition: service_healthy
......@@ -52,14 +56,23 @@ services:
container_name: llm-filter-edu
restart: always
ports:
- "8082:8082"
- "${EDU_SERVICE_PORT:-8082}:8082"
environment:
- DB_HOST=postgres
- DB_USER=admin
- DB_PASSWORD=password
- DB_NAME=llm_filter_db
- DB_PORT=5432
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- JWT_SECRET=${JWT_SECRET}
- SERVER_PORT=${SERVER_PORT}
- JPA_DDL_AUTO=${JPA_DDL_AUTO}
- JPA_SHOW_SQL=${JPA_SHOW_SQL}
- JPA_FORMAT_SQL=${JPA_FORMAT_SQL}
- JPA_DIALECT=${JPA_DIALECT}
- LOGGING_LEVEL=${LOGGING_LEVEL}
- SPRING_REDIS_HOST=${REDIS_HOST}
- SPRING_REDIS_PORT=${REDIS_PORT}
- TZ=${TZ}
depends_on:
postgres:
condition: service_healthy
......@@ -76,22 +89,35 @@ services:
# 生产环境不需要 --reload
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers --forwarded-allow-ips '*'
ports:
- "8000:8000"
- "${LLM_SERVICE_PORT:-8000}:8000"
# 生产环境移除代码挂载,使用镜像内的代码
volumes:
- ./scripts:/app/scripts
environment:
- MONGODB_URL=mongodb://mongo:27017
- DB_NAME=llm_filter_db
- SECRET_KEY=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- ALGORITHM=HS256
- ACCESS_TOKEN_EXPIRE_MINUTES=30
- TERM_START_DATE=2025-09-01
- OLLAMA_BASE_URL=http://192.168.6.6:11434/
- OLLAMA_MODEL=deepseek-r1:14b
- MONGODB_URL=${MONGODB_URL}
- DB_NAME=${DB_NAME}
- SECRET_KEY=${JWT_SECRET}
- ALGORITHM=${ALGORITHM}
- ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES}
- TERM_START_DATE=${TERM_START_DATE}
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL}
- OLLAMA_MODEL=${OLLAMA_MODEL}
# Dify Configuration
- DIFY_API_URL=http://192.168.6.6/v1
- DIFY_API_KEY=app-lkK33EQOVXXrjD9x3SKbItr7
- DIFY_API_URL=${DIFY_API_URL}
- DIFY_API_KEY=${DIFY_API_KEY}
- DIFY_RESPONSE_MODE=${DIFY_RESPONSE_MODE}
- DIFY_MESSAGE_ENDPOINT=${DIFY_MESSAGE_ENDPOINT}
# Redis Configuration
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- REDIS_PASSWORD=${REDIS_PASSWORD}
# App Configuration
- APP_BASE_URL=${APP_BASE_URL}
- API_V1_STR=${API_V1_STR}
- APP_MODE=${APP_MODE}
- CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS}
- TZ=${TZ}
depends_on:
- mongo
networks:
......@@ -107,14 +133,21 @@ services:
# 生产环境不需要 --reload
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers --forwarded-allow-ips '*'
ports:
- "8003:8000"
- "${SECURITY_SERVICE_PORT:-8003}:8000"
# 生产环境移除代码挂载
environment:
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- DIFY_API_URL=http://192.168.6.6/v1
- DIFY_API_KEY=app-ggTb0oC9WXQQm2r7KrvVUS6v
- MONGODB_URL=mongodb://mongo:27017
- MONGODB_DB_NAME=security_service_db
- JWT_SECRET=${JWT_SECRET}
- ALGORITHM=${ALGORITHM}
- DIFY_API_URL=${DIFY_API_URL}
- DIFY_API_KEY=${DIFY_API_KEY}
- DIFY_RESPONSE_MODE=${DIFY_RESPONSE_MODE}
- MONGODB_URL=${MONGODB_URL}
- MONGODB_DB_NAME=${MONGODB_DB_NAME}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- TZ=${TZ}
networks:
- llm-network
......@@ -124,7 +157,7 @@ services:
container_name: llm-filter-mongo
restart: always
ports:
- "27017:27017"
- "${MONGODB_PORT_EXTERNAL:-27017}:27017"
volumes:
- mongo_data:/data/db
networks:
......@@ -136,9 +169,11 @@ services:
container_name: llm-filter-gateway
restart: always
ports:
- "8080:80"
- "${GATEWAY_PORT:-8080}:80"
volumes:
- ./gateway/nginx.conf:/etc/nginx/nginx.conf:ro
environment:
- TZ=${TZ}
depends_on:
- auth-service
- edu-service
......
......@@ -6,11 +6,11 @@ services:
image: postgres:15-alpine
container_name: llm-filter-db
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: llm_filter_db
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "5433:5432"
- "${POSTGRES_PORT_EXTERNAL:-5433}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
......@@ -20,10 +20,13 @@ services:
redis:
image: redis:7-alpine
container_name: llm-filter-redis
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "6379:6379"
- "${REDIS_PORT_EXTERNAL:-6379}:6379"
volumes:
- redis_data:/data
environment:
- TZ=${TZ}
networks:
- llm-network
......@@ -34,36 +37,47 @@ services:
dockerfile: Dockerfile
container_name: llm-filter-auth
ports:
- "8081:8081"
- "${AUTH_SERVICE_PORT:-8081}:8081"
environment:
- DB_HOST=postgres
- DB_USER=admin
- DB_PASSWORD=password
- DB_NAME=llm_filter_db
- DB_PORT=5432
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- JWT_SECRET=${JWT_SECRET}
- ADMIN_USERNAME=${ADMIN_USERNAME}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- ADMIN_EMAIL=${ADMIN_EMAIL}
- TZ=${TZ}
depends_on:
- postgres
networks:
- llm-network
# 教务核心服务 (Go)
# 教务核心服务
edu-service:
build:
context: ./microservices/edu-service
dockerfile: Dockerfile
container_name: llm-filter-edu
ports:
- "8082:8082"
- "${EDU_SERVICE_PORT:-8082}:8082"
environment:
- DB_HOST=postgres
- DB_USER=admin
- DB_PASSWORD=password
- DB_NAME=llm_filter_db
- DB_PORT=5432
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- JWT_SECRET=${JWT_SECRET}
- SERVER_PORT=${SERVER_PORT}
- JPA_DDL_AUTO=${JPA_DDL_AUTO}
- JPA_SHOW_SQL=${JPA_SHOW_SQL}
- JPA_FORMAT_SQL=${JPA_FORMAT_SQL}
- JPA_DIALECT=${JPA_DIALECT}
- LOGGING_LEVEL=${LOGGING_LEVEL}
- SPRING_REDIS_HOST=${REDIS_HOST}
- SPRING_REDIS_PORT=${REDIS_PORT}
- TZ=${TZ}
depends_on:
- postgres
- redis
......@@ -78,25 +92,35 @@ services:
container_name: llm-filter-llm
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --proxy-headers --forwarded-allow-ips '*'
ports:
- "8000:8000"
- "${LLM_SERVICE_PORT:-8000}:8000"
volumes:
- ./microservices/llm-service:/app
- ./scripts:/app/scripts
environment:
- MONGODB_URL=mongodb://mongo:27017
- DB_NAME=llm_filter_db
- SECRET_KEY=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- ALGORITHM=HS256
- ACCESS_TOKEN_EXPIRE_MINUTES=30
- TERM_START_DATE=2025-09-01
- OLLAMA_BASE_URL=http://192.168.6.6:11434/
- OLLAMA_MODEL=deepseek-r1:14b
- MONGODB_URL=${MONGODB_URL}
- DB_NAME=${DB_NAME}
- SECRET_KEY=${JWT_SECRET}
- ALGORITHM=${ALGORITHM}
- ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES}
- TERM_START_DATE=${TERM_START_DATE}
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL}
- OLLAMA_MODEL=${OLLAMA_MODEL}
# Dify Configuration
- DIFY_API_URL=http://192.168.6.6/v1
- DIFY_API_KEY=app-sLnrbNjEi1GiTDGgL2B2DwLZ
- DIFY_API_URL=${DIFY_API_URL}
- DIFY_API_KEY=${DIFY_API_KEY}
- DIFY_RESPONSE_MODE=${DIFY_RESPONSE_MODE}
- DIFY_MESSAGE_ENDPOINT=${DIFY_MESSAGE_ENDPOINT}
# Redis Configuration
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- REDIS_PASSWORD=${REDIS_PASSWORD}
# App Configuration
- APP_BASE_URL=${APP_BASE_URL}
- API_V1_STR=${API_V1_STR}
- APP_MODE=${APP_MODE}
- CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS}
- TZ=${TZ}
depends_on:
- mongo
- redis
......@@ -111,15 +135,22 @@ services:
container_name: llm-filter-security
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --proxy-headers --forwarded-allow-ips '*'
ports:
- "8003:8000"
- "${SECURITY_SERVICE_PORT:-8003}:8000"
volumes:
- ./microservices/security-service/app:/app/app
environment:
- JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
- DIFY_API_URL=http://192.168.6.6/v1
- DIFY_API_KEY=app-ggTb0oC9WXQQm2r7KrvVUS6v
- MONGODB_URL=mongodb://mongo:27017
- MONGODB_DB_NAME=security_service_db
- JWT_SECRET=${JWT_SECRET}
- ALGORITHM=${ALGORITHM}
- DIFY_API_URL=${DIFY_API_URL}
- DIFY_API_KEY=${DIFY_API_KEY}
- DIFY_RESPONSE_MODE=${DIFY_RESPONSE_MODE}
- MONGODB_URL=${MONGODB_URL}
- MONGODB_DB_NAME=${MONGODB_DB_NAME}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_DB=${REDIS_DB}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- TZ=${TZ}
depends_on:
- mongo
networks:
......@@ -130,7 +161,7 @@ services:
image: mongo:latest
container_name: llm-filter-mongo
ports:
- "27017:27017"
- "${MONGODB_PORT_EXTERNAL:-27017}:27017"
volumes:
- mongo_data:/data/db
networks:
......@@ -141,9 +172,11 @@ services:
image: nginx:alpine
container_name: llm-filter-gateway
ports:
- "8080:80"
- "${GATEWAY_PORT:-8080}:80"
volumes:
- ./gateway/nginx.conf:/etc/nginx/nginx.conf:ro
environment:
- TZ=${TZ}
depends_on:
- auth-service
- edu-service
......
......@@ -37,21 +37,9 @@ func main() {
dbName := os.Getenv("DB_NAME")
dbPort := os.Getenv("DB_PORT")
// 默认值处理(用于本地开发)
if dbHost == "" {
dbHost = "localhost"
}
if dbUser == "" {
dbUser = "admin"
}
if dbPassword == "" {
dbPassword = "password" // 请确保本地有此密码的数据库或修改此处
}
if dbName == "" {
dbName = "llm_filter_db"
}
if dbPort == "" {
dbPort = "5433"
// 必需的环境变量检查
if dbHost == "" || dbUser == "" || dbPassword == "" || dbName == "" || dbPort == "" {
log.Fatal("Missing required database environment variables: DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT")
}
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai",
......@@ -111,7 +99,11 @@ func main() {
}
func initAdminUser(repo *repository.UserRepository) {
adminUsername := "admin"
adminUsername := os.Getenv("ADMIN_USERNAME")
if adminUsername == "" {
adminUsername = "admin"
}
exists, err := repo.ExistsByUsername(adminUsername)
if err != nil {
log.Printf("Failed to check admin user existence: %v", err)
......@@ -123,7 +115,7 @@ func initAdminUser(repo *repository.UserRepository) {
adminPassword := os.Getenv("ADMIN_PASSWORD")
if adminPassword == "" {
adminPassword = "password123"
log.Fatal("ADMIN_PASSWORD environment variable is required for initial admin user creation")
}
hashedPwd, err := utils.HashPassword(adminPassword)
......@@ -132,11 +124,16 @@ func initAdminUser(repo *repository.UserRepository) {
return
}
adminEmail := os.Getenv("ADMIN_EMAIL")
if adminEmail == "" {
adminEmail = "admin@example.com"
}
adminUser := &model.User{
Username: adminUsername,
Email: "admin@example.com",
Email: adminEmail,
Password: hashedPwd,
Role: "administrator", // 兼容旧系统的最高权限角色
Role: "administrator",
RoleLevel: 5,
Edition: "edu",
}
......@@ -144,7 +141,7 @@ func initAdminUser(repo *repository.UserRepository) {
if err := repo.Create(adminUser); err != nil {
log.Printf("Failed to create admin user: %v", err)
} else {
log.Printf("Admin user created successfully. Username: %s, Password: %s", adminUsername, adminPassword)
log.Printf("Admin user created successfully. Username: %s", adminUsername)
}
} else {
log.Println("Admin user already exists.")
......
......@@ -9,12 +9,17 @@ import (
"golang.org/x/crypto/bcrypt"
)
var jwtSecret = []byte("your-secret-key")
var jwtSecret []byte
func init() {
if secret := os.Getenv("JWT_SECRET"); secret != "" {
jwtSecret = []byte(secret)
secret := os.Getenv("JWT_SECRET")
if secret == "" {
log.Fatal("JWT_SECRET environment variable is required")
}
if len(secret) < 32 {
log.Fatal("JWT_SECRET must be at least 32 characters long")
}
jwtSecret = []byte(secret)
}
func GetJWTSecret() []byte {
......
server.port=8082
server.port=${SERVER_PORT:8082}
spring.application.name=edu-service
# Database Configuration
# ============================================================
# 数据库配置
# ============================================================
spring.datasource.url=jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5433}/${DB_NAME:llm_filter_db}
spring.datasource.username=${DB_USER:admin}
spring.datasource.password=${DB_PASSWORD:password}
spring.datasource.password=${DB_PASSWORD}
spring.datasource.driver-class-name=org.postgresql.Driver
# JPA Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
# ============================================================
# JPA/Hibernate 配置
# ============================================================
spring.jpa.hibernate.ddl-auto=${JPA_DDL_AUTO:update}
spring.jpa.show-sql=${JPA_SHOW_SQL:true}
spring.jpa.properties.hibernate.dialect=${JPA_DIALECT:org.hibernate.dialect.PostgreSQLDialect}
spring.jpa.properties.hibernate.format_sql=${JPA_FORMAT_SQL:true}
# Security
jwt.secret=${JWT_SECRET:your_secret_key_here_must_be_very_long_to_be_secure_at_least_32_bytes}
# ============================================================
# 安全配置
# ============================================================
jwt.secret=${JWT_SECRET}
# Redis Configuration
# ============================================================
# Redis 配置
# ============================================================
spring.redis.host=${SPRING_REDIS_HOST:localhost}
spring.redis.port=${SPRING_REDIS_PORT:6379}
spring.redis.timeout=2000
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.timeout=${REDIS_TIMEOUT:2000}
spring.redis.lettuce.pool.max-active=${REDIS_POOL_MAX_ACTIVE:8}
spring.redis.lettuce.pool.max-wait=${REDIS_POOL_MAX_WAIT:-1}
spring.redis.lettuce.pool.max-idle=${REDIS_POOL_MAX_IDLE:8}
spring.redis.lettuce.pool.min-idle=${REDIS_POOL_MIN_IDLE:0}
# ============================================================
# 日志配置
# ============================================================
logging.level.root=${LOGGING_LEVEL:INFO}
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
import os
# Pydantic v2 中 BaseSettings 已迁移到 pydantic-settings
from pydantic_settings import BaseSettings
from dotenv import load_dotenv
......@@ -21,17 +20,17 @@ class Settings(BaseSettings):
DB_NAME: str = os.getenv("DB_NAME", "llm_filter_db")
# JWT配置
SECRET_KEY: str = os.getenv("SECRET_KEY", "your_secret_key_here")
SECRET_KEY: str = os.getenv("SECRET_KEY", "")
ALGORITHM: str = os.getenv("ALGORITHM", "HS256")
ACCESS_TOKEN_EXPIRE_MINUTES: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))
# Ollama配置
OLLAMA_BASE_URL: str = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434")
OLLAMA_MODEL: str = os.getenv("OLLAMA_MODEL", "llama2")
OLLAMA_BASE_URL: str = os.getenv("OLLAMA_BASE_URL", "http://192.168.6.6:11434/")
OLLAMA_MODEL: str = os.getenv("OLLAMA_MODEL", "deepseek-r1:14b")
# Dify配置
DIFY_API_URL: str = os.getenv("DIFY_API_URL", "http://192.168.6.6/v1")
DIFY_API_KEY: str = os.getenv("DIFY_API_KEY", "app-sLnrbNjEi1GiTDGgL2B2DwLZ")
DIFY_API_KEY: str = os.getenv("DIFY_API_KEY", "")
DIFY_RESPONSE_MODE: str = os.getenv("DIFY_RESPONSE_MODE", "streaming")
DIFY_MESSAGE_ENDPOINT: str = os.getenv("DIFY_MESSAGE_ENDPOINT", "chat-messages")
......
from pydantic_settings import BaseSettings
import os
class Settings(BaseSettings):
API_V1_STR: str = "/api/v1"
PROJECT_NAME: str = "Security Service"
# 鉴权配置 (与 Auth Service 保持一致)
JWT_SECRET: str = "llm_filter_secure_secret_key_2025_update_must_be_32_bytes"
ALGORITHM: str = "HS256"
JWT_SECRET: str = os.getenv("JWT_SECRET", "")
ALGORITHM: str = os.getenv("ALGORITHM", "HS256")
# Dify 配置
DIFY_API_URL: str = "http://192.168.6.6/v1"
DIFY_API_KEY: str = "app-lkK33EQOVXXrjD9x3SKbItr7"
DIFY_API_URL: str = os.getenv("DIFY_API_URL", "http://192.168.6.6/v1")
DIFY_API_KEY: str = os.getenv("DIFY_API_KEY", "")
DIFY_RESPONSE_MODE: str = os.getenv("DIFY_RESPONSE_MODE", "streaming")
# MongoDB 配置
MONGODB_URL: str = "mongodb://localhost:27017"
MONGODB_DB_NAME: str = "security_service_db"
MONGODB_URL: str = os.getenv("MONGODB_URL", "mongodb://localhost:27017")
MONGODB_DB_NAME: str = os.getenv("MONGODB_DB_NAME", "security_service_db")
# Redis 配置
REDIS_HOST: str = os.getenv("REDIS_HOST", "localhost")
REDIS_PORT: int = int(os.getenv("REDIS_PORT", "6379"))
REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
REDIS_PASSWORD: str = os.getenv("REDIS_PASSWORD", "")
class Config:
case_sensitive = True
......
This diff is collapsed.
#!/bin/bash
# LLM Filter 项目启动脚本
echo "=========================================="
echo " LLM Filter 项目启动脚本"
echo "=========================================="
echo ""
# 检查 Docker 和 Docker Compose
if ! command -v docker &> /dev/null; then
echo "[ERROR] Docker 未安装"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo "[ERROR] Docker Compose 未安装"
exit 1
fi
echo "[INFO] Docker 和 Docker Compose 已安装"
echo ""
# 检查 .env 文件
if [ ! -f .env ]; then
echo "[ERROR] .env 文件不存在,请先运行:"
echo " python scripts/generate_secrets.py"
exit 1
fi
echo "[INFO] .env 文件存在"
echo ""
# 步骤 1:停止现有服务
echo "=========================================="
echo "步骤 1: 停止现有服务"
echo "=========================================="
docker-compose down
echo ""
# 步骤 2:启动基础设施
echo "=========================================="
echo "步骤 2: 启动基础设施 (PostgreSQL, Redis, MongoDB)"
echo "=========================================="
docker-compose up -d postgres redis mongo
echo "[INFO] 等待数据库启动..."
sleep 10
echo ""
echo "[INFO] 检查数据库状态..."
docker-compose ps postgres redis mongo
echo ""
# 步骤 3:启动业务服务
echo "=========================================="
echo "步骤 3: 启动业务服务"
echo "=========================================="
docker-compose up -d auth-service edu-service llm-service security-service
echo "[INFO] 等待服务启动..."
sleep 15
echo ""
echo "[INFO] 检查业务服务状态..."
docker-compose ps auth-service edu-service llm-service security-service
echo ""
# 步骤 4:启动网关
echo "=========================================="
echo "步骤 4: 启动 API 网关"
echo "=========================================="
docker-compose up -d gateway
echo "[INFO] 等待网关启动..."
sleep 5
echo ""
echo "[INFO] 检查网关状态..."
docker-compose ps gateway
echo ""
# 步骤 5:验证服务
echo "=========================================="
echo "步骤 5: 验证所有服务"
echo "=========================================="
docker-compose ps
echo ""
echo "=========================================="
echo " 启动完成!"
echo "=========================================="
echo ""
echo "📚 文档地址:"
echo " - Gateway: http://localhost:8080"
echo " - Auth Service: http://localhost:8080/docs/auth/"
echo " - Edu Service: http://localhost:8080/docs/edu/"
echo " - LLM Service: http://localhost:8080/docs/llm/"
echo " - Security: http://localhost:8080/docs/security/"
echo ""
echo "🔑 默认管理员账号:"
echo " - 用户名: admin"
echo " - 密码: 查看 .env 文件中的 ADMIN_PASSWORD"
echo ""
echo "📊 查看日志:"
echo " - 所有服务: docker-compose logs -f"
echo " - 特定服务: docker-compose logs -f [service-name]"
echo ""
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment