Files
kami_apple_exchage/deploy/swarm-init.sh
danial 5c486e34d3 docs(项目): 添加项目文档并进行代码调整
- 新增 CODEBUDDY.md、GEMINI.md、GEMINI_CN.md 等项目文档
- 更新 Dockerfile 和其他配置文件
- 优化部分代码结构,如 orders.py、tasks.py 等
- 新增 .dockerignore 文件
2025-09-12 19:38:24 +08:00

346 lines
8.5 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Apple Gift Card Exchange Platform - Docker Swarm 初始化脚本
# 用于初始化 Docker Swarm 集群和部署应用
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 配置变量
STACK_NAME="apple-exchange"
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="${DEPLOY_DIR}/docker-compose.swarm.yml"
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 Docker 是否运行
check_docker() {
log_info "检查 Docker 运行状态..."
if ! docker info >/dev/null 2>&1; then
log_error "Docker 未运行,请启动 Docker 后重试"
exit 1
fi
log_success "Docker 运行正常"
}
# 检查 Docker Swarm 是否已初始化
check_swarm() {
log_info "检查 Docker Swarm 状态..."
if docker info | grep -q "Swarm: active"; then
log_success "Docker Swarm 已激活"
return 0
else
log_warning "Docker Swarm 未激活"
return 1
fi
}
# 初始化 Docker Swarm
init_swarm() {
log_info "初始化 Docker Swarm..."
# 获取当前主机 IP
local advertise_addr=$(ip route get 8.8.8.8 | awk '{print $7; exit}')
if docker swarm init --advertise-addr "${advertise_addr}"; then
log_success "Docker Swarm 初始化成功"
# 添加节点标签
log_info "添加节点标签..."
docker node update --label-add db=true $(docker node ls --filter role=manager -q) >/dev/null 2>&1 || true
docker node update --label-add redis=true $(docker node ls --filter role=manager -q) >/dev/null 2>&1 || true
log_success "节点标签设置完成"
else
log_error "Docker Swarm 初始化失败"
exit 1
fi
}
# 创建必要的配置文件
create_configs() {
log_info "创建 Docker 配置..."
# 创建 redis.conf
cat > "${DEPLOY_DIR}/redis.conf" << 'EOF'
# Redis 配置文件
bind 0.0.0.0
port 6379
protected-mode no
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-ping-replica-period 10
repl-timeout 60
repl-disable-tcp-nodelay no
repl-backlog-size 1mb
repl-backlog-ttl 3600
replica-priority 100
maxmemory-policy allkeys-lru
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
EOF
# 创建 postgresql.conf
cat > "${DEPLOY_DIR}/postgresql.conf" << 'EOF'
# PostgreSQL 配置文件
listen_addresses = '*'
port = 5432
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 4MB
min_wal_size = 1GB
max_wal_size = 4GB
max_worker_processes = 4
max_parallel_workers_per_gather = 2
max_parallel_workers = 4
max_parallel_maintenance_workers = 2
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_timezone = 'UTC'
datestyle = 'iso, mdy'
timezone = 'UTC'
default_text_search_config = 'pg_catalog.english'
EOF
# 创建 .env 文件模板
cat > "${DEPLOY_DIR}/.env.template" << 'EOF'
# 环境变量配置
POSTGRES_PASSWORD=your_secure_password_here
LETSENCRYPT_EMAIL=your_email@example.com
FLOWER_AUTH=admin:$(openssl passwd -crypt admin)
EOF
log_success "配置文件创建完成"
}
# 构建镜像
build_images() {
log_info "构建 Docker 镜像..."
# 构建前端镜像
if [ -d "../frontend" ]; then
log_info "构建前端镜像..."
docker build -t apple-exchange-frontend:latest ../frontend || {
log_error "前端镜像构建失败"
exit 1
}
log_success "前端镜像构建完成"
fi
# 构建后端镜像
if [ -d "../backend" ]; then
log_info "构建后端镜像..."
docker build -t apple-exchange-api:latest ../backend || {
log_error "后端镜像构建失败"
exit 1
}
# 构建 Worker 镜像
if [ -f "../backend/Dockerfile.worker" ]; then
docker build -f ../backend/Dockerfile.worker -t apple-exchange-worker:latest ../backend || {
log_error "Worker 镜像构建失败"
exit 1
}
else
# 如果没有专门的 Dockerfile.worker使用 API 镜像
docker tag apple-exchange-api:latest apple-exchange-worker:latest
fi
log_success "后端镜像构建完成"
fi
}
# 部署 Stack
deploy_stack() {
log_info "部署 Docker Stack: ${STACK_NAME}"
# 检查环境变量文件
if [ ! -f "${DEPLOY_DIR}/.env" ]; then
log_warning "环境变量文件 .env 不存在,使用模板创建"
cp "${DEPLOY_DIR}/.env.template" "${DEPLOY_DIR}/.env"
log_warning "请编辑 .env 文件设置正确的环境变量"
exit 1
fi
# 部署 Stack
if docker stack deploy -c "${COMPOSE_FILE}" "${STACK_NAME}"; then
log_success "Stack 部署成功"
else
log_error "Stack 部署失败"
exit 1
fi
}
# 显示部署状态
show_status() {
log_info "部署状态:"
echo "----------------------------------------"
docker stack services "${STACK_NAME}"
echo "----------------------------------------"
log_info "查看服务状态:"
echo " docker stack services ${STACK_NAME}"
echo " docker service ps ${STACK_NAME}_frontend"
echo " docker service ps ${STACK_NAME}_api"
echo " docker service ps ${STACK_NAME}_worker"
echo " docker service ps ${STACK_NAME}_db"
echo " docker service ps ${STACK_NAME}_redis"
log_info "查看日志:"
echo " docker service logs ${STACK_NAME}_frontend"
echo " docker service logs ${STACK_NAME}_api"
echo " docker service logs ${STACK_NAME}_worker"
log_info "访问地址:"
echo " 应用: https://apple-exchange.com"
echo " API: https://api.apple-exchange.com"
echo " Flower 监控: https://flower.apple-exchange.com"
echo " Traefik Dashboard: https://traefik.apple-exchange.com"
}
# 主函数
main() {
log_info "开始 Docker Swarm 部署..."
# 检查必要的文件
if [ ! -f "${COMPOSE_FILE}" ]; then
log_error "Docker Compose 文件不存在: ${COMPOSE_FILE}"
exit 1
fi
# 检查 Docker
check_docker
# 检查 Swarm
if ! check_swarm; then
init_swarm
fi
# 创建配置文件
create_configs
# 构建镜像
build_images
# 部署 Stack
deploy_stack
# 显示状态
show_status
log_success "Docker Swarm 部署完成!"
}
# 脚本选项
case "${1:-}" in
"init")
check_docker
if ! check_swarm; then
init_swarm
fi
;;
"build")
build_images
;;
"deploy")
deploy_stack
;;
"status")
show_status
;;
"remove")
log_info "移除 Stack: ${STACK_NAME}"
docker stack rm "${STACK_NAME}"
;;
"logs")
shift
if [ $# -eq 0 ]; then
docker service logs "${STACK_NAME}_api"
else
docker service logs "${STACK_NAME}_${1}"
fi
;;
*)
main
;;
esac