Compare commits
8 Commits
01836971e5
...
3991ce5134
| Author | SHA1 | Date |
|---|---|---|
|
|
3991ce5134 | |
|
|
cd552a1a4d | |
|
|
1232efa191 | |
|
|
4ea06ba637 | |
|
|
d34c0c7cb5 | |
|
|
2bda66bd64 | |
|
|
f1ababe5be | |
|
|
e2937d0ce1 |
169
deploy-ai.sh
169
deploy-ai.sh
|
|
@ -66,11 +66,12 @@ echo " 3) token.tlyq.ai (Token工厂)"
|
||||||
echo " 4) issue.tlyq.ai (工单系统)"
|
echo " 4) issue.tlyq.ai (工单系统)"
|
||||||
echo " 5) assets.tlyq.ai (资产管理系统)"
|
echo " 5) assets.tlyq.ai (资产管理系统)"
|
||||||
echo " 6) oa.tlyq.ai (OA 统一门户 — 含 nginx 配置)"
|
echo " 6) oa.tlyq.ai (OA 统一门户 — 含 nginx 配置)"
|
||||||
echo " 7) ldap.tlyq.ai (LLDAP 用户目录服务)"
|
echo " 7) ldap.tlyq.ai (LLDAP 用户目录服务)"
|
||||||
echo " 8) git.tlyq.ai (Gitea 代码托管)"
|
echo " 8) git.tlyq.ai (Gitea 代码托管)"
|
||||||
echo " 9) sso.tlyq.ai (Authelia SSO — 统一认证中心)"
|
echo " 9) sso.tlyq.ai (Authelia SSO — 统一认证中心)"
|
||||||
|
echo " 10) monitor.tlyq.ai (告警监控中心)"
|
||||||
echo ""
|
echo ""
|
||||||
printf "请输入编号 (1/2/3/4/5/6/7/8/9): "
|
printf "请输入编号 (1/2/3/4/5/6/7/8/9/10): "
|
||||||
read choice
|
read choice
|
||||||
|
|
||||||
SITE=""; LOCAL_DIR=""; REMOTE_DIR=""; CONTAINER=""
|
SITE=""; LOCAL_DIR=""; REMOTE_DIR=""; CONTAINER=""
|
||||||
|
|
@ -84,6 +85,7 @@ case "$choice" in
|
||||||
7) SITE="ldap"; LOCAL_DIR="/Users/niuniu/programs/docker/ldap-ai"; REMOTE_DIR="/root/docker/ldap-ai"; CONTAINER="lldap" ;;
|
7) SITE="ldap"; LOCAL_DIR="/Users/niuniu/programs/docker/ldap-ai"; REMOTE_DIR="/root/docker/ldap-ai"; CONTAINER="lldap" ;;
|
||||||
8) SITE="gitea"; LOCAL_DIR="/Users/niuniu/programs/docker/gitea-ai"; REMOTE_DIR="/root/docker/gitea-ai"; CONTAINER="gitea-ai" ;;
|
8) SITE="gitea"; LOCAL_DIR="/Users/niuniu/programs/docker/gitea-ai"; REMOTE_DIR="/root/docker/gitea-ai"; CONTAINER="gitea-ai" ;;
|
||||||
9) SITE="sso"; LOCAL_DIR="/Users/niuniu/programs/docker/sso-ai"; REMOTE_DIR="/root/docker/sso-ai"; CONTAINER="authelia" ;;
|
9) SITE="sso"; LOCAL_DIR="/Users/niuniu/programs/docker/sso-ai"; REMOTE_DIR="/root/docker/sso-ai"; CONTAINER="authelia" ;;
|
||||||
|
10) SITE="monitor"; LOCAL_DIR="/Users/niuniu/programs/docker/monitor-ai"; REMOTE_DIR="/root/docker/monitor-ai"; CONTAINER="monitor-ai" ;;
|
||||||
*) echo "无效选择"; exit 1 ;;
|
*) echo "无效选择"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
@ -159,8 +161,8 @@ replace_oa_urls() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
to_prod() { [[ "$SITE" != "issue" && "$SITE" != "assets" && "$SITE" != "oa" ]] && replace_url prod; }
|
to_prod() { [[ "$SITE" == "www" || "$SITE" == "cloud" || "$SITE" == "token" ]] && replace_url prod; }
|
||||||
to_local() { [[ "$SITE" != "issue" && "$SITE" != "assets" && "$SITE" != "oa" ]] && replace_url local; }
|
to_local() { [[ "$SITE" == "www" || "$SITE" == "cloud" || "$SITE" == "token" ]] && replace_url local; }
|
||||||
trap 'to_local; [[ "$SITE" == "oa" ]] && replace_oa_urls local' EXIT
|
trap 'to_local; [[ "$SITE" == "oa" ]] && replace_oa_urls local' EXIT
|
||||||
[[ "$SITE" == "oa" ]] && replace_oa_urls prod
|
[[ "$SITE" == "oa" ]] && replace_oa_urls prod
|
||||||
[[ "$SITE" != "issue" && "$SITE" != "assets" && "$SITE" != "oa" ]] && to_prod
|
[[ "$SITE" != "issue" && "$SITE" != "assets" && "$SITE" != "oa" ]] && to_prod
|
||||||
|
|
@ -174,7 +176,12 @@ deploy_sso() {
|
||||||
# 1. 上传 docker-compose.yml 和 config/
|
# 1. 上传 docker-compose.yml 和 config/
|
||||||
log "上传配置文件..."
|
log "上传配置文件..."
|
||||||
scp /Users/niuniu/programs/docker/sso-ai/docker-compose.yml txjp:/root/docker/sso-ai/docker-compose.yml
|
scp /Users/niuniu/programs/docker/sso-ai/docker-compose.yml txjp:/root/docker/sso-ai/docker-compose.yml
|
||||||
scp -r /Users/niuniu/programs/docker/sso-ai/config txjp:/root/docker/sso-ai/config
|
# 备份现有配置(用于恢复 JWKS 密钥等动态生成的值)
|
||||||
|
ssh txjp "cp /root/docker/sso-ai/config/authelia/configuration.yml /root/docker/sso-ai/config/authelia/configuration.yml.bak 2>/dev/null || true"
|
||||||
|
# 使用生产配置(configuration.prod.yml → configuration.yml)
|
||||||
|
scp /Users/niuniu/programs/docker/sso-ai/config/authelia/configuration.prod.yml txjp:/root/docker/sso-ai/config/authelia/configuration.yml
|
||||||
|
# 上传其他 config 文件(如 notifications.yml)
|
||||||
|
scp /Users/niuniu/programs/docker/sso-ai/config/authelia/notifications.yml txjp:/root/docker/sso-ai/config/authelia/notifications.yml 2>/dev/null || true
|
||||||
|
|
||||||
# 2. 首次部署:生成密钥
|
# 2. 首次部署:生成密钥
|
||||||
ssh txjp "if [ ! -f /root/docker/sso-ai/.env ]; then
|
ssh txjp "if [ ! -f /root/docker/sso-ai/.env ]; then
|
||||||
|
|
@ -192,15 +199,39 @@ AUTHELIA_STORAGE_ENCRYPTION_KEY=\$AUTHELIA_STORAGE_ENCRYPTION_KEY
|
||||||
LLDAP_PASSWORD=\$LLDAP_PASSWORD
|
LLDAP_PASSWORD=\$LLDAP_PASSWORD
|
||||||
ENVEOF
|
ENVEOF
|
||||||
echo '密钥已生成'
|
echo '密钥已生成'
|
||||||
|
chmod 600 /root/docker/sso-ai/.env
|
||||||
else
|
else
|
||||||
echo '已存在 .env,跳过密钥生成'
|
echo '已存在 .env,跳过密钥生成'
|
||||||
|
chmod 600 /root/docker/sso-ai/.env 2>/dev/null || true
|
||||||
fi"
|
fi"
|
||||||
|
|
||||||
# 3. 注入 LDAP 密码到 configuration.yml
|
# 3. 注入占位符真实值(LDAP 密码、JWKS 密钥)
|
||||||
log "注入 LDAP 密码..."
|
log "注入 LDAP 密码和 JWKS 密钥..."
|
||||||
ssh txjp "cd /root/docker/sso-ai && \
|
ssh txjp "cd /root/docker/sso-ai && \
|
||||||
LLDAP_PASSWORD=\$(docker exec lldap printenv LLDAP_ADMIN_PASSWORD) && \
|
LLDAP_PASSWORD=\$(docker exec lldap printenv LLDAP_ADMIN_PASSWORD) && \
|
||||||
sed -i \"s/password: 'placeholder'/password: '\$LLDAP_PASSWORD'/\" config/authelia/configuration.yml 2>/dev/null || true"
|
sed -i \"s|PRODUCTION_LDAP_PASSWORD|\$LLDAP_PASSWORD|\" config/authelia/configuration.yml 2>/dev/null || true && \
|
||||||
|
# 如果 JWKS key 仍是占位符,从现有配置或生成新密钥
|
||||||
|
if grep -q 'OIDC_JWKS_KEY_PLACEHOLDER' config/authelia/configuration.yml; then
|
||||||
|
EXISTING_KEY=\$(cat /root/docker/sso-ai/config/authelia/configuration.yml.bak 2>/dev/null | sed -n '/key: |/,/-----END/{p}' || true)
|
||||||
|
if [ -n \"\$EXISTING_KEY\" ]; then
|
||||||
|
echo '从备份恢复 JWKS 密钥'
|
||||||
|
# 使用 python 替换多行占位符(sed 不便处理)
|
||||||
|
python3 -c \"
|
||||||
|
import sys
|
||||||
|
content = open('config/authelia/configuration.yml').read()
|
||||||
|
key = '''\$EXISTING_KEY'''
|
||||||
|
content = content.replace('OIDC_JWKS_KEY_PLACEHOLDER', key.strip())
|
||||||
|
open('config/authelia/configuration.yml', 'w').write(content)
|
||||||
|
\" 2>/dev/null || true
|
||||||
|
else
|
||||||
|
echo '警告: JWKS 密钥为占位符,需要手动配置'
|
||||||
|
fi
|
||||||
|
fi && \
|
||||||
|
# 检查 OIDC client_secret 占位符
|
||||||
|
if grep -q 'OIDC_.*_SECRET_HASH' config/authelia/configuration.yml; then
|
||||||
|
echo '警告: 存在 OIDC client_secret 占位符,需要手动替换'
|
||||||
|
grep 'OIDC_.*_SECRET_HASH' config/authelia/configuration.yml || true
|
||||||
|
fi"
|
||||||
|
|
||||||
# 4. 部署 nginx sso-ai.conf
|
# 4. 部署 nginx sso-ai.conf
|
||||||
log "部署 nginx 配置..."
|
log "部署 nginx 配置..."
|
||||||
|
|
@ -402,18 +433,21 @@ build_on_server() {
|
||||||
|| echo 'NEXT_PUBLIC_ASSETS_URL=https://assets.tlyq.ai' >> $REMOTE_DIR/.env"
|
|| echo 'NEXT_PUBLIC_ASSETS_URL=https://assets.tlyq.ai' >> $REMOTE_DIR/.env"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 确保 AUTHELIA_URL 已设置(退出登录 cookie domain 依赖此变量)
|
# 确保 AUTHELIA_URL 已设置(仅对使用 OIDC 的站点)
|
||||||
|
if [[ "$SITE" == "oa" || "$SITE" == "assets" || "$SITE" == "issue" || "$SITE" == "monitor" ]]; then
|
||||||
ssh txjp "grep -q 'AUTHELIA_URL' $REMOTE_DIR/.env 2>/dev/null \
|
ssh txjp "grep -q 'AUTHELIA_URL' $REMOTE_DIR/.env 2>/dev/null \
|
||||||
&& sed -i 's|AUTHELIA_URL=.*|AUTHELIA_URL=https://sso.tlyq.ai|' $REMOTE_DIR/.env 2>/dev/null \
|
&& sed -i 's|AUTHELIA_URL=.*|AUTHELIA_URL=https://sso.tlyq.ai|' $REMOTE_DIR/.env 2>/dev/null \
|
||||||
|| echo 'AUTHELIA_URL=https://sso.tlyq.ai' >> $REMOTE_DIR/.env"
|
|| echo 'AUTHELIA_URL=https://sso.tlyq.ai' >> $REMOTE_DIR/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
# OIDC 环境变量配置(oa/assets/issue 站点)
|
# OIDC 环境变量配置(oa/assets/issue/monitor 站点)
|
||||||
if [[ "$SITE" == "oa" || "$SITE" == "assets" || "$SITE" == "issue" ]]; then
|
if [[ "$SITE" == "oa" || "$SITE" == "assets" || "$SITE" == "issue" || "$SITE" == "monitor" ]]; then
|
||||||
# 根据站点设置 OIDC 变量
|
# 根据站点设置 OIDC 变量
|
||||||
case "$SITE" in
|
case "$SITE" in
|
||||||
oa) OIDC_ID="oa-oidc"; OIDC_URI="https://oa.tlyq.ai/api/auth/callback" ;;
|
oa) OIDC_ID="oa-oidc"; OIDC_URI="https://oa.tlyq.ai/api/auth/callback" ;;
|
||||||
assets) OIDC_ID="assets-oidc"; OIDC_URI="https://assets.tlyq.ai/api/auth/callback" ;;
|
assets) OIDC_ID="assets-oidc"; OIDC_URI="https://assets.tlyq.ai/api/auth/callback" ;;
|
||||||
issue) OIDC_ID="issue-oidc"; OIDC_URI="https://issue.tlyq.ai/api/auth/callback" ;;
|
issue) OIDC_ID="issue-oidc"; OIDC_URI="https://issue.tlyq.ai/api/auth/callback" ;;
|
||||||
|
monitor) OIDC_ID="monitor-oidc"; OIDC_URI="https://monitor.tlyq.ai/api/auth/callback" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# 确保 OIDC_CLIENT_ID 已设置
|
# 确保 OIDC_CLIENT_ID 已设置
|
||||||
|
|
@ -432,16 +466,71 @@ build_on_server() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 使用 .env.prod 模板补充缺失的环境变量
|
||||||
|
ENV_PROD="$LOCAL_DIR/config/.env.prod"
|
||||||
|
if [[ -f "$ENV_PROD" ]]; then
|
||||||
|
info "使用 .env.prod 模板补充缺失变量..."
|
||||||
|
# 上传模板到服务器临时目录
|
||||||
|
scp "$ENV_PROD" txjp:/tmp/.env.prod.template
|
||||||
|
# 逐行检查:模板中有但 .env 中没有的变量,追加到 .env
|
||||||
|
ssh txjp "while IFS= read -r line; do
|
||||||
|
# 跳过注释和空行
|
||||||
|
[[ \"\$line\" =~ ^#.*$ ]] && continue
|
||||||
|
[[ -z \"\$line\" ]] && continue
|
||||||
|
# 提取变量名
|
||||||
|
varname=\"\$(echo \"\$line\" | cut -d= -f1)\"
|
||||||
|
# 如果 .env 中没有此变量,追加(跳过占位符值)
|
||||||
|
if ! grep -q \"^\${varname}=\" $REMOTE_DIR/.env 2>/dev/null; then
|
||||||
|
# 跳过 __PLACEHOLDER__ 格式的值(需要真实密钥)
|
||||||
|
if [[ ! \"\$line\" =~ __.*__ ]]; then
|
||||||
|
echo \"\$line\" >> $REMOTE_DIR/.env
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < /tmp/.env.prod.template && rm -f /tmp/.env.prod.template"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 自动生成缺失的密钥(首次部署场景)
|
||||||
|
# JWT_SECRET:所有站点都需要
|
||||||
|
if ! ssh txjp "grep -q '^JWT_SECRET=' $REMOTE_DIR/.env 2>/dev/null"; then
|
||||||
|
JWT_GEN=$(openssl rand -hex 32)
|
||||||
|
ssh txjp "echo 'JWT_SECRET=${JWT_GEN}' >> $REMOTE_DIR/.env"
|
||||||
|
info "已自动生成 JWT_SECRET"
|
||||||
|
fi
|
||||||
|
# OIDC_CLIENT_SECRET:从 Authelia 配置读取或警告
|
||||||
|
if [[ "$SITE" == "oa" || "$SITE" == "assets" || "$SITE" == "issue" || "$SITE" == "monitor" ]]; then
|
||||||
|
if ! ssh txjp "grep -q '^OIDC_CLIENT_SECRET=' $REMOTE_DIR/.env 2>/dev/null"; then
|
||||||
|
# 尝试从 Authelia 配置读取对应的 client_secret 哈希
|
||||||
|
OIDC_SECRET_KEY="${SITE}_OIDC_SECRET"
|
||||||
|
OIDC_SECRET_VAL=$(ssh txjp "grep -A1 'client_id:.*${OIDC_ID}' /root/docker/sso-ai/config/authelia/configuration.yml 2>/dev/null | grep client_secret | head -1 | sed \"s/.*client_secret: *'\\(.*\\)'/\\1/\" || true" 2>/dev/null)
|
||||||
|
if [[ -n "$OIDC_SECRET_VAL" && "$OIDC_SECRET_VAL" != *"PLACEHOLDER"* ]]; then
|
||||||
|
ssh txjp "echo 'OIDC_CLIENT_SECRET=${OIDC_SECRET_VAL}' >> $REMOTE_DIR/.env"
|
||||||
|
info "已从 Authelia 配置注入 OIDC_CLIENT_SECRET"
|
||||||
|
else
|
||||||
|
warn "OIDC_CLIENT_SECRET 未设置,请从 Authelia 配置获取并手动配置"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# LOCALADMIN_PASSWORD:monitor 专属
|
||||||
|
if [[ "$SITE" == "monitor" ]]; then
|
||||||
|
if ! ssh txjp "grep -q '^LOCALADMIN_PASSWORD=' $REMOTE_DIR/.env 2>/dev/null"; then
|
||||||
|
LOCALADMIN_GEN=$(openssl rand -hex 16)
|
||||||
|
ssh txjp "echo 'LOCALADMIN_PASSWORD=${LOCALADMIN_GEN}' >> $REMOTE_DIR/.env"
|
||||||
|
info "已自动生成 LOCALADMIN_PASSWORD"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# 清理可能被上传的本地环境变量文件(.env.local 等会覆盖 .env 中的生产配置)
|
# 清理可能被上传的本地环境变量文件(.env.local 等会覆盖 .env 中的生产配置)
|
||||||
ssh txjp "rm -f $REMOTE_DIR/.env.local $REMOTE_DIR/.env.development $REMOTE_DIR/.env.production 2>/dev/null; echo '已清理本地环境文件'"
|
ssh txjp "rm -f $REMOTE_DIR/.env.local $REMOTE_DIR/.env.development $REMOTE_DIR/.env.production 2>/dev/null; echo '已清理本地环境文件'"
|
||||||
|
|
||||||
|
# 设置 .env 文件权限为 600(仅 root 可读写,防止密码泄露)
|
||||||
|
ssh txjp "chmod 600 $REMOTE_DIR/.env 2>/dev/null || true"
|
||||||
|
|
||||||
# 5. 服务器上直接 npm run build(不重建 Docker)
|
# 5. 服务器上直接 npm run build(不重建 Docker)
|
||||||
log "服务器上执行 npm run build..."
|
log "服务器上执行 npm run build..."
|
||||||
build_start=$(date +%s)
|
build_start=$(date +%s)
|
||||||
# 使用 tee 避免管道导致退出码丢失,并过滤无用输出
|
# 使用 tee 避免管道导致退出码丢失,并过滤无用输出
|
||||||
ssh txjp "cd ${REMOTE_DIR} && npm run build 2>&1" | \
|
ssh txjp "cd ${REMOTE_DIR} && npm run build 2>&1" | \
|
||||||
grep -vE "^(info|warn|npm warn|audited|packages|funding|vulnerability|npm notice|New major)" | \
|
grep -vE "^(info|warn|npm warn|audited|packages|funding|vulnerability|npm notice|New major)" | \
|
||||||
tee /tmp/build_output.txt | \
|
|
||||||
tail -15
|
tail -15
|
||||||
build_exit_code=${PIPESTATUS[0]}
|
build_exit_code=${PIPESTATUS[0]}
|
||||||
build_end=$(date +%s)
|
build_end=$(date +%s)
|
||||||
|
|
@ -449,11 +538,12 @@ build_on_server() {
|
||||||
timing "构建耗时: ${build_dur}s"
|
timing "构建耗时: ${build_dur}s"
|
||||||
|
|
||||||
if [[ "$build_exit_code" -ne 0 ]]; then
|
if [[ "$build_exit_code" -ne 0 ]]; then
|
||||||
warn "构建可能有警告,请检查上面的输出"
|
error "构建失败(退出码: $build_exit_code),中止部署"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 清理 standalone 中的 musl 原生模块(Alpine builder 残留,Debian runner 不兼容)
|
# 清理 standalone 中的 musl 原生模块(Alpine builder 残留,Debian runner 不兼容)
|
||||||
if [[ "$SITE" == "issue" || "$SITE" == "assets" || "$SITE" == "oa" ]]; then
|
if [[ "$SITE" == "issue" || "$SITE" == "assets" || "$SITE" == "oa" || "$SITE" == "monitor" ]]; then
|
||||||
ssh txjp "rm -rf $REMOTE_DIR/.next/standalone/node_modules/@img/sharp-linuxmusl-x64 \
|
ssh txjp "rm -rf $REMOTE_DIR/.next/standalone/node_modules/@img/sharp-linuxmusl-x64 \
|
||||||
$REMOTE_DIR/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64 \
|
$REMOTE_DIR/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64 \
|
||||||
$REMOTE_DIR/.next/standalone/node_modules/@next/swc-linux-x64-musl 2>/dev/null; echo '已清理 musl 残留'"
|
$REMOTE_DIR/.next/standalone/node_modules/@next/swc-linux-x64-musl 2>/dev/null; echo '已清理 musl 残留'"
|
||||||
|
|
@ -464,8 +554,24 @@ build_on_server() {
|
||||||
log "重建容器..."
|
log "重建容器..."
|
||||||
local build_flag=""
|
local build_flag=""
|
||||||
ssh txjp "test -f $REMOTE_DIR/Dockerfile" 2>/dev/null && build_flag="--build"
|
ssh txjp "test -f $REMOTE_DIR/Dockerfile" 2>/dev/null && build_flag="--build"
|
||||||
|
|
||||||
|
# Docker 无法跟随指向构建上下文外的符号链接,临时将 shared 符号链接替换为实际目录
|
||||||
|
ssh txjp "cd $REMOTE_DIR && if [ -L shared ]; then
|
||||||
|
target=\$(readlink shared)
|
||||||
|
rm shared
|
||||||
|
cp -r \$target shared
|
||||||
|
echo 'shared 符号链接已临时替换为实际目录'
|
||||||
|
fi"
|
||||||
|
|
||||||
ssh txjp "cd $REMOTE_DIR && docker compose up -d $build_flag && docker compose restart"
|
ssh txjp "cd $REMOTE_DIR && docker compose up -d $build_flag && docker compose restart"
|
||||||
|
|
||||||
|
# 恢复 shared 符号链接(仅当目录非符号链接且上级 shared 存在时)
|
||||||
|
ssh txjp "cd $REMOTE_DIR && if [ -d shared ] && [ ! -L shared ] && [ -d ../shared ]; then
|
||||||
|
rm -rf shared
|
||||||
|
ln -s ../shared shared
|
||||||
|
echo 'shared 符号链接已恢复'
|
||||||
|
fi"
|
||||||
|
|
||||||
# 7. 清理构建产生的悬空镜像和缓存(根据磁盘使用率动态调整)
|
# 7. 清理构建产生的悬空镜像和缓存(根据磁盘使用率动态调整)
|
||||||
log "清理构建缓存..."
|
log "清理构建缓存..."
|
||||||
# 清理悬空镜像(无标签或未被引用的中间层)
|
# 清理悬空镜像(无标签或未被引用的中间层)
|
||||||
|
|
@ -476,6 +582,8 @@ build_on_server() {
|
||||||
if [ "$DISK_USAGE" -gt 95 ]; then
|
if [ "$DISK_USAGE" -gt 95 ]; then
|
||||||
warn "磁盘使用率 ${DISK_USAGE}%,执行紧急清理"
|
warn "磁盘使用率 ${DISK_USAGE}%,执行紧急清理"
|
||||||
ssh txjp "docker builder prune -f 2>/dev/null || true"
|
ssh txjp "docker builder prune -f 2>/dev/null || true"
|
||||||
|
# 截断容器日志(占磁盘大户)
|
||||||
|
ssh txjp "truncate -s 0 /var/lib/docker/containers/*/\*-json.log 2>/dev/null || true"
|
||||||
elif [ "$DISK_USAGE" -gt 85 ]; then
|
elif [ "$DISK_USAGE" -gt 85 ]; then
|
||||||
info "磁盘使用率 ${DISK_USAGE}%,执行激进清理(6小时)"
|
info "磁盘使用率 ${DISK_USAGE}%,执行激进清理(6小时)"
|
||||||
ssh txjp "docker builder prune -f --filter 'until=6h' 2>/dev/null || true"
|
ssh txjp "docker builder prune -f --filter 'until=6h' 2>/dev/null || true"
|
||||||
|
|
@ -489,6 +597,9 @@ build_on_server() {
|
||||||
|
|
||||||
# 8. 保存快照
|
# 8. 保存快照
|
||||||
ssh txjp "echo '$local_md5' > ${SNAPSHOT_FILE}"
|
ssh txjp "echo '$local_md5' > ${SNAPSHOT_FILE}"
|
||||||
|
|
||||||
|
# 9. 清理远程临时文件(源码包、连通性检查脚本)
|
||||||
|
ssh txjp "rm -f /tmp/${SITE}.tar.gz /tmp/shared-deploy.tar.gz /tmp/check-conn.js /tmp/.env.prod.template 2>/dev/null || true"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
@ -591,13 +702,18 @@ CHECKEOF
|
||||||
scp "$LOCAL_DIR/Dockerfile" txjp:$REMOTE_DIR/Dockerfile
|
scp "$LOCAL_DIR/Dockerfile" txjp:$REMOTE_DIR/Dockerfile
|
||||||
ssh txjp "cd $REMOTE_DIR && \
|
ssh txjp "cd $REMOTE_DIR && \
|
||||||
if [ ! -f .env ]; then \
|
if [ ! -f .env ]; then \
|
||||||
echo 'LLDAP_JWT_SECRET='\$(docker exec lldap printenv LLDAP_JWT_SECRET 2>/dev/null) > .env && \
|
LLDAP_JWT=\$(docker exec lldap printenv LLDAP_JWT_SECRET 2>/dev/null) && \
|
||||||
echo 'LLDAP_LDAP_USER_PASS='\$(docker exec lldap printenv LLDAP_LDAP_USER_PASS 2>/dev/null) >> .env && \
|
LLDAP_PASS=\$(docker exec lldap printenv LLDAP_LDAP_USER_PASS 2>/dev/null) && \
|
||||||
echo 'LLDAP_LDAP_BASE_DN=dc=tlyq,dc=ai' >> .env && \
|
LLDAP_ADMIN=\$(docker exec lldap printenv LLDAP_ADMIN_PASSWORD 2>/dev/null) && \
|
||||||
echo 'LLDAP_HTTP_PORT=17170' >> .env && \
|
printf '%s\n' \
|
||||||
echo 'LLDAP_LDAP_PORT=3890' >> .env && \
|
\"LLDAP_JWT_SECRET=\$LLDAP_JWT\" \
|
||||||
echo 'LLDAP_DATABASE_PATH=/data/users.db' >> .env && \
|
\"LLDAP_LDAP_USER_PASS=\$LLDAP_PASS\" \
|
||||||
echo 'LLDAP_ADMIN_PASSWORD='\$(docker exec lldap printenv LLDAP_ADMIN_PASSWORD 2>/dev/null) >> .env && \
|
\"LLDAP_LDAP_BASE_DN=dc=tlyq,dc=ai\" \
|
||||||
|
\"LLDAP_HTTP_PORT=17170\" \
|
||||||
|
\"LLDAP_LDAP_PORT=3890\" \
|
||||||
|
\"LLDAP_DATABASE_PATH=/data/users.db\" \
|
||||||
|
\"LLDAP_ADMIN_PASSWORD=\$LLDAP_ADMIN\" \
|
||||||
|
> .env && \
|
||||||
fi && \
|
fi && \
|
||||||
sed -i '/3890:3890/d' docker-compose.yml 2>/dev/null || true && \
|
sed -i '/3890:3890/d' docker-compose.yml 2>/dev/null || true && \
|
||||||
docker compose up -d --build && docker compose restart"
|
docker compose up -d --build && docker compose restart"
|
||||||
|
|
@ -609,6 +725,11 @@ CHECKEOF
|
||||||
log "Gitea 已部署" ;;
|
log "Gitea 已部署" ;;
|
||||||
sso)
|
sso)
|
||||||
deploy_sso ;;
|
deploy_sso ;;
|
||||||
|
monitor)
|
||||||
|
build_on_server || exit 1
|
||||||
|
info "部署 nginx 配置..."
|
||||||
|
ssh txjp "cp $REMOTE_DIR/../nginx-proxy-ai/conf.d/monitor-ai.conf /root/docker/nginx-proxy-ai/conf.d/ 2>/dev/null || true
|
||||||
|
docker exec nginx-ai nginx -t && docker exec nginx-ai nginx -s reload" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
@ -630,11 +751,13 @@ case "$SITE" in
|
||||||
ldap) URL="http://localhost:6178" ;;
|
ldap) URL="http://localhost:6178" ;;
|
||||||
gitea) URL="https://git.tlyq.ai" ;;
|
gitea) URL="https://git.tlyq.ai" ;;
|
||||||
sso) URL="https://sso.tlyq.ai" ;;
|
sso) URL="https://sso.tlyq.ai" ;;
|
||||||
|
monitor) URL="https://monitor.tlyq.ai" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ "$SITE" == "ldap" ]]; then
|
if [[ "$SITE" == "ldap" ]]; then
|
||||||
STATUS=$(ssh txjp "docker exec lldap wget -q -O - http://127.0.0.1:17170 > /dev/null 2>&1 && echo 200 || echo 000" 2>/dev/null || echo "???")
|
STATUS=$(ssh txjp "docker exec lldap wget -q -O - http://127.0.0.1:17170 > /dev/null 2>&1 && echo 200 || echo 000" 2>/dev/null || echo "???")
|
||||||
else
|
else
|
||||||
|
# -k: 服务器本地使用自签名证书,必须跳过 TLS 验证
|
||||||
STATUS=$(ssh txjp "curl -s -o /dev/null -w '%{http_code}' -k '$URL' 2>/dev/null" 2>/dev/null || echo "???")
|
STATUS=$(ssh txjp "curl -s -o /dev/null -w '%{http_code}' -k '$URL' 2>/dev/null" 2>/dev/null || echo "???")
|
||||||
fi
|
fi
|
||||||
if [[ "$STATUS" == "200" || "$STATUS" == "307" || "$STATUS" == "301" ]]; then
|
if [[ "$STATUS" == "200" || "$STATUS" == "307" || "$STATUS" == "301" ]]; then
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# 用法:bash sites-manage-cloud.sh [命令] [站点名...]
|
# 用法:bash sites-manage-cloud.sh [命令] [站点名...]
|
||||||
# 不加命令默认 status
|
# 不加命令默认 status
|
||||||
# 站点名:ldap www cloud token gitea issue assets oa nginx
|
# 站点名:ldap www cloud token gitea issue assets oa nginx sso monitor
|
||||||
# ai(上述全部)、all(同 ai)
|
# ai(上述全部)、all(同 ai)
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
@ -48,32 +48,41 @@ run() {
|
||||||
|
|
||||||
BASE="/root/docker"
|
BASE="/root/docker"
|
||||||
|
|
||||||
# 站点 → 目录 & 容器名
|
# 站点 → 目录
|
||||||
declare -A SITE_DIR
|
site_dir() {
|
||||||
SITE_DIR[ldap]="ldap-ai"
|
case $1 in
|
||||||
SITE_DIR[www]="www-ai"
|
ldap) echo "ldap-ai" ;;
|
||||||
SITE_DIR[cloud]="cloud-ai"
|
www) echo "www-ai" ;;
|
||||||
SITE_DIR[token]="token-ai"
|
cloud) echo "cloud-ai" ;;
|
||||||
SITE_DIR[gitea]="gitea-ai"
|
token) echo "token-ai" ;;
|
||||||
SITE_DIR[issue]="issue-ai"
|
gitea) echo "gitea-ai" ;;
|
||||||
SITE_DIR[assets]="assets-ai"
|
issue) echo "issue-ai" ;;
|
||||||
SITE_DIR[oa]="oa-ai"
|
assets) echo "assets-ai" ;;
|
||||||
SITE_DIR[nginx]="nginx-proxy-ai"
|
oa) echo "oa-ai" ;;
|
||||||
SITE_DIR[sso]="sso-ai"
|
nginx) echo "nginx-proxy-ai" ;;
|
||||||
|
sso) echo "sso-ai" ;;
|
||||||
|
monitor) echo "monitor-ai" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
declare -A SITE_CONTAINER
|
# 站点 → 容器名
|
||||||
SITE_CONTAINER[ldap]="lldap"
|
site_container() {
|
||||||
SITE_CONTAINER[www]="www-ai"
|
case $1 in
|
||||||
SITE_CONTAINER[cloud]="cloud-ai"
|
ldap) echo "lldap" ;;
|
||||||
SITE_CONTAINER[token]="token-ai"
|
www) echo "www-ai" ;;
|
||||||
SITE_CONTAINER[gitea]="gitea-ai"
|
cloud) echo "cloud-ai" ;;
|
||||||
SITE_CONTAINER[issue]="issue-ai"
|
token) echo "token-ai" ;;
|
||||||
SITE_CONTAINER[assets]="assets-ai"
|
gitea) echo "gitea-ai" ;;
|
||||||
SITE_CONTAINER[oa]="oa-ai"
|
issue) echo "issue-ai" ;;
|
||||||
SITE_CONTAINER[nginx]="nginx-ai"
|
assets) echo "assets-ai" ;;
|
||||||
SITE_CONTAINER[sso]="sso-ai"
|
oa) echo "oa-ai" ;;
|
||||||
|
nginx) echo "nginx-ai" ;;
|
||||||
|
sso) echo "authelia" ;;
|
||||||
|
monitor) echo "monitor-ai" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
AI_SITES="ldap www cloud token gitea issue assets oa nginx"
|
AI_SITES="ldap www cloud token gitea issue assets oa nginx sso monitor"
|
||||||
|
|
||||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||||||
log() { printf "${GREEN}[✓]${NC} %s\n" "$1"; }
|
log() { printf "${GREEN}[✓]${NC} %s\n" "$1"; }
|
||||||
|
|
@ -112,8 +121,8 @@ expand_sites() {
|
||||||
# 操作
|
# 操作
|
||||||
# ============================================================
|
# ============================================================
|
||||||
remote_start() {
|
remote_start() {
|
||||||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
local name=$1 dir="${BASE}/$(site_dir $name)"
|
||||||
local container="${SITE_CONTAINER[$name]}"
|
local container="$(site_container $name)"
|
||||||
|
|
||||||
if run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
if run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||||||
warn "$name 已在运行"
|
warn "$name 已在运行"
|
||||||
|
|
@ -124,8 +133,8 @@ remote_start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_stop() {
|
remote_stop() {
|
||||||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
local name=$1 dir="${BASE}/$(site_dir $name)"
|
||||||
local container="${SITE_CONTAINER[$name]}"
|
local container="$(site_container $name)"
|
||||||
|
|
||||||
if ! run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
if ! run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||||||
warn "$name 未在运行"
|
warn "$name 未在运行"
|
||||||
|
|
@ -144,7 +153,7 @@ remote_status() {
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
for name in "${targets[@]}"; do
|
for name in "${targets[@]}"; do
|
||||||
local container="${SITE_CONTAINER[$name]}"
|
local container="$(site_container $name)"
|
||||||
local status
|
local status
|
||||||
status=$(run "docker ps --format '{{.Status}}' -f name=^${container}$" 2>/dev/null || echo "")
|
status=$(run "docker ps --format '{{.Status}}' -f name=^${container}$" 2>/dev/null || echo "")
|
||||||
if [ -n "$status" ]; then
|
if [ -n "$status" ]; then
|
||||||
|
|
@ -178,6 +187,8 @@ show_help() {
|
||||||
echo " assets 设备资产管理"
|
echo " assets 设备资产管理"
|
||||||
echo " oa OA 统一门户"
|
echo " oa OA 统一门户"
|
||||||
echo " nginx 反向代理"
|
echo " nginx 反向代理"
|
||||||
|
echo " sso Authelia OIDC 认证"
|
||||||
|
echo " monitor 告警监控中心"
|
||||||
echo " ai 全部 tlyq.ai 站点"
|
echo " ai 全部 tlyq.ai 站点"
|
||||||
echo ""
|
echo ""
|
||||||
echo "示例:"
|
echo "示例:"
|
||||||
|
|
@ -194,9 +205,9 @@ show_help() {
|
||||||
ACTION=${1:-status}
|
ACTION=${1:-status}
|
||||||
shift || true
|
shift || true
|
||||||
|
|
||||||
mapfile -t TARGETS < <(expand_sites "$@")
|
TARGETS=($(expand_sites "$@"))
|
||||||
if [ ${#TARGETS[@]} -eq 0 ]; then
|
if [ ${#TARGETS[@]} -eq 0 ]; then
|
||||||
mapfile -t TARGETS < <(expand_sites ai)
|
TARGETS=($(expand_sites ai))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查 Docker 服务(help 命令除外)
|
# 检查 Docker 服务(help 命令除外)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#
|
#
|
||||||
# 站点名:
|
# 站点名:
|
||||||
# cc: www-cc cloud-cc token-cc
|
# cc: www-cc cloud-cc token-cc
|
||||||
# ai: www-ai cloud-ai token-ai issue assets ldap
|
# ai: www-ai cloud-ai token-ai issue assets ldap oa sso gitea monitor
|
||||||
# all: 全部站点
|
# all: 全部站点
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
@ -16,7 +16,8 @@ ASSETS_DIR="$BASE_DIR/assets-ai"
|
||||||
LDAP_DIR="$BASE_DIR/ldap-ai"
|
LDAP_DIR="$BASE_DIR/ldap-ai"
|
||||||
OA_DIR="$BASE_DIR/oa-ai"
|
OA_DIR="$BASE_DIR/oa-ai"
|
||||||
GITEA_DIR="$BASE_DIR/gitea-ai"
|
GITEA_DIR="$BASE_DIR/gitea-ai"
|
||||||
OA_PORT=6179
|
SSO_DIR="$BASE_DIR/sso-ai"
|
||||||
|
MONITOR_DIR="$BASE_DIR/monitor-ai"
|
||||||
|
|
||||||
# 颜色
|
# 颜色
|
||||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||||||
|
|
@ -25,9 +26,18 @@ warn() { printf "${YELLOW}[!]${NC} %s\n" "$1"; }
|
||||||
err() { printf "${RED}[✗]${NC} %s\n" "$1"; }
|
err() { printf "${RED}[✗]${NC} %s\n" "$1"; }
|
||||||
|
|
||||||
# 端口
|
# 端口
|
||||||
|
WWW_AI_PORT=6173
|
||||||
|
CLOUD_AI_PORT=6174
|
||||||
|
TOKEN_AI_PORT=6175
|
||||||
ISSUE_PORT=6176
|
ISSUE_PORT=6176
|
||||||
ASSETS_PORT=6177
|
ASSETS_PORT=6177
|
||||||
LDAP_WEB_PORT=6178
|
LDAP_WEB_PORT=6178
|
||||||
|
OA_PORT=6179
|
||||||
|
SSO_PORT=6180
|
||||||
|
MONITOR_PORT=6181
|
||||||
|
WWW_CC_PORT=5173
|
||||||
|
CLOUD_CC_PORT=5174
|
||||||
|
TOKEN_CC_PORT=5175
|
||||||
GITEA_PORT=3000
|
GITEA_PORT=3000
|
||||||
|
|
||||||
is_port() { lsof -i :"$1" >/dev/null 2>&1; }
|
is_port() { lsof -i :"$1" >/dev/null 2>&1; }
|
||||||
|
|
@ -109,9 +119,11 @@ start_all() {
|
||||||
log "LLDAP Web UI: http://127.0.0.1:$LDAP_WEB_PORT"
|
log "LLDAP Web UI: http://127.0.0.1:$LDAP_WEB_PORT"
|
||||||
fi ;;
|
fi ;;
|
||||||
oa) node_start oa-ai "$OA_DIR" $OA_PORT "/tmp/oa-ai-dev.log" ;;
|
oa) node_start oa-ai "$OA_DIR" $OA_PORT "/tmp/oa-ai-dev.log" ;;
|
||||||
|
sso) docker_start authelia "$SSO_DIR" ;;
|
||||||
gitea) docker_start gitea-ai "$GITEA_DIR" ;;
|
gitea) docker_start gitea-ai "$GITEA_DIR" ;;
|
||||||
|
monitor) node_start monitor-ai "$MONITOR_DIR" $MONITOR_PORT "/tmp/monitor-ai-dev.log" ;;
|
||||||
cc) start_all www-cc cloud-cc token-cc ;;
|
cc) start_all www-cc cloud-cc token-cc ;;
|
||||||
ai) start_all ldap www-ai cloud-ai token-ai issue assets oa gitea ;;
|
ai) start_all ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor ;;
|
||||||
all) start_all cc ai ;;
|
all) start_all cc ai ;;
|
||||||
*) err "未知站点: $name" ;;
|
*) err "未知站点: $name" ;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -131,9 +143,11 @@ stop_all() {
|
||||||
assets) node_stop assets-ai $ASSETS_PORT ;;
|
assets) node_stop assets-ai $ASSETS_PORT ;;
|
||||||
ldap) docker_stop lldap "$LDAP_DIR" ;;
|
ldap) docker_stop lldap "$LDAP_DIR" ;;
|
||||||
oa) node_stop oa-ai $OA_PORT ;;
|
oa) node_stop oa-ai $OA_PORT ;;
|
||||||
|
sso) docker_stop authelia "$SSO_DIR" ;;
|
||||||
gitea) docker_stop gitea-ai "$GITEA_DIR" ;;
|
gitea) docker_stop gitea-ai "$GITEA_DIR" ;;
|
||||||
|
monitor) node_stop monitor-ai $MONITOR_PORT ;;
|
||||||
cc) stop_all www-cc cloud-cc token-cc ;;
|
cc) stop_all www-cc cloud-cc token-cc ;;
|
||||||
ai) stop_all ldap www-ai cloud-ai token-ai issue assets oa gitea ;;
|
ai) stop_all ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor ;;
|
||||||
all) stop_all cc ai ;;
|
all) stop_all cc ai ;;
|
||||||
*) err "未知站点: $name" ;;
|
*) err "未知站点: $name" ;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -156,9 +170,9 @@ show_status() {
|
||||||
local expanded=()
|
local expanded=()
|
||||||
for t in "${targets[@]}"; do
|
for t in "${targets[@]}"; do
|
||||||
case $t in
|
case $t in
|
||||||
all) eval "expanded=(www-cc cloud-cc token-cc ldap www-ai cloud-ai token-ai issue assets oa gitea)" ;;
|
all) eval "expanded=(www-cc cloud-cc token-cc ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor)" ;;
|
||||||
cc) eval "expanded=(\${expanded[@]} www-cc cloud-cc token-cc)" ;;
|
cc) eval "expanded=(\${expanded[@]} www-cc cloud-cc token-cc)" ;;
|
||||||
ai) eval "expanded=(\${expanded[@]} ldap www-ai cloud-ai token-ai issue assets oa gitea)" ;;
|
ai) eval "expanded=(\${expanded[@]} ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor)" ;;
|
||||||
*) expanded+=($t) ;;
|
*) expanded+=($t) ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
@ -169,66 +183,34 @@ show_status() {
|
||||||
printf "${CYAN}=========================================${NC}\n"
|
printf "${CYAN}=========================================${NC}\n"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# 获取站点对应端口
|
||||||
|
get_port() {
|
||||||
|
case $1 in
|
||||||
|
www-cc) echo $WWW_CC_PORT ;;
|
||||||
|
cloud-cc) echo $CLOUD_CC_PORT ;;
|
||||||
|
token-cc) echo $TOKEN_CC_PORT ;;
|
||||||
|
www-ai) echo $WWW_AI_PORT ;;
|
||||||
|
cloud-ai) echo $CLOUD_AI_PORT ;;
|
||||||
|
token-ai) echo $TOKEN_AI_PORT ;;
|
||||||
|
issue) echo $ISSUE_PORT ;;
|
||||||
|
assets) echo $ASSETS_PORT ;;
|
||||||
|
ldap) echo $LDAP_WEB_PORT ;;
|
||||||
|
oa) echo $OA_PORT ;;
|
||||||
|
sso) echo $SSO_PORT ;;
|
||||||
|
gitea) echo $GITEA_PORT ;;
|
||||||
|
monitor) echo $MONITOR_PORT ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
local running=0
|
local running=0
|
||||||
for name in "${expanded[@]}"; do
|
for name in "${expanded[@]}"; do
|
||||||
case $name in
|
local port=$(get_port $name)
|
||||||
www-cc|cloud-cc|token-cc|cloud-ai|token-ai)
|
if [ -n "$port" ] && is_port $port; then
|
||||||
if is_running $name; then
|
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $port
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中\n" "$name"
|
|
||||||
running=$((running + 1))
|
running=$((running + 1))
|
||||||
else
|
else
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||||||
fi
|
fi
|
||||||
;;
|
|
||||||
www-ai)
|
|
||||||
if is_running www-local-ai; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中\n" "$name"
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
issue)
|
|
||||||
if is_port $ISSUE_PORT; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $ISSUE_PORT
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
ldap)
|
|
||||||
if is_running lldap; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $LDAP_WEB_PORT
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
assets)
|
|
||||||
if is_port $ASSETS_PORT; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $ASSETS_PORT
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
oa)
|
|
||||||
if is_port $OA_PORT; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $OA_PORT
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
gitea)
|
|
||||||
if is_running gitea-ai; then
|
|
||||||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $GITEA_PORT
|
|
||||||
running=$((running + 1))
|
|
||||||
else
|
|
||||||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|
@ -247,9 +229,11 @@ show_status() {
|
||||||
echo " token-ai http://127.0.0.1:6175"
|
echo " token-ai http://127.0.0.1:6175"
|
||||||
echo " ldap http://127.0.0.1:$LDAP_WEB_PORT (LLDAP Web UI)"
|
echo " ldap http://127.0.0.1:$LDAP_WEB_PORT (LLDAP Web UI)"
|
||||||
echo " oa http://127.0.0.1:$OA_PORT"
|
echo " oa http://127.0.0.1:$OA_PORT"
|
||||||
|
echo " sso http://127.0.0.1:$SSO_PORT (Authelia OIDC)"
|
||||||
echo " issue http://127.0.0.1:$ISSUE_PORT"
|
echo " issue http://127.0.0.1:$ISSUE_PORT"
|
||||||
echo " assets http://127.0.0.1:$ASSETS_PORT"
|
echo " assets http://127.0.0.1:$ASSETS_PORT"
|
||||||
echo " gitea http://127.0.0.1:$GITEA_PORT"
|
echo " gitea http://127.0.0.1:$GITEA_PORT"
|
||||||
|
echo " monitor http://127.0.0.1:$MONITOR_PORT"
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,9 +252,9 @@ show_help() {
|
||||||
echo ""
|
echo ""
|
||||||
echo " 站点名(可指定多个,空格分隔):"
|
echo " 站点名(可指定多个,空格分隔):"
|
||||||
echo " www-cc cloud-cc token-cc"
|
echo " www-cc cloud-cc token-cc"
|
||||||
echo " ldap www-ai cloud-ai token-ai issue assets oa gitea"
|
echo " ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor"
|
||||||
echo " cc — tlyq.cc 全部 (www-cc cloud-cc token-cc)"
|
echo " cc — tlyq.cc 全部 (www-cc cloud-cc token-cc)"
|
||||||
echo " ai — tlyq.ai 全部 (ldap www-ai cloud-ai token-ai issue assets oa gitea)"
|
echo " ai — tlyq.ai 全部 (ldap www-ai cloud-ai token-ai issue assets oa sso gitea monitor)"
|
||||||
echo " all — 全部站点"
|
echo " all — 全部站点"
|
||||||
echo ""
|
echo ""
|
||||||
echo "示例:"
|
echo "示例:"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue