feat: 添加环境变量管理工具和部署配置改版
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m33s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m33s
主要改动: - 新增交互式环境配置脚本 (scripts/setup-env.sh) - 新增本地启动快捷脚本 (scripts/run-local.sh) - 新增环境变量模板文件 (.env.example) - 部署模式改版:使用嵌入式配置 + 环境变量覆盖 - 添加对象存储功能支持 - 改进 IoT 卡片导入任务 - 优化 OpenAPI 文档生成 - 删除旧的配置文件,改用嵌入式默认配置
This commit is contained in:
106
scripts/run-local.sh
Executable file
106
scripts/run-local.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# 君鸿卡管系统 - 本地开发快速启动脚本
|
||||
# ============================================================================
|
||||
# 使用方法:
|
||||
# ./scripts/run-local.sh # 启动 API 服务
|
||||
# ./scripts/run-local.sh worker # 启动 Worker 服务
|
||||
# ./scripts/run-local.sh both # 同时启动 API 和 Worker
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
ENV_FILE=".env.local"
|
||||
|
||||
# 检查环境配置文件
|
||||
check_env() {
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo -e "${RED}[ERROR]${NC} 未找到环境配置文件: $ENV_FILE"
|
||||
echo ""
|
||||
echo "请先运行环境配置向导:"
|
||||
echo -e " ${BLUE}./scripts/setup-env.sh${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 加载环境变量
|
||||
load_env() {
|
||||
echo -e "${BLUE}[INFO]${NC} 加载环境变量: $ENV_FILE"
|
||||
source "$ENV_FILE"
|
||||
}
|
||||
|
||||
# 创建日志目录
|
||||
ensure_logs_dir() {
|
||||
if [ ! -d "logs" ]; then
|
||||
mkdir -p logs
|
||||
echo -e "${GREEN}[OK]${NC} 创建日志目录: logs/"
|
||||
fi
|
||||
}
|
||||
|
||||
# 启动 API 服务
|
||||
start_api() {
|
||||
echo -e "\n${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} 启动 API 服务${NC}"
|
||||
echo -e "${GREEN}========================================${NC}\n"
|
||||
go run cmd/api/main.go
|
||||
}
|
||||
|
||||
# 启动 Worker 服务
|
||||
start_worker() {
|
||||
echo -e "\n${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} 启动 Worker 服务${NC}"
|
||||
echo -e "${GREEN}========================================${NC}\n"
|
||||
go run cmd/worker/main.go
|
||||
}
|
||||
|
||||
# 同时启动两个服务
|
||||
start_both() {
|
||||
echo -e "\n${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} 同时启动 API 和 Worker 服务${NC}"
|
||||
echo -e "${GREEN}========================================${NC}\n"
|
||||
|
||||
# 后台启动 worker
|
||||
go run cmd/worker/main.go &
|
||||
WORKER_PID=$!
|
||||
echo -e "${GREEN}[OK]${NC} Worker 服务已启动 (PID: $WORKER_PID)"
|
||||
|
||||
# 前台启动 api
|
||||
trap "kill $WORKER_PID 2>/dev/null" EXIT
|
||||
go run cmd/api/main.go
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
check_env
|
||||
load_env
|
||||
ensure_logs_dir
|
||||
|
||||
case "${1:-api}" in
|
||||
api)
|
||||
start_api
|
||||
;;
|
||||
worker)
|
||||
start_worker
|
||||
;;
|
||||
both)
|
||||
start_both
|
||||
;;
|
||||
*)
|
||||
echo "用法: $0 [api|worker|both]"
|
||||
echo ""
|
||||
echo " api - 启动 API 服务(默认)"
|
||||
echo " worker - 启动 Worker 服务"
|
||||
echo " both - 同时启动 API 和 Worker 服务"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
308
scripts/setup-env.sh
Executable file
308
scripts/setup-env.sh
Executable file
@@ -0,0 +1,308 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# 君鸿卡管系统 - 本地开发环境变量设置脚本
|
||||
# ============================================================================
|
||||
# 使用方法:
|
||||
# 1. 首次设置:./scripts/setup-env.sh
|
||||
# 2. 加载环境:source .env.local
|
||||
# 3. 启动服务:go run cmd/api/main.go
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 配置文件路径
|
||||
ENV_FILE=".env.local"
|
||||
|
||||
# 打印带颜色的消息
|
||||
print_header() {
|
||||
echo -e "\n${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} $1${NC}"
|
||||
echo -e "${BLUE}========================================${NC}\n"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${CYAN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[OK]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 读取用户输入(带默认值)
|
||||
read_input() {
|
||||
local prompt="$1"
|
||||
local default="$2"
|
||||
local var_name="$3"
|
||||
local is_password="$4"
|
||||
|
||||
if [ "$is_password" = "true" ]; then
|
||||
echo -n -e "${CYAN}$prompt${NC} [默认: ****]: "
|
||||
read -s input
|
||||
echo ""
|
||||
else
|
||||
echo -n -e "${CYAN}$prompt${NC} [默认: $default]: "
|
||||
read input
|
||||
fi
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
eval "$var_name='$default'"
|
||||
else
|
||||
eval "$var_name='$input'"
|
||||
fi
|
||||
}
|
||||
|
||||
# 生成随机密钥
|
||||
generate_secret() {
|
||||
if command -v openssl &> /dev/null; then
|
||||
openssl rand -hex 32
|
||||
else
|
||||
# 备用方案:使用 /dev/urandom
|
||||
head -c 32 /dev/urandom | xxd -p
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查服务是否可用
|
||||
check_service() {
|
||||
local host="$1"
|
||||
local port="$2"
|
||||
local name="$3"
|
||||
|
||||
if command -v nc &> /dev/null; then
|
||||
if nc -z "$host" "$port" 2>/dev/null; then
|
||||
print_success "$name ($host:$port) 连接正常"
|
||||
return 0
|
||||
else
|
||||
print_warning "$name ($host:$port) 无法连接"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
print_info "跳过 $name 连接检查(nc 命令不可用)"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
print_header "君鸿卡管系统 - 环境变量配置向导"
|
||||
|
||||
echo "本脚本将帮助您配置本地开发所需的环境变量。"
|
||||
echo "配置将保存到 $ENV_FILE 文件中。"
|
||||
echo ""
|
||||
|
||||
# 检查是否已存在配置文件
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
print_warning "发现已存在的配置文件: $ENV_FILE"
|
||||
echo -n "是否覆盖?[y/N]: "
|
||||
read confirm
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
print_info "已取消。如需更新配置,请手动编辑 $ENV_FILE"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# ========================================
|
||||
# 数据库配置
|
||||
# ========================================
|
||||
print_header "数据库配置 (PostgreSQL)"
|
||||
|
||||
read_input "数据库主机地址" "localhost" DB_HOST
|
||||
read_input "数据库端口" "5432" DB_PORT
|
||||
read_input "数据库用户名" "postgres" DB_USER
|
||||
read_input "数据库密码" "postgres" DB_PASSWORD "true"
|
||||
read_input "数据库名称" "junhong_cmp_dev" DB_NAME
|
||||
read_input "SSL 模式" "disable" DB_SSLMODE
|
||||
|
||||
# 测试数据库连接
|
||||
echo ""
|
||||
check_service "$DB_HOST" "$DB_PORT" "PostgreSQL"
|
||||
|
||||
# ========================================
|
||||
# Redis 配置
|
||||
# ========================================
|
||||
print_header "Redis 配置"
|
||||
|
||||
read_input "Redis 主机地址" "localhost" REDIS_ADDRESS
|
||||
read_input "Redis 端口" "6379" REDIS_PORT
|
||||
read_input "Redis 密码(无密码直接回车)" "" REDIS_PASSWORD "true"
|
||||
read_input "Redis 数据库编号" "0" REDIS_DB
|
||||
|
||||
# 测试 Redis 连接
|
||||
echo ""
|
||||
check_service "$REDIS_ADDRESS" "$REDIS_PORT" "Redis"
|
||||
|
||||
# ========================================
|
||||
# JWT 配置
|
||||
# ========================================
|
||||
print_header "JWT 配置"
|
||||
|
||||
DEFAULT_SECRET=$(generate_secret)
|
||||
read_input "JWT 密钥(直接回车生成随机密钥)" "$DEFAULT_SECRET" JWT_SECRET_KEY "true"
|
||||
|
||||
# ========================================
|
||||
# 服务器配置
|
||||
# ========================================
|
||||
print_header "服务器配置"
|
||||
|
||||
read_input "服务监听地址" ":3000" SERVER_ADDRESS
|
||||
read_input "日志级别 (debug/info/warn/error)" "debug" LOGGING_LEVEL
|
||||
|
||||
# ========================================
|
||||
# 可选:对象存储配置
|
||||
# ========================================
|
||||
print_header "对象存储配置(可选)"
|
||||
|
||||
echo -n "是否配置对象存储?[y/N]: "
|
||||
read configure_storage
|
||||
|
||||
if [ "$configure_storage" = "y" ] || [ "$configure_storage" = "Y" ]; then
|
||||
read_input "S3 端点" "" STORAGE_S3_ENDPOINT
|
||||
read_input "S3 区域" "" STORAGE_S3_REGION
|
||||
read_input "S3 存储桶" "" STORAGE_S3_BUCKET
|
||||
read_input "S3 Access Key ID" "" STORAGE_S3_ACCESS_KEY_ID
|
||||
read_input "S3 Secret Access Key" "" STORAGE_S3_SECRET_ACCESS_KEY "true"
|
||||
STORAGE_CONFIGURED="true"
|
||||
else
|
||||
STORAGE_CONFIGURED="false"
|
||||
fi
|
||||
|
||||
# ========================================
|
||||
# 生成配置文件
|
||||
# ========================================
|
||||
print_header "生成配置文件"
|
||||
|
||||
cat > "$ENV_FILE" << EOF
|
||||
# ============================================================================
|
||||
# 君鸿卡管系统 - 本地开发环境变量
|
||||
# 生成时间: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
# ============================================================================
|
||||
# 使用方法:
|
||||
# source .env.local && go run cmd/api/main.go
|
||||
# 或者:
|
||||
# ./scripts/run-local.sh
|
||||
# ============================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 数据库配置(必填)
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_DATABASE_HOST="$DB_HOST"
|
||||
export JUNHONG_DATABASE_PORT="$DB_PORT"
|
||||
export JUNHONG_DATABASE_USER="$DB_USER"
|
||||
export JUNHONG_DATABASE_PASSWORD="$DB_PASSWORD"
|
||||
export JUNHONG_DATABASE_DBNAME="$DB_NAME"
|
||||
export JUNHONG_DATABASE_SSLMODE="$DB_SSLMODE"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Redis 配置(必填)
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_REDIS_ADDRESS="$REDIS_ADDRESS"
|
||||
export JUNHONG_REDIS_PORT="$REDIS_PORT"
|
||||
export JUNHONG_REDIS_PASSWORD="$REDIS_PASSWORD"
|
||||
export JUNHONG_REDIS_DB="$REDIS_DB"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# JWT 配置(必填)
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_JWT_SECRET_KEY="$JWT_SECRET_KEY"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 服务器配置
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_SERVER_ADDRESS="$SERVER_ADDRESS"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 日志配置
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_LOGGING_LEVEL="$LOGGING_LEVEL"
|
||||
export JUNHONG_LOGGING_DEVELOPMENT="true"
|
||||
export JUNHONG_LOGGING_APP_LOG_FILENAME="logs/app.log"
|
||||
export JUNHONG_LOGGING_ACCESS_LOG_FILENAME="logs/access.log"
|
||||
|
||||
EOF
|
||||
|
||||
# 添加对象存储配置(如果配置了)
|
||||
if [ "$STORAGE_CONFIGURED" = "true" ]; then
|
||||
cat >> "$ENV_FILE" << EOF
|
||||
# ----------------------------------------------------------------------------
|
||||
# 对象存储配置
|
||||
# ----------------------------------------------------------------------------
|
||||
export JUNHONG_STORAGE_PROVIDER="s3"
|
||||
export JUNHONG_STORAGE_S3_ENDPOINT="$STORAGE_S3_ENDPOINT"
|
||||
export JUNHONG_STORAGE_S3_REGION="$STORAGE_S3_REGION"
|
||||
export JUNHONG_STORAGE_S3_BUCKET="$STORAGE_S3_BUCKET"
|
||||
export JUNHONG_STORAGE_S3_ACCESS_KEY_ID="$STORAGE_S3_ACCESS_KEY_ID"
|
||||
export JUNHONG_STORAGE_S3_SECRET_ACCESS_KEY="$STORAGE_S3_SECRET_ACCESS_KEY"
|
||||
export JUNHONG_STORAGE_S3_USE_SSL="false"
|
||||
export JUNHONG_STORAGE_S3_PATH_STYLE="true"
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 添加迁移工具兼容配置
|
||||
cat >> "$ENV_FILE" << EOF
|
||||
# ----------------------------------------------------------------------------
|
||||
# 迁移工具兼容配置(用于 scripts/migrate.sh)
|
||||
# ----------------------------------------------------------------------------
|
||||
export MIGRATIONS_DIR="migrations"
|
||||
export DB_HOST="$DB_HOST"
|
||||
export DB_PORT="$DB_PORT"
|
||||
export DB_USER="$DB_USER"
|
||||
export DB_PASSWORD="$DB_PASSWORD"
|
||||
export DB_NAME="$DB_NAME"
|
||||
export DB_SSLMODE="$DB_SSLMODE"
|
||||
EOF
|
||||
|
||||
print_success "配置文件已生成: $ENV_FILE"
|
||||
|
||||
# ========================================
|
||||
# 后续步骤提示
|
||||
# ========================================
|
||||
print_header "设置完成!"
|
||||
|
||||
echo -e "${GREEN}环境变量已配置完成!${NC}"
|
||||
echo ""
|
||||
echo "后续步骤:"
|
||||
echo ""
|
||||
echo " 1. 加载环境变量:"
|
||||
echo -e " ${CYAN}source .env.local${NC}"
|
||||
echo ""
|
||||
echo " 2. 运行数据库迁移(如果需要):"
|
||||
echo -e " ${CYAN}./scripts/migrate.sh up${NC}"
|
||||
echo ""
|
||||
echo " 3. 启动 API 服务:"
|
||||
echo -e " ${CYAN}go run cmd/api/main.go${NC}"
|
||||
echo ""
|
||||
echo " 4. 启动 Worker 服务(可选):"
|
||||
echo -e " ${CYAN}go run cmd/worker/main.go${NC}"
|
||||
echo ""
|
||||
echo " 或者使用快捷脚本:"
|
||||
echo -e " ${CYAN}./scripts/run-local.sh${NC}"
|
||||
echo ""
|
||||
print_warning "注意:.env.local 包含敏感信息,请勿提交到 Git!"
|
||||
|
||||
# 确保 .env.local 在 .gitignore 中
|
||||
if [ -f ".gitignore" ]; then
|
||||
if ! grep -q "^\.env\.local$" .gitignore; then
|
||||
echo ".env.local" >> .gitignore
|
||||
print_info "已将 .env.local 添加到 .gitignore"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 运行主流程
|
||||
main
|
||||
48
scripts/test_storage.go
Normal file
48
scripts/test_storage.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/config"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
fmt.Printf("加载配置失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
provider, err := storage.NewS3Provider(&cfg.Storage)
|
||||
if err != nil {
|
||||
fmt.Printf("创建 S3 Provider 失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
testContent := "iccid,msisdn\n89860012345678901234,13800000001\n89860012345678901235,13800000002\n"
|
||||
testKey := fmt.Sprintf("test/verify-%d.csv", time.Now().Unix())
|
||||
|
||||
fmt.Printf("上传文件到: %s/%s\n", cfg.Storage.S3.Bucket, testKey)
|
||||
|
||||
if err := provider.Upload(ctx, testKey, bytes.NewReader([]byte(testContent)), "text/csv"); err != nil {
|
||||
fmt.Printf("上传失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
exists, err := provider.Exists(ctx, testKey)
|
||||
if err != nil {
|
||||
fmt.Printf("检查存在失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("上传完成,文件存在: %v\n", exists)
|
||||
fmt.Printf("\n请在联通云后台检查 bucket '%s' 下的文件: %s\n", cfg.Storage.S3.Bucket, testKey)
|
||||
fmt.Println("文件未删除,请手动验证后删除")
|
||||
}
|
||||
Reference in New Issue
Block a user