feat: 部署diocker到服务器上
This commit is contained in:
parent
656c8fefac
commit
6f51cead6c
@ -13,10 +13,14 @@ JWT_SECRET=CHANGE_ME_TO_A_VERY_LONG_RANDOM_STRING
|
|||||||
|
|
||||||
# OSS Configuration
|
# OSS Configuration
|
||||||
OSS_REGION=cn-shanghai
|
OSS_REGION=cn-shanghai
|
||||||
OSS_BUCKET_NAME=top-fans-prod
|
OSS_BUCKET_NAME=top-fans-test
|
||||||
OSS_STS_ROLE_ARN=acs:ram::1387642798143585:role/top-fans-oss-user
|
OSS_STS_ROLE_ARN=acs:ram::1387642798143585:role/top-fans-oss-user
|
||||||
OSS_ACCESS_KEY_ID=LTAI5t6QcdJHpYbCPxM8SXYE
|
OSS_ACCESS_KEY_ID=LTAI5t99tafzfyrzbbEbjryH
|
||||||
OSS_ACCESS_KEY_SECRET=ybvjSEb7wilMt3qT5nOppYPoNVayCD
|
OSS_ACCESS_KEY_SECRET=sBmrqG9owzi53hiV4dpE3EL2A5dn9b
|
||||||
OSS_AVATAR_DIR=avatar/
|
OSS_AVATAR_DIR=avatar/
|
||||||
OSS_ASSET_DIR=asset/
|
OSS_ASSET_DIR=asset/
|
||||||
OSS_TOKEN_EXPIRE_TIME=3600
|
OSS_TOKEN_EXPIRE_TIME=3600
|
||||||
|
|
||||||
|
# ==================== MiniMax API Configuration ====================
|
||||||
|
MINIMAX_API_KEY=sk-cp-Fffv8Bg8zeFD929_KUAZq9EKet64Nkxgu7t1ibZEngqmyPKaOOa7U8U_gtg3VICfUQyGPn8c5XR4hxmWzjKC4wO6DxKh5ipN36Yv5jsFzZWMEPh6NKV2qAE
|
||||||
|
MINIMAX_API_URL=https://api.minimaxi.com/v1/image_generation
|
||||||
|
|||||||
204
docker/deploy.sh
204
docker/deploy.sh
@ -5,28 +5,50 @@
|
|||||||
# - 本地:构建镜像 → 推送到镜像仓库
|
# - 本地:构建镜像 → 推送到镜像仓库
|
||||||
# - 远程:拉取镜像 → 启动服务
|
# - 远程:拉取镜像 → 启动服务
|
||||||
# - 回滚:回滚到指定版本
|
# - 回滚:回滚到指定版本
|
||||||
|
# - 配置:快速上传配置文件、重启服务
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
#
|
#
|
||||||
# 使用前提:
|
# 使用前提:
|
||||||
# 1. 已安装 Docker
|
# 1. 已安装 Docker
|
||||||
# 2. 已创建阿里云容器镜像仓库
|
# 2. 已创建阿里云容器镜像仓库
|
||||||
# 3. 服务器已配置 SSH 免密登录(建议)
|
# 3. 服务器已配置 SSH 免密登录
|
||||||
#
|
#
|
||||||
# 使用方式:
|
# 使用方式:
|
||||||
# # 本地构建 + 推送
|
# # ========== 完整部署流程 ==========
|
||||||
|
# # 本地构建镜像
|
||||||
# ./deploy.sh build v1.0.0
|
# ./deploy.sh build v1.0.0
|
||||||
#
|
#
|
||||||
# # 远程部署(从仓库拉取 + 启动)
|
# # 上传镜像到服务器(会自动跳过未变化的镜像)
|
||||||
|
# ./deploy.sh push v1.0.0
|
||||||
|
#
|
||||||
|
# # 远程部署
|
||||||
# ./deploy.sh deploy v1.0.0
|
# ./deploy.sh deploy v1.0.0
|
||||||
#
|
#
|
||||||
|
# # 一键构建 + 推送 + 部署
|
||||||
|
# ./deploy.sh all v1.0.0
|
||||||
|
#
|
||||||
|
# # ========== 配置更新(不重新构建镜像)==========
|
||||||
|
# # 修改 .env.prod 或 docker-compose.prod.yml 后:
|
||||||
|
# ./deploy.sh upload-config --server 101.132.250.62
|
||||||
|
#
|
||||||
|
# # 上传配置并重启服务
|
||||||
|
# ./deploy.sh upload-config --server 101.132.250.62 && ./deploy.sh restart --server 101.132.250.62
|
||||||
|
#
|
||||||
|
# # ========== 其他命令 ==========
|
||||||
# # 回滚到指定版本
|
# # 回滚到指定版本
|
||||||
# ./deploy.sh rollback v1.0.0
|
# ./deploy.sh rollback v0.9.0
|
||||||
#
|
#
|
||||||
# # 查看部署历史
|
# # 查看部署历史
|
||||||
# ./deploy.sh history
|
# ./deploy.sh history
|
||||||
#
|
#
|
||||||
# # 一键构建 + 推送 + 部署(本地构建完成后远程部署)
|
# # 清理本地镜像
|
||||||
# ./deploy.sh all v1.0.0
|
# ./deploy.sh clean
|
||||||
|
#
|
||||||
|
# # ========== 服务器信息 ==========
|
||||||
|
# SERVER_HOST="101.132.250.62"
|
||||||
|
# SERVER_USER="root"
|
||||||
|
# SERVER_PASSWORD=">n73qBnCja-,#VF+Wq"
|
||||||
|
# SERVER_PATH="/opt/topfans/docker"
|
||||||
#
|
#
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
|
|
||||||
@ -61,8 +83,21 @@ SERVICES=(
|
|||||||
SERVER_HOST="101.132.250.62" # 服务器 IP 或域名
|
SERVER_HOST="101.132.250.62" # 服务器 IP 或域名
|
||||||
SERVER_PORT="22" # SSH 端口
|
SERVER_PORT="22" # SSH 端口
|
||||||
SERVER_USER="root" # SSH 用户名
|
SERVER_USER="root" # SSH 用户名
|
||||||
|
SERVER_PASSWORD=">n73qBnCja-,#VF+Wq" # 服务器密码
|
||||||
SERVER_PATH="/opt/topfans/docker" # 服务器上 docker 目录路径
|
SERVER_PATH="/opt/topfans/docker" # 服务器上 docker 目录路径
|
||||||
|
|
||||||
|
# ==================== SSH 别名 ====================
|
||||||
|
# 使用 sshpass 执行 SSH 命令
|
||||||
|
ssh_cmd() {
|
||||||
|
sshpass -p "$SERVER_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$SERVER_PORT" "$SERVER_USER@$SERVER_HOST" "$@"
|
||||||
|
}
|
||||||
|
ssh_cmd_batch() {
|
||||||
|
sshpass -p "$SERVER_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$SERVER_PORT" "$SERVER_USER@$SERVER_HOST" "$@"
|
||||||
|
}
|
||||||
|
scp_cmd() {
|
||||||
|
sshpass -p "$SERVER_PASSWORD" scp -P "$SERVER_PORT" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
# ==================== 打印函数 ====================
|
# ==================== 打印函数 ====================
|
||||||
print_step() {
|
print_step() {
|
||||||
echo ""
|
echo ""
|
||||||
@ -92,6 +127,8 @@ ${YELLOW}命令:${NC}
|
|||||||
${GREEN}history${NC} 查看部署历史
|
${GREEN}history${NC} 查看部署历史
|
||||||
${GREEN}all${NC} <版本号> 一键构建 + 传输 + 部署
|
${GREEN}all${NC} <版本号> 一键构建 + 传输 + 部署
|
||||||
${GREEN}clean${NC} 清理本地镜像(谨慎使用)
|
${GREEN}clean${NC} 清理本地镜像(谨慎使用)
|
||||||
|
${GREEN}upload-config${NC} 仅上传配置文件(不重新构建镜像)
|
||||||
|
${GREEN}restart${NC} 重启服务(不重新构建/上传)
|
||||||
|
|
||||||
${YELLOW}选项:${NC}
|
${YELLOW}选项:${NC}
|
||||||
--server <IP> 指定服务器(覆盖配置文件)
|
--server <IP> 指定服务器(覆盖配置文件)
|
||||||
@ -106,6 +143,8 @@ ${YELLOW}示例:${NC}
|
|||||||
$0 rollback v0.9.0 # 回滚到 v0.9.0
|
$0 rollback v0.9.0 # 回滚到 v0.9.0
|
||||||
$0 history # 查看部署历史
|
$0 history # 查看部署历史
|
||||||
$0 all v1.0.0 --server 192.168.1.100 # 一键完成所有操作
|
$0 all v1.0.0 --server 192.168.1.100 # 一键完成所有操作
|
||||||
|
$0 upload-config --server 192.168.1.100 # 仅上传配置
|
||||||
|
$0 restart --server 192.168.1.100 # 重启服务
|
||||||
|
|
||||||
${YELLOW}前提准备:${NC}
|
${YELLOW}前提准备:${NC}
|
||||||
1. 修改 SERVER_HOST 为你的服务器 IP
|
1. 修改 SERVER_HOST 为你的服务器 IP
|
||||||
@ -182,21 +221,52 @@ do_push() {
|
|||||||
|
|
||||||
print_msg "$GREEN" "✅ 全部打包完成"
|
print_msg "$GREEN" "✅ 全部打包完成"
|
||||||
|
|
||||||
|
# 计算本地镜像的 MD5 哈希
|
||||||
|
print_step "🔍 检查镜像差异"
|
||||||
|
local local_hash=""
|
||||||
|
for SERVICE in "${packed[@]}"; do
|
||||||
|
local tar_file="${tmp_dir}/${SERVICE}.tar"
|
||||||
|
local file_hash=$(md5 -q "${tar_file}")
|
||||||
|
local image_hash=$(docker images -q "topfans/${SERVICE}:latest")
|
||||||
|
local combo="${file_hash}:${image_hash}"
|
||||||
|
if [ -z "$local_hash" ]; then
|
||||||
|
local_hash="$combo"
|
||||||
|
else
|
||||||
|
local_hash="${local_hash}-${combo}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local local_md5=$(echo "$local_hash" | md5)
|
||||||
|
|
||||||
|
print_msg "$YELLOW" "本地镜像 MD5: ${local_md5:0:16}..."
|
||||||
|
|
||||||
|
# 获取服务器上的哈希
|
||||||
|
local server_hash=$(ssh_cmd "cat ${SERVER_PATH}/images/.images_hash 2>/dev/null || echo ''")
|
||||||
|
|
||||||
print_step "📤 传输镜像到服务器"
|
print_step "📤 传输镜像到服务器"
|
||||||
|
|
||||||
|
# 检查是否需要上传
|
||||||
|
if [ "$local_md5" = "$server_hash" ]; then
|
||||||
|
print_msg "$GREEN" "✅ 镜像未变化,跳过上传"
|
||||||
|
rm -rf "${tmp_dir}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
print_msg "$YELLOW" "正在传输到 ${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}..."
|
print_msg "$YELLOW" "正在传输到 ${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}..."
|
||||||
|
|
||||||
# 创建服务器目录
|
# 创建服务器目录
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "mkdir -p ${SERVER_PATH}/images && rm -f ${SERVER_PATH}/images/*.tar 2>/dev/null || true"
|
ssh_cmd "mkdir -p ${SERVER_PATH}/images && rm -f ${SERVER_PATH}/images/*.tar 2>/dev/null || true"
|
||||||
|
|
||||||
# 传输 tar 文件
|
# 传输 tar 文件
|
||||||
for SERVICE in "${packed[@]}"; do
|
for SERVICE in "${packed[@]}"; do
|
||||||
local tar_file="${tmp_dir}/${SERVICE}.tar"
|
local tar_file="${tmp_dir}/${SERVICE}.tar"
|
||||||
print_msg "$YELLOW" "传输 ${SERVICE}.tar..."
|
print_msg "$YELLOW" "传输 ${SERVICE}.tar..."
|
||||||
scp -P "${SERVER_PORT}" "${tar_file}" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/images/"
|
scp_cmd "${tar_file}" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/images/"
|
||||||
print_msg "$GREEN" "✅ ${SERVICE}.tar 传输完成"
|
print_msg "$GREEN" "✅ ${SERVICE}.tar 传输完成"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# 保存哈希到服务器
|
||||||
|
ssh_cmd "echo '$local_md5' > ${SERVER_PATH}/images/.images_hash"
|
||||||
|
|
||||||
# 清理本地临时文件
|
# 清理本地临时文件
|
||||||
rm -rf "${tmp_dir}"
|
rm -rf "${tmp_dir}"
|
||||||
|
|
||||||
@ -217,40 +287,72 @@ do_deploy() {
|
|||||||
|
|
||||||
print_msg "$YELLOW" "检查 Docker 环境..."
|
print_msg "$YELLOW" "检查 Docker 环境..."
|
||||||
|
|
||||||
ssh -p "${SERVER_PORT}" -T "${SERVER_USER}@${SERVER_HOST}" << 'ENDSSH'
|
sshpass -p "$SERVER_PASSWORD" ssh -T -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" << 'ENDSSH'
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo '=== 1. 检查 Docker 环境 ==='
|
echo '=== 1. 检查/安装 Docker 环境 ==='
|
||||||
if ! command -v docker &> /dev/null; then
|
if ! command -v docker &> /dev/null; then
|
||||||
echo '❌ Docker 未安装'
|
echo '📦 Docker 未安装,开始安装...'
|
||||||
exit 1
|
|
||||||
|
# 使用阿里云镜像源安装 Docker
|
||||||
|
yum remove -y docker docker-common docker-selinux docker-engine-selinux docker-engine docker-ce 2>/dev/null || true
|
||||||
|
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
|
||||||
|
yum install -y docker-ce docker-ce-cli containerd.io
|
||||||
|
|
||||||
|
systemctl start docker
|
||||||
|
systemctl enable docker
|
||||||
|
echo '✅ Docker 安装成功'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
if ! command -v docker-compose &> /dev/null; then
|
||||||
echo '❌ docker-compose 未安装'
|
if docker compose version &> /dev/null; then
|
||||||
exit 1
|
echo '📦 创建 docker-compose 软链接...'
|
||||||
|
ln -sf /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose
|
||||||
|
else
|
||||||
|
echo '⚠️ docker-compose 未安装'
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 配置 Docker 镜像加速器
|
||||||
|
echo '📦 配置 Docker 镜像加速器...'
|
||||||
|
mkdir -p /etc/docker
|
||||||
|
cat > /etc/docker/daemon.json << 'DOCKER_EOF'
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"https://docker.1ms.run",
|
||||||
|
"https://docker.xuanyuan.me"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
DOCKER_EOF
|
||||||
|
systemctl restart docker
|
||||||
|
echo '✅ 镜像加速器配置完成'
|
||||||
|
|
||||||
echo '✅ Docker 环境就绪'
|
echo '✅ Docker 环境就绪'
|
||||||
ENDSSH
|
ENDSSH
|
||||||
|
|
||||||
# 确保服务器目录存在
|
# 确保服务器目录存在
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "mkdir -p ${SERVER_PATH}/images"
|
ssh_cmd "mkdir -p ${SERVER_PATH}/images"
|
||||||
print_msg "$GREEN" "✅ 服务器目录就绪"
|
print_msg "$GREEN" "✅ 服务器目录就绪"
|
||||||
|
|
||||||
|
# 上传配置文件
|
||||||
|
print_step "📤 上传配置文件"
|
||||||
|
print_msg "$YELLOW" "上传 docker-compose.prod.yml 和 .env.prod..."
|
||||||
|
scp_cmd "${SCRIPT_DIR}/docker-compose.prod.yml" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
scp_cmd "${SCRIPT_DIR}/.env.prod" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
scp_cmd "${SCRIPT_DIR}/init-db.sql" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
print_msg "$GREEN" "✅ 配置文件上传完成"
|
||||||
|
|
||||||
# 从 tar 文件加载镜像
|
# 从 tar 文件加载镜像
|
||||||
print_step "📥 从 tar 文件加载镜像"
|
print_step "📥 从 tar 文件加载镜像"
|
||||||
for SERVICE in "${SERVICES[@]}"; do
|
for SERVICE in "${SERVICES[@]}"; do
|
||||||
print_msg "$YELLOW" "加载 ${SERVICE}..."
|
print_msg "$YELLOW" "加载 ${SERVICE}..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "docker load -i ${SERVER_PATH}/images/${SERVICE}.tar"
|
||||||
docker load -i ${SERVER_PATH}/images/${SERVICE}.tar
|
|
||||||
"
|
|
||||||
print_msg "$GREEN" "✅ ${SERVICE} 加载完成"
|
print_msg "$GREEN" "✅ ${SERVICE} 加载完成"
|
||||||
done
|
done
|
||||||
|
|
||||||
# 打 latest 标签
|
# 打 latest 标签
|
||||||
print_msg "$YELLOW" "打 latest 标签..."
|
print_msg "$YELLOW" "打 latest 标签..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
for service in ${SERVICES[*]}; do
|
for service in ${SERVICES[*]}; do
|
||||||
docker tag topfans/\${service}:latest topfans/\${service}:v${version}
|
docker tag topfans/\${service}:latest topfans/\${service}:v${version}
|
||||||
docker tag topfans/\${service}:latest topfans/\${service}:latest
|
docker tag topfans/\${service}:latest topfans/\${service}:latest
|
||||||
@ -258,27 +360,35 @@ ENDSSH
|
|||||||
echo '标签完成'
|
echo '标签完成'
|
||||||
"
|
"
|
||||||
|
|
||||||
# 停止旧服务
|
# 停止旧服务并清理
|
||||||
print_msg "$YELLOW" "停止旧服务..."
|
print_msg "$YELLOW" "停止旧服务..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
cd ${SERVER_PATH} && \
|
cd ${SERVER_PATH} && \
|
||||||
docker-compose -f docker-compose.prod.yml down 2>/dev/null || true
|
docker-compose -f docker-compose.prod.yml down 2>/dev/null || true
|
||||||
|
|
||||||
|
# 停止并删除所有 topfans 容器
|
||||||
|
docker ps -a --filter 'name=topfans-' -q | xargs -r docker stop 2>/dev/null || true
|
||||||
|
docker ps -a --filter 'name=topfans-' -q | xargs -r docker rm 2>/dev/null || true
|
||||||
|
|
||||||
|
# 清理可能的端口占用 (8080, 5432)
|
||||||
|
fuser -k 8080/tcp 2>/dev/null || true
|
||||||
|
fuser -k 5432/tcp 2>/dev/null || true
|
||||||
"
|
"
|
||||||
|
|
||||||
# 启动新服务
|
# 启动新服务
|
||||||
print_msg "$YELLOW" "启动服务..."
|
print_msg "$YELLOW" "启动服务..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
cd ${SERVER_PATH} && \
|
cd ${SERVER_PATH} && \
|
||||||
docker-compose -f docker-compose.prod.yml --profile prod up -d
|
docker-compose -f docker-compose.prod.yml --profile prod up -d
|
||||||
"
|
"
|
||||||
|
|
||||||
# 等待并检查
|
# 等待并检查
|
||||||
print_msg "$YELLOW" "等待服务启动 (15s)..."
|
print_msg "$YELLOW" "等待服务启动 (20s)..."
|
||||||
sleep 15
|
sleep 20
|
||||||
|
|
||||||
print_step "📊 部署结果"
|
print_step "📊 部署结果"
|
||||||
|
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
echo ''
|
echo ''
|
||||||
docker-compose -f docker-compose.prod.yml ps
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
echo ''
|
echo ''
|
||||||
@ -304,7 +414,7 @@ do_rollback() {
|
|||||||
|
|
||||||
# 停止服务
|
# 停止服务
|
||||||
print_msg "$YELLOW" "停止服务..."
|
print_msg "$YELLOW" "停止服务..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
cd ${SERVER_PATH} && \
|
cd ${SERVER_PATH} && \
|
||||||
docker-compose -f docker-compose.prod.yml down
|
docker-compose -f docker-compose.prod.yml down
|
||||||
"
|
"
|
||||||
@ -312,7 +422,7 @@ do_rollback() {
|
|||||||
# 从已有的 tar 文件加载镜像并打标签
|
# 从已有的 tar 文件加载镜像并打标签
|
||||||
for SERVICE in "${SERVICES[@]}"; do
|
for SERVICE in "${SERVICES[@]}"; do
|
||||||
print_msg "$YELLOW" "加载 ${SERVICE}:v${version}..."
|
print_msg "$YELLOW" "加载 ${SERVICE}:v${version}..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
docker load -i ${SERVER_PATH}/images/${SERVICE}.tar
|
docker load -i ${SERVER_PATH}/images/${SERVICE}.tar
|
||||||
docker tag topfans/${SERVICE}:latest topfans/${SERVICE}:v${version}
|
docker tag topfans/${SERVICE}:latest topfans/${SERVICE}:v${version}
|
||||||
docker tag topfans/${SERVICE}:latest topfans/${SERVICE}:latest
|
docker tag topfans/${SERVICE}:latest topfans/${SERVICE}:latest
|
||||||
@ -322,7 +432,7 @@ do_rollback() {
|
|||||||
|
|
||||||
# 启动服务
|
# 启动服务
|
||||||
print_msg "$YELLOW" "启动服务..."
|
print_msg "$YELLOW" "启动服务..."
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
cd ${SERVER_PATH} && \
|
cd ${SERVER_PATH} && \
|
||||||
docker-compose -f docker-compose.prod.yml --profile prod up -d
|
docker-compose -f docker-compose.prod.yml --profile prod up -d
|
||||||
"
|
"
|
||||||
@ -331,7 +441,7 @@ do_rollback() {
|
|||||||
|
|
||||||
print_step "📊 回滚结果"
|
print_step "📊 回滚结果"
|
||||||
|
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
echo ''
|
echo ''
|
||||||
docker-compose -f docker-compose.prod.yml ps
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
echo ''
|
echo ''
|
||||||
@ -351,7 +461,7 @@ do_history() {
|
|||||||
|
|
||||||
print_step "📜 部署历史"
|
print_step "📜 部署历史"
|
||||||
|
|
||||||
ssh -p "${SERVER_PORT}" "${SERVER_USER}@${SERVER_HOST}" "
|
ssh_cmd "
|
||||||
if [ -f ${SERVER_PATH}/deploy_history.json ]; then
|
if [ -f ${SERVER_PATH}/deploy_history.json ]; then
|
||||||
cat ${SERVER_PATH}/deploy_history.json
|
cat ${SERVER_PATH}/deploy_history.json
|
||||||
else
|
else
|
||||||
@ -492,6 +602,38 @@ main() {
|
|||||||
do_clean
|
do_clean
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
upload-config)
|
||||||
|
# 上传配置文件
|
||||||
|
if [ -z "$SERVER_HOST" ]; then
|
||||||
|
print_msg "$RED" "错误: 请设置 SERVER_HOST 或使用 --server 参数"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_step "📤 上传配置文件到 ${SERVER_HOST}"
|
||||||
|
|
||||||
|
scp_cmd "${SCRIPT_DIR}/docker-compose.prod.yml" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
print_msg "$GREEN" "✅ docker-compose.prod.yml 上传完成"
|
||||||
|
|
||||||
|
scp_cmd "${SCRIPT_DIR}/.env.prod" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
print_msg "$GREEN" "✅ .env.prod 上传完成"
|
||||||
|
|
||||||
|
print_msg "$YELLOW" "请运行以下命令重启服务:"
|
||||||
|
print_msg "$CYAN" "ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${SERVER_PATH} && docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d'"
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
# 重启服务
|
||||||
|
if [ -z "$SERVER_HOST" ]; then
|
||||||
|
print_msg "$RED" "错误: 请设置 SERVER_HOST 或使用 --server 参数"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_step "🔄 重启服务"
|
||||||
|
ssh_cmd "cd ${SERVER_PATH} && docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d"
|
||||||
|
sleep 10
|
||||||
|
print_msg "$GREEN" "✅ 服务重启完成"
|
||||||
|
;;
|
||||||
|
|
||||||
all)
|
all)
|
||||||
# 构建 + 推送 + 部署
|
# 构建 + 推送 + 部署
|
||||||
if [ -z "$version" ]; then
|
if [ -z "$version" ]; then
|
||||||
|
|||||||
@ -29,10 +29,10 @@ x-postgres-env: &postgres-env
|
|||||||
POSTGRES_WAL_BUFFERS: 8MB
|
POSTGRES_WAL_BUFFERS: 8MB
|
||||||
|
|
||||||
x-healthcheck: &healthcheck
|
x-healthcheck: &healthcheck
|
||||||
interval: 15s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 5
|
||||||
start_period: 30s
|
start_period: 60s
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ==================== Database ====================
|
# ==================== Database ====================
|
||||||
@ -78,7 +78,7 @@ services:
|
|||||||
DB_NAME: topfans
|
DB_NAME: topfans
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
expose:
|
expose:
|
||||||
@ -111,7 +111,7 @@ services:
|
|||||||
DB_USER: postgres
|
DB_USER: postgres
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
||||||
DB_NAME: topfans
|
DB_NAME: topfans
|
||||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
USER_SERVICE_URL: tri://userservice:20000
|
||||||
OSS_REGION: ${OSS_REGION:-cn-shanghai}
|
OSS_REGION: ${OSS_REGION:-cn-shanghai}
|
||||||
OSS_BUCKET_NAME: ${OSS_BUCKET_NAME:-top-fans-test}
|
OSS_BUCKET_NAME: ${OSS_BUCKET_NAME:-top-fans-test}
|
||||||
OSS_STS_ROLE_ARN: ${OSS_STS_ROLE_ARN:-acs:ram::1387642798143585:role/top-fans-oss-user}
|
OSS_STS_ROLE_ARN: ${OSS_STS_ROLE_ARN:-acs:ram::1387642798143585:role/top-fans-oss-user}
|
||||||
@ -122,7 +122,7 @@ services:
|
|||||||
OSS_TOKEN_EXPIRE_TIME: ${OSS_TOKEN_EXPIRE_TIME:-3600}
|
OSS_TOKEN_EXPIRE_TIME: ${OSS_TOKEN_EXPIRE_TIME:-3600}
|
||||||
depends_on:
|
depends_on:
|
||||||
userservice:
|
userservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
expose:
|
expose:
|
||||||
@ -155,13 +155,13 @@ services:
|
|||||||
DB_USER: postgres
|
DB_USER: postgres
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
||||||
DB_NAME: topfans
|
DB_NAME: topfans
|
||||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
USER_SERVICE_URL: tri://userservice:20000
|
||||||
DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003
|
ASSET_SERVICE_URL: tri://assetservice:20003
|
||||||
depends_on:
|
depends_on:
|
||||||
userservice:
|
userservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
assetservice:
|
assetservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
expose:
|
expose:
|
||||||
@ -194,13 +194,13 @@ services:
|
|||||||
DB_USER: postgres
|
DB_USER: postgres
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
||||||
DB_NAME: topfans
|
DB_NAME: topfans
|
||||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
USER_SERVICE_URL: tri://userservice:20000
|
||||||
DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003
|
ASSET_SERVICE_URL: tri://assetservice:20003
|
||||||
depends_on:
|
depends_on:
|
||||||
userservice:
|
userservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
assetservice:
|
assetservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
expose:
|
expose:
|
||||||
@ -233,10 +233,10 @@ services:
|
|||||||
DB_USER: postgres
|
DB_USER: postgres
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
||||||
DB_NAME: topfans
|
DB_NAME: topfans
|
||||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
USER_SERVICE_URL: tri://userservice:20000
|
||||||
depends_on:
|
depends_on:
|
||||||
userservice:
|
userservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
expose:
|
expose:
|
||||||
@ -262,6 +262,8 @@ services:
|
|||||||
target: gateway
|
target: gateway
|
||||||
container_name: topfans-gateway
|
container_name: topfans-gateway
|
||||||
restart: always
|
restart: always
|
||||||
|
env_file:
|
||||||
|
- .env.prod
|
||||||
environment:
|
environment:
|
||||||
<<: *common-env
|
<<: *common-env
|
||||||
SERVER_PORT: 8080
|
SERVER_PORT: 8080
|
||||||
@ -273,15 +275,15 @@ services:
|
|||||||
DUBBO_ACTIVITY_SERVICE_URL: tri://activityservice:20005
|
DUBBO_ACTIVITY_SERVICE_URL: tri://activityservice:20005
|
||||||
depends_on:
|
depends_on:
|
||||||
userservice:
|
userservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
assetservice:
|
assetservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
socialservice:
|
socialservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
galleryservice:
|
galleryservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
activityservice:
|
activityservice:
|
||||||
condition: service_healthy
|
condition: service_started
|
||||||
networks:
|
networks:
|
||||||
- topfans-net
|
- topfans-net
|
||||||
ports:
|
ports:
|
||||||
@ -298,40 +300,6 @@ services:
|
|||||||
memory: 64M
|
memory: 64M
|
||||||
cpus: '0.25'
|
cpus: '0.25'
|
||||||
|
|
||||||
# ==================== Admin Backend ====================
|
|
||||||
admin-backend:
|
|
||||||
image: topfans/admin-backend:latest
|
|
||||||
build:
|
|
||||||
context: ../../TopFans-activity
|
|
||||||
dockerfile: docker/Dockerfile.admin
|
|
||||||
container_name: topfans-admin-backend
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
<<: *common-env
|
|
||||||
DB_HOST: postgres
|
|
||||||
DB_PORT: 5432
|
|
||||||
DB_USER: postgres
|
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
|
|
||||||
DB_NAME: topfans
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
|
||||||
- topfans-net
|
|
||||||
ports:
|
|
||||||
- "8081:8081"
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8081/health || exit 1"]
|
|
||||||
<<: *healthcheck
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 200M
|
|
||||||
cpus: '0.5'
|
|
||||||
reservations:
|
|
||||||
memory: 64M
|
|
||||||
cpus: '0.25'
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
topfans-net:
|
topfans-net:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
2026
docker/init-db.sql
2026
docker/init-db.sql
File diff suppressed because it is too large
Load Diff
73
docker/快速配置更新指南.md
Normal file
73
docker/快速配置更新指南.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# 快速配置更新指南
|
||||||
|
|
||||||
|
## 场景:只修改了配置,不想重新推送镜像
|
||||||
|
|
||||||
|
### 1. 更新配置文件到服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/liulujian/Documents/code/TopFansByGithub/docker
|
||||||
|
|
||||||
|
# 上传 .env.prod
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' scp -P 22 .env.prod root@101.132.250.62:/opt/topfans/docker/
|
||||||
|
|
||||||
|
# 上传 docker-compose.prod.yml(如果也修改了)
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' scp -P 22 docker-compose.prod.yml root@101.132.250.62:/opt/topfans/docker/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 重启服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' ssh -o StrictHostKeyChecking=no -p 22 root@101.132.250.62 '
|
||||||
|
cd /opt/topfans/docker
|
||||||
|
docker-compose -f docker-compose.prod.yml down
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 验证服务状态
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' ssh -o StrictHostKeyChecking=no -p 22 root@101.132.250.62 "curl -s http://localhost:8080/health"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 添加 upload-config 命令到 deploy.sh
|
||||||
|
|
||||||
|
如果你想让 deploy.sh 支持直接上传配置,可以添加以下命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在 deploy.sh 的 main 函数中添加:
|
||||||
|
upload-config)
|
||||||
|
print_step "📤 上传配置文件到服务器"
|
||||||
|
scp_cmd "${SCRIPT_DIR}/docker-compose.prod.yml" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
scp_cmd "${SCRIPT_DIR}/.env.prod" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
|
||||||
|
print_msg "$GREEN" "✅ 配置文件上传完成"
|
||||||
|
print_msg "$YELLOW" "请手动重启服务: docker-compose -f docker-compose.prod.yml down && up -d"
|
||||||
|
;;
|
||||||
|
```
|
||||||
|
|
||||||
|
然后使用方式:
|
||||||
|
```bash
|
||||||
|
./deploy.sh upload-config --server 101.132.250.62
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **不需要重新 build 镜像** - 配置修改不需要重新构建 Docker 镜像
|
||||||
|
2. **env_file 优先级** - docker-compose 中 `env_file: .env.prod` 会覆盖 `environment` 中的变量
|
||||||
|
3. **敏感信息** - `.env.prod` 包含敏感信息,请勿提交到 Git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看服务状态
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' ssh -o StrictHostKeyChecking=no -p 22 root@101.132.250.62 "docker ps --format 'table {{.Names}}\t{{.Status}}'"
|
||||||
|
|
||||||
|
# 查看环境变量是否生效
|
||||||
|
sshpass -p '>n73qBnCja-,#VF+Wq' ssh -o StrictHostKeyChecking=no -p 22 root@101.132.250.62 "docker exec topfans-gateway env | grep OSS"
|
||||||
|
```
|
||||||
@ -955,8 +955,9 @@ const handleCabinClick = (cabin) => {
|
|||||||
if (Math.abs(velocity) > 0.5) return;
|
if (Math.abs(velocity) > 0.5) return;
|
||||||
// 无用户、或被 banner 遮住(showNickname=false)的小屋不响应点击
|
// 无用户、或被 banner 遮住(showNickname=false)的小屋不响应点击
|
||||||
if (!cabin.userId || !cabin.showNickname) return;
|
if (!cabin.userId || !cabin.showNickname) return;
|
||||||
|
// 如果是自己的小屋,不需要 target_uid 参数
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/exhibition/exhibition?target_uid=${cabin.userId}`,
|
url: cabin.isMine ? '/pages/exhibition/exhibition' : `/pages/exhibition/exhibition?target_uid=${cabin.userId}`,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// API 基础配置
|
// API 基础配置
|
||||||
// const baseURL = 'http://101.132.250.62:8080'
|
const baseURL = 'http://101.132.250.62:8080'
|
||||||
// const baseURL = 'http://192.168.110.60:8080'
|
// const baseURL = 'http://192.168.110.60:8080'
|
||||||
const baseURL = 'http://localhost:8080'
|
// const baseURL = 'http://localhost:8080'
|
||||||
|
|
||||||
// 是否使用模拟数据(开发调试时设为 true,后端API准备好后改为 false)
|
// 是否使用模拟数据(开发调试时设为 true,后端API准备好后改为 false)
|
||||||
const USE_MOCK_API = false
|
const USE_MOCK_API = false
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user