refactor: local.sh 更名为 sites-manage-local.sh,新增 sites-manage-cloud.sh 云端管理脚本
- local.sh → sites-manage-local.sh(重命名,职责更清晰) - 新增 sites-manage-cloud.sh(云服务器站点启停管理) - 更新 backup-db.sh、deploy-ai.sh、restore-db.sh - 添加 .gitignore(忽略 .DS_Store)
This commit is contained in:
parent
3efb7573ac
commit
78ff4b01b6
|
|
@ -0,0 +1 @@
|
|||
.DS_Store
|
||||
111
README.md
111
README.md
|
|
@ -1,34 +1,61 @@
|
|||
# Scripts — 部署与运维脚本
|
||||
|
||||
多站点 Docker 项目的运维脚本集合,涵盖本地开发管理、云端部署、数据库备份恢复、内容编辑等。
|
||||
多站点 Docker 项目的运维脚本集合,涵盖本地开发管理、云服务器运维、云端部署、数据库备份恢复。
|
||||
|
||||
## 脚本清单
|
||||
|
||||
| 脚本 | 用途 | 目标环境 |
|
||||
|------|------|---------|
|
||||
| `local.sh` | 本地站点启停管理 | 本地 Docker |
|
||||
| `sites-manage-local.sh` | 本地站点启停(npm run dev + Docker) | 本地 |
|
||||
| `sites-manage-cloud.sh` | 云服务器站点启停(SSH / 服务器本地运行) | 云端 |
|
||||
| `deploy-ai.sh` | 部署站点到 tlyq.ai(txjp 服务器) | 云端 |
|
||||
| `deploy-cc.sh` | 部署站点到 tlyq.cc(tgz 服务器) | 云端 |
|
||||
| `edit-site-cc.sh` | www.tlyq.cc 官网内容管理(新闻、联系方式等) | 云端 |
|
||||
| `backup-db.sh` | 备份 issue-ai 和 assets-ai 数据库 | 云端 → 本地 |
|
||||
| `restore-db.sh` | 恢复数据库(本地或云端) | 本地 / 云端 |
|
||||
| `backup-db.sh` | 备份数据库(assets / issue / ldap) | 云端 → 本地 |
|
||||
| `restore-db.sh` | 恢复数据库到本地或云端 | 本地 / 云端 |
|
||||
| `edit-site-cc.sh` | www.tlyq.cc 官网内容管理 | 云端 |
|
||||
|
||||
## 详细说明
|
||||
---
|
||||
|
||||
### local.sh — 本地站点管理
|
||||
## sites-manage-local.sh — 本地站点管理
|
||||
|
||||
```bash
|
||||
bash scripts/local.sh start # 启动所有站点
|
||||
bash scripts/local.sh stop # 停止所有站点
|
||||
bash scripts/local.sh restart issue # 重启指定站点
|
||||
bash scripts/local.sh status # 查看运行状态
|
||||
bash scripts/sites-manage-local.sh start # 启动全部
|
||||
bash scripts/sites-manage-local.sh start ai # 启动 ai 全部
|
||||
bash scripts/sites-manage-local.sh start ldap oa # 启动指定站点
|
||||
bash scripts/sites-manage-local.sh stop oa # 停止指定站点
|
||||
bash scripts/sites-manage-local.sh restart ldap # 重启指定站点
|
||||
bash scripts/sites-manage-local.sh status # 查看状态
|
||||
```
|
||||
|
||||
支持站点:www、cloud、token、issue、assets、ldap、oa。
|
||||
站点启动方式:
|
||||
|
||||
启动前自动检查是否有线上域名残留,防止本地开发时跳转到生产环境。
|
||||
| 站点 | 方式 | 端口 |
|
||||
|------|------|------|
|
||||
| ldap | Docker | 6178(Web UI)、3890(LDAP) |
|
||||
| oa | `npm run dev`(宿主机) | 6179 |
|
||||
| issue | `npm run dev`(宿主机) | 6176 |
|
||||
| assets | `npm run dev`(宿主机) | 6177 |
|
||||
| www / cloud / token | Docker | 6173–6175 |
|
||||
|
||||
### deploy-ai.sh — tlyq.ai 部署
|
||||
## sites-manage-cloud.sh — 云服务器站点管理
|
||||
|
||||
```bash
|
||||
bash scripts/sites-manage-cloud.sh start ai # 启动全部
|
||||
bash scripts/sites-manage-cloud.sh restart nginx # 重启 nginx
|
||||
bash scripts/sites-manage-cloud.sh stop oa issue # 停指定站点
|
||||
bash scripts/sites-manage-cloud.sh status # 查看状态
|
||||
```
|
||||
|
||||
自动检测运行环境:本地 Mac 运行时通过 SSH 操作 txjp,在云服务器上运行时直接操作本地 Docker。也可显式指定:
|
||||
|
||||
```bash
|
||||
OA_REMOTE=local bash scripts/sites-manage-cloud.sh status # 强制本地模式
|
||||
OA_REMOTE=ssh bash scripts/sites-manage-cloud.sh status # 强制 SSH 模式
|
||||
```
|
||||
|
||||
站点全部以 Docker 方式运行,依赖关系:`ldap → oa / issue / assets → nginx`。
|
||||
|
||||
## deploy-ai.sh — tlyq.ai 部署
|
||||
|
||||
```bash
|
||||
bash scripts/deploy-ai.sh # 自动检测:增量 or 完整构建
|
||||
|
|
@ -36,60 +63,52 @@ bash scripts/deploy-ai.sh --force # 强制完整构建
|
|||
bash scripts/deploy-ai.sh --restart # 仅重启容器
|
||||
```
|
||||
|
||||
交互式选择站点后执行:源码打包 → 上传 → 服务器构建 → 容器重启。部署 issue/assets 后自动验证 API 连通性(带重试机制)。
|
||||
交互式选择站点(1–7):www / cloud / token / issue / assets / oa / ldap。
|
||||
|
||||
> 详细文档见 [deploy-ai-readme.md](deploy-ai-readme.md)
|
||||
流程:源码打包 → 上传 → 服务器 `npm install` → `npm run build` → 容器重建。部署后自动验证。
|
||||
|
||||
### deploy-cc.sh — tlyq.cc 部署
|
||||
LDAP 部署特殊处理:上传 Dockerfile + docker-compose.yml,自动创建 .env,去除端口映射,`--build` 构建含 sqlite3 的镜像。
|
||||
|
||||
```bash
|
||||
bash scripts/deploy-cc.sh
|
||||
```
|
||||
|
||||
交互式选择站点后部署到 tlyq.cc(tgz 服务器),逻辑与 deploy-ai.sh 类似。
|
||||
|
||||
### edit-site-cc.sh — tlyq.cc 官网内容编辑
|
||||
|
||||
```bash
|
||||
bash scripts/edit-site-cc.sh
|
||||
```
|
||||
|
||||
交互式菜单编辑 www.tlyq.cc 的联系方式、新闻动态、时间线等内容,修改后自动部署。
|
||||
|
||||
### backup-db.sh — 数据库备份
|
||||
## backup-db.sh — 数据库备份
|
||||
|
||||
```bash
|
||||
bash scripts/backup-db.sh
|
||||
```
|
||||
|
||||
一键备份 issue-ai 和 assets-ai 的生产数据库:
|
||||
一键备份三个数据库:
|
||||
|
||||
1. 执行 WAL checkpoint 确保数据一致性
|
||||
2. 在云端 `/root/docker/db-backups/` 保留一份
|
||||
3. 下载到本地 `~/programs/docker/db-backups/`
|
||||
4. 验证备份文件为有效 SQLite 数据库
|
||||
| 数据库 | 服务 | 内容 |
|
||||
|--------|------|------|
|
||||
| assets-{时间戳}.db | assets-ai | 设备资产 |
|
||||
| issue-{时间戳}.db | issue-ai | 工单、配件 |
|
||||
| ldap-{时间戳}.db | lldap | **全部用户账号** |
|
||||
|
||||
### restore-db.sh — 数据库恢复
|
||||
流程:WAL checkpoint → 云端打包 → 云端持久保留 → 下载到本地 → 完整性验证。
|
||||
|
||||
> 详细文档见 [BACKUP-RESTORE.md](../docs/BACKUP-RESTORE.md)
|
||||
|
||||
## restore-db.sh — 数据库恢复
|
||||
|
||||
```bash
|
||||
# 恢复本地数据库
|
||||
bash scripts/restore-db.sh local issue issue-20260515_163059.db
|
||||
|
||||
# 恢复云端数据库
|
||||
bash scripts/restore-db.sh cloud assets assets-20260515_163059.db
|
||||
bash scripts/restore-db.sh cloud issue issue-20260518_1200.db
|
||||
bash scripts/restore-db.sh cloud ldap ldap-20260518_1200.db
|
||||
|
||||
# 恢复本地数据库
|
||||
bash scripts/restore-db.sh local assets assets-20260518_1200.db
|
||||
```
|
||||
|
||||
恢复流程:停止容器 → 备份当前库 → 替换 → 清理 WAL/SHM → 启动 → 验证。支持 `issue` 和 `assets` 两个服务。
|
||||
支持服务:`assets` / `issue` / `ldap`。流程:检查 → 验证 → 确认 → 备份当前库 → 停止容器 → 替换 → 清理 WAL → 启动 → 验证。
|
||||
|
||||
## 备份存储路径
|
||||
|
||||
| 位置 | 路径 |
|
||||
|------|------|
|
||||
| 云端持久备份 | `/root/docker/db-backups/` |
|
||||
| 本地备份 | `~/programs/docker/db-backups/` |
|
||||
| 云端临时(传输中) | `/tmp/db-backup/`(完成后清理) |
|
||||
| 本地备份 | `db-backups/` |
|
||||
| 云端临时 | `/tmp/db-backup/`(完成后清理) |
|
||||
|
||||
## 依赖
|
||||
|
||||
- **本地**:macOS / Linux,bash,ssh(配置 `txjp` 和 `tgz` 别名),scp,docker
|
||||
- **本地**:macOS / Linux,bash,ssh(配置 `txjp` 和 `tgz` 别名),scp,docker,sqlite3
|
||||
- **云端**:Docker Compose,Node.js,better-sqlite3
|
||||
|
|
|
|||
15
backup-db.sh
15
backup-db.sh
|
|
@ -16,11 +16,14 @@ log "执行 WAL checkpoint (assets)..."
|
|||
ssh txjp "docker exec assets-ai node -e \"const D=require('better-sqlite3');const db=new D('/app/data/assets.db');db.pragma('wal_checkpoint(TRUNCATE)');db.close();\""
|
||||
log "执行 WAL checkpoint (issue)..."
|
||||
ssh txjp "docker exec issue-ai node -e \"const D=require('better-sqlite3');const db=new D('/app/data/issue.db');db.pragma('wal_checkpoint(TRUNCATE)');db.close();\""
|
||||
log "执行 WAL checkpoint (LLDAP)..."
|
||||
ssh txjp "docker exec lldap sqlite3 /data/users.db 'PRAGMA wal_checkpoint(TRUNCATE);' 2>/dev/null || true"
|
||||
|
||||
# 云端打包
|
||||
ssh txjp "mkdir -p /tmp/db-backup && \
|
||||
cp /root/docker/assets-ai/data/assets.db /tmp/db-backup/assets-${TIMESTAMP}.db && \
|
||||
cp /root/docker/issue-ai/data/issue.db /tmp/db-backup/issue-${TIMESTAMP}.db"
|
||||
cp /root/docker/issue-ai/data/issue.db /tmp/db-backup/issue-${TIMESTAMP}.db && \
|
||||
docker cp lldap:/data/users.db /tmp/db-backup/ldap-${TIMESTAMP}.db 2>/dev/null || cp /root/docker/ldap-ai/data/lldap/users.db /tmp/db-backup/ldap-${TIMESTAMP}.db"
|
||||
|
||||
# 确保本地备份目录存在
|
||||
mkdir -p "${LOCAL_DIR}"
|
||||
|
|
@ -29,7 +32,8 @@ mkdir -p "${LOCAL_DIR}"
|
|||
CLOUD_DIR="/root/docker/db-backups"
|
||||
ssh txjp "mkdir -p ${CLOUD_DIR} && \
|
||||
cp /tmp/db-backup/assets-${TIMESTAMP}.db ${CLOUD_DIR}/assets-${TIMESTAMP}.db && \
|
||||
cp /tmp/db-backup/issue-${TIMESTAMP}.db ${CLOUD_DIR}/issue-${TIMESTAMP}.db"
|
||||
cp /tmp/db-backup/issue-${TIMESTAMP}.db ${CLOUD_DIR}/issue-${TIMESTAMP}.db && \
|
||||
cp /tmp/db-backup/ldap-${TIMESTAMP}.db ${CLOUD_DIR}/ldap-${TIMESTAMP}.db"
|
||||
log "云端备份已保存至: ${CLOUD_DIR}"
|
||||
|
||||
# 复制到本地
|
||||
|
|
@ -37,10 +41,11 @@ log "复制到本地..."
|
|||
mkdir -p "${LOCAL_DIR}"
|
||||
scp "txjp:/tmp/db-backup/assets-${TIMESTAMP}.db" "${LOCAL_DIR}/"
|
||||
scp "txjp:/tmp/db-backup/issue-${TIMESTAMP}.db" "${LOCAL_DIR}/"
|
||||
scp "txjp:/tmp/db-backup/ldap-${TIMESTAMP}.db" "${LOCAL_DIR}/"
|
||||
|
||||
# 验证备份文件为有效 SQLite 数据库
|
||||
log "验证备份完整性..."
|
||||
for f in "${LOCAL_DIR}/assets-${TIMESTAMP}.db" "${LOCAL_DIR}/issue-${TIMESTAMP}.db"; do
|
||||
for f in "${LOCAL_DIR}/assets-${TIMESTAMP}.db" "${LOCAL_DIR}/issue-${TIMESTAMP}.db" "${LOCAL_DIR}/ldap-${TIMESTAMP}.db"; do
|
||||
if ! sqlite3 "$f" "SELECT count(*) FROM sqlite_master" > /dev/null 2>&1; then
|
||||
echo "[错误] 备份文件无效或损坏: $f"
|
||||
exit 1
|
||||
|
|
@ -53,6 +58,6 @@ ssh txjp "rm -rf /tmp/db-backup"
|
|||
|
||||
log "备份完成:${TIMESTAMP}"
|
||||
echo " 云端: ${CLOUD_DIR}/"
|
||||
ssh txjp "ls -lh ${CLOUD_DIR}/assets-${TIMESTAMP}.db ${CLOUD_DIR}/issue-${TIMESTAMP}.db 2>/dev/null"
|
||||
ssh txjp "ls -lh ${CLOUD_DIR}/assets-${TIMESTAMP}.db ${CLOUD_DIR}/issue-${TIMESTAMP}.db ${CLOUD_DIR}/ldap-${TIMESTAMP}.db 2>/dev/null"
|
||||
echo " 本地:"
|
||||
ls -lh "${LOCAL_DIR}"/assets-${TIMESTAMP}.db "${LOCAL_DIR}"/issue-${TIMESTAMP}.db 2>/dev/null
|
||||
ls -lh "${LOCAL_DIR}"/assets-${TIMESTAMP}.db "${LOCAL_DIR}"/issue-${TIMESTAMP}.db "${LOCAL_DIR}"/ldap-${TIMESTAMP}.db 2>/dev/null
|
||||
|
|
|
|||
28
deploy-ai.sh
28
deploy-ai.sh
|
|
@ -66,8 +66,9 @@ echo " 3) token.tlyq.ai (Token工厂)"
|
|||
echo " 4) issue.tlyq.ai (工单系统)"
|
||||
echo " 5) assets.tlyq.ai (资产管理系统)"
|
||||
echo " 6) oa.tlyq.ai (OA 统一门户 — 含 nginx 配置)"
|
||||
echo " 7) ldap.tlyq.ai (LLDAP 用户目录服务)"
|
||||
echo ""
|
||||
printf "请输入编号 (1/2/3/4/5/6): "
|
||||
printf "请输入编号 (1/2/3/4/5/6/7): "
|
||||
read choice
|
||||
|
||||
SITE=""; LOCAL_DIR=""; REMOTE_DIR=""; CONTAINER=""
|
||||
|
|
@ -78,6 +79,7 @@ case "$choice" in
|
|||
4) SITE="issue"; LOCAL_DIR="/Users/niuniu/programs/docker/issue-ai"; REMOTE_DIR="/root/docker/issue-ai"; CONTAINER="issue-ai" ;;
|
||||
5) SITE="assets"; LOCAL_DIR="/Users/niuniu/programs/docker/assets-ai"; REMOTE_DIR="/root/docker/assets-ai"; CONTAINER="assets-ai" ;;
|
||||
6) SITE="oa"; LOCAL_DIR="/Users/niuniu/programs/docker/oa-ai"; REMOTE_DIR="/root/docker/oa-ai"; CONTAINER="oa-ai" ;;
|
||||
7) SITE="ldap"; LOCAL_DIR="/Users/niuniu/programs/docker/ldap-ai"; REMOTE_DIR="/root/docker/ldap-ai"; CONTAINER="lldap" ;;
|
||||
*) echo "无效选择"; exit 1 ;;
|
||||
esac
|
||||
|
||||
|
|
@ -419,6 +421,23 @@ CHECKEOF
|
|||
info "部署 nginx 配置..."
|
||||
ssh txjp "cp $REMOTE_DIR/../nginx-proxy-ai/conf.d/oa-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" ;;
|
||||
ldap)
|
||||
info "部署 LLDAP..."
|
||||
scp "$LOCAL_DIR/docker-compose.yml" txjp:$REMOTE_DIR/docker-compose.yml
|
||||
scp "$LOCAL_DIR/Dockerfile" txjp:$REMOTE_DIR/Dockerfile
|
||||
ssh txjp "cd $REMOTE_DIR && \
|
||||
if [ ! -f .env ]; then \
|
||||
echo 'LLDAP_JWT_SECRET='\$(docker exec lldap printenv LLDAP_JWT_SECRET 2>/dev/null) > .env && \
|
||||
echo 'LLDAP_LDAP_USER_PASS='\$(docker exec lldap printenv LLDAP_LDAP_USER_PASS 2>/dev/null) >> .env && \
|
||||
echo 'LLDAP_LDAP_BASE_DN=dc=tlyq,dc=ai' >> .env && \
|
||||
echo 'LLDAP_HTTP_PORT=17170' >> .env && \
|
||||
echo 'LLDAP_LDAP_PORT=3890' >> .env && \
|
||||
echo 'LLDAP_DATABASE_PATH=/data/users.db' >> .env && \
|
||||
echo 'LLDAP_ADMIN_PASSWORD='\$(docker exec lldap printenv LLDAP_ADMIN_PASSWORD 2>/dev/null) >> .env && \
|
||||
fi && \
|
||||
sed -i '/3890:3890/d' docker-compose.yml 2>/dev/null || true && \
|
||||
docker compose up -d --build && docker compose restart"
|
||||
log "LLDAP 已部署" ;;
|
||||
esac
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -437,9 +456,14 @@ case "$SITE" in
|
|||
issue) URL="https://issue.tlyq.ai" ;;
|
||||
assets) URL="https://assets.tlyq.ai" ;;
|
||||
oa) URL="https://oa.tlyq.ai" ;;
|
||||
ldap) URL="http://localhost:6178" ;;
|
||||
esac
|
||||
|
||||
STATUS=$(ssh txjp "curl -s -o /dev/null -w '%{http_code}' -k '$URL' 2>/dev/null" 2>/dev/null || echo "???")
|
||||
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 "???")
|
||||
else
|
||||
STATUS=$(ssh txjp "curl -s -o /dev/null -w '%{http_code}' -k '$URL' 2>/dev/null" 2>/dev/null || echo "???")
|
||||
fi
|
||||
if [[ "$STATUS" == "200" || "$STATUS" == "307" || "$STATUS" == "301" ]]; then
|
||||
log "部署成功!总耗时: ${TOTAL_DUR}s | 访问 $URL"
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -6,21 +6,23 @@
|
|||
# 恢复本地数据库: bash scripts/restore-db.sh local <服务名> <备份文件名>
|
||||
# 恢复云端数据库: bash scripts/restore-db.sh cloud <服务名> <备份文件名>
|
||||
#
|
||||
# 服务名: issue / assets
|
||||
# 服务名: issue / assets / ldap
|
||||
#
|
||||
# 示例:
|
||||
# bash scripts/restore-db.sh local issue issue-2026-04-29_1753.db
|
||||
# bash scripts/restore-db.sh cloud assets assets-2026-04-29_1753.db
|
||||
# bash scripts/restore-db.sh cloud ldap ldap-2026-05-15_1200.db
|
||||
# ============================================
|
||||
|
||||
set -e
|
||||
|
||||
# ---- 参数检查 ----
|
||||
if [ $# -lt 3 ]; then
|
||||
echo "用法: $0 <local|cloud> <issue|assets> <备份文件名>"
|
||||
echo "用法: $0 <local|cloud> <issue|assets|ldap> <备份文件名>"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 local issue issue-2026-04-29_1753.db"
|
||||
echo " $0 cloud ldap ldap-2026-05-15_1200.db"
|
||||
echo " $0 cloud assets assets-2026-04-29_1753.db"
|
||||
echo ""
|
||||
echo "可用备份文件:"
|
||||
|
|
@ -52,8 +54,14 @@ case $SERVICE in
|
|||
DB_PATH_IN_CONTAINER="/app/data/assets.db"
|
||||
LOCAL_DB_PATH="/Users/niuniu/programs/docker/assets-ai/data/assets.db"
|
||||
;;
|
||||
ldap)
|
||||
PROJECT_DIR="ldap-ai"
|
||||
CONTAINER="lldap"
|
||||
DB_PATH_IN_CONTAINER="/data/users.db"
|
||||
LOCAL_DB_PATH="/Users/niuniu/programs/docker/ldap-ai/data/lldap/users.db"
|
||||
;;
|
||||
*)
|
||||
echo "错误: 服务名必须是 issue 或 assets"
|
||||
echo "错误: 服务名必须是 issue、assets 或 ldap"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -0,0 +1,214 @@
|
|||
#!/bin/bash
|
||||
# 站点管理脚本(自动适配本地/云端)
|
||||
#
|
||||
# 本地 Mac 运行 → 通过 SSH 操作 txjp 服务器
|
||||
# 云服务器运行 → 直接操作本地 Docker
|
||||
#
|
||||
# 用法:bash sites-manage-cloud.sh <命令> [站点名...]
|
||||
# 站点名:ldap www cloud token gitea issue assets oa nginx
|
||||
# ai(上述全部)、all(同 ai)
|
||||
|
||||
set -e
|
||||
|
||||
# ============================================================
|
||||
# 自动检测运行环境
|
||||
#
|
||||
# 优先级:
|
||||
# 1. OA_REMOTE 环境变量 — "local" 强制本地 / "ssh" 强制远程
|
||||
# 2. hostname 匹配 — 包含 "Tencent" 则判为云服务器本地
|
||||
# 3. 以上都不满足 → SSH 远程模式
|
||||
# ============================================================
|
||||
THIS_HOST=$(hostname 2>/dev/null || uname -n 2>/dev/null || echo "")
|
||||
|
||||
if [ "$OA_REMOTE" = "local" ]; then
|
||||
IS_LOCAL_SERVER=true
|
||||
LABEL="txjp(本地运行 · 手动指定)"
|
||||
elif [ "$OA_REMOTE" = "ssh" ]; then
|
||||
IS_LOCAL_SERVER=false
|
||||
SERVER="txjp"
|
||||
LABEL="txjp(SSH 远程 · 手动指定)"
|
||||
elif echo "$THIS_HOST" | grep -qi "Tencent"; then
|
||||
IS_LOCAL_SERVER=true
|
||||
LABEL="txjp(本地运行 · 自动检测)"
|
||||
else
|
||||
IS_LOCAL_SERVER=false
|
||||
SERVER="txjp"
|
||||
LABEL="txjp(SSH 远程 · 自动检测)"
|
||||
fi
|
||||
|
||||
# 执行命令:服务器本地直接跑,否则 SSH
|
||||
run() {
|
||||
if $IS_LOCAL_SERVER; then
|
||||
bash -c "$*"
|
||||
else
|
||||
ssh $SERVER "$*"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE="/root/docker"
|
||||
|
||||
# 站点 → 目录 & 容器名
|
||||
declare -A SITE_DIR
|
||||
SITE_DIR[ldap]="ldap-ai"
|
||||
SITE_DIR[www]="www-ai"
|
||||
SITE_DIR[cloud]="cloud-ai"
|
||||
SITE_DIR[token]="token-ai"
|
||||
SITE_DIR[gitea]="gitea-ai"
|
||||
SITE_DIR[issue]="issue-ai"
|
||||
SITE_DIR[assets]="assets-ai"
|
||||
SITE_DIR[oa]="oa-ai"
|
||||
SITE_DIR[nginx]="nginx-proxy-ai"
|
||||
SITE_DIR[sso]="sso-ai"
|
||||
|
||||
declare -A SITE_CONTAINER
|
||||
SITE_CONTAINER[ldap]="lldap"
|
||||
SITE_CONTAINER[www]="www-ai"
|
||||
SITE_CONTAINER[cloud]="cloud-ai"
|
||||
SITE_CONTAINER[token]="token-ai"
|
||||
SITE_CONTAINER[gitea]="gitea-ai"
|
||||
SITE_CONTAINER[issue]="issue-ai"
|
||||
SITE_CONTAINER[assets]="assets-ai"
|
||||
SITE_CONTAINER[oa]="oa-ai"
|
||||
SITE_CONTAINER[nginx]="nginx-ai"
|
||||
SITE_CONTAINER[sso]="sso-ai"
|
||||
|
||||
AI_SITES="ldap www cloud token gitea issue assets oa nginx"
|
||||
|
||||
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"; }
|
||||
warn() { printf "${YELLOW}[!]${NC} %s\n" "$1"; }
|
||||
err() { printf "${RED}[✗]${NC} %s\n" "$1"; }
|
||||
|
||||
expand_sites() {
|
||||
local result=()
|
||||
for s in "$@"; do
|
||||
case $s in
|
||||
ai|all) for x in $AI_SITES; do result+=("$x"); done ;;
|
||||
*) result+=("$s") ;;
|
||||
esac
|
||||
done
|
||||
echo "${result[@]}"
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 操作
|
||||
# ============================================================
|
||||
remote_start() {
|
||||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
||||
local container="${SITE_CONTAINER[$name]}"
|
||||
|
||||
if run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||||
warn "$name 已在运行"
|
||||
return
|
||||
fi
|
||||
log "启动 $name ..."
|
||||
run "cd $dir && docker compose up -d" 2>/dev/null && log "$name 已启动" || err "$name 启动失败"
|
||||
}
|
||||
|
||||
remote_stop() {
|
||||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
||||
local container="${SITE_CONTAINER[$name]}"
|
||||
|
||||
if ! run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||||
warn "$name 未在运行"
|
||||
return
|
||||
fi
|
||||
log "停止 $name ..."
|
||||
run "cd $dir && docker compose down" 2>/dev/null && log "$name 已停止" || err "$name 停止失败"
|
||||
}
|
||||
|
||||
remote_status() {
|
||||
local targets=("$@")
|
||||
echo ""
|
||||
printf "${CYAN}=========================================${NC}\n"
|
||||
printf "${CYAN} 站点状态 — ${LABEL}${NC}\n"
|
||||
printf "${CYAN}=========================================${NC}\n"
|
||||
echo ""
|
||||
|
||||
for name in "${targets[@]}"; do
|
||||
local container="${SITE_CONTAINER[$name]}"
|
||||
local status
|
||||
status=$(run "docker ps --format '{{.Status}}' -f name=^${container}$" 2>/dev/null || echo "")
|
||||
if [ -n "$status" ]; then
|
||||
printf " ${GREEN}●${NC} %-8s 运行中 (%s)\n" "$name" "$status"
|
||||
else
|
||||
printf " ${RED}●${NC} %-8s 未运行\n" "$name"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_help() {
|
||||
echo ""
|
||||
printf "${CYAN}用法:${NC} bash sites-manage-cloud.sh <命令> [站点名...]\n"
|
||||
echo ""
|
||||
echo " 当前环境: ${LABEL}"
|
||||
echo ""
|
||||
echo " 命令:"
|
||||
echo " start 启动站点"
|
||||
echo " stop 停止站点"
|
||||
echo " restart 重启站点"
|
||||
echo " status 查看状态"
|
||||
echo ""
|
||||
echo " 站点名(可指定多个,空格分隔):"
|
||||
echo " ldap LLDAP 用户目录"
|
||||
echo " www tlyq.ai 官网"
|
||||
echo " cloud 云平台登录页"
|
||||
echo " token Token 工厂登录页"
|
||||
echo " gitea Gitea 代码托管"
|
||||
echo " issue 工单系统"
|
||||
echo " assets 设备资产管理"
|
||||
echo " oa OA 统一门户"
|
||||
echo " nginx 反向代理"
|
||||
echo " ai 全部 tlyq.ai 站点"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " bash sites-manage-cloud.sh start ai # 启动全部"
|
||||
echo " bash sites-manage-cloud.sh restart nginx # 重启 nginx"
|
||||
echo " bash sites-manage-cloud.sh stop oa issue # 停 OA + 工单"
|
||||
echo " bash sites-manage-cloud.sh status # 查看所有状态"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 入口
|
||||
# ============================================================
|
||||
ACTION=${1:-}
|
||||
shift || true
|
||||
|
||||
if [ -z "$ACTION" ]; then
|
||||
show_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mapfile -t TARGETS < <(expand_sites "$@")
|
||||
if [ ${#TARGETS[@]} -eq 0 ]; then
|
||||
mapfile -t TARGETS < <(expand_sites ai)
|
||||
fi
|
||||
|
||||
case $ACTION in
|
||||
start)
|
||||
for s in "${TARGETS[@]}"; do remote_start "$s"; done
|
||||
;;
|
||||
stop)
|
||||
for s in "${TARGETS[@]}"; do remote_stop "$s"; done
|
||||
;;
|
||||
restart)
|
||||
for s in "${TARGETS[@]}"; do remote_stop "$s"; done
|
||||
echo ""
|
||||
log "等待 2 秒后启动..."
|
||||
sleep 2
|
||||
for s in "${TARGETS[@]}"; do remote_start "$s"; done
|
||||
;;
|
||||
status)
|
||||
remote_status "${TARGETS[@]}"
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
err "未知命令: $ACTION"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
# 本地站点管理:启动 / 停止 / 重启 / 状态
|
||||
# 用法:bash local.sh [start|stop|restart|status] [站点名...]
|
||||
# 用法:bash sites-manage-local.sh [start|stop|restart|status] [站点名...]
|
||||
# 不加参数则交互选择
|
||||
#
|
||||
# 站点名:
|
||||
|
|
@ -237,7 +237,7 @@ show_status() {
|
|||
# ============================================================
|
||||
show_help() {
|
||||
echo ""
|
||||
printf "${CYAN}用法:${NC} bash local.sh <命令> [站点名...]\n"
|
||||
printf "${CYAN}用法:${NC} bash sites-manage-local.sh <命令> [站点名...]\n"
|
||||
echo ""
|
||||
echo " 命令:"
|
||||
echo " start 启动站点"
|
||||
|
|
@ -253,11 +253,11 @@ show_help() {
|
|||
echo " all — 全部站点"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " bash local.sh start all # 启动全部"
|
||||
echo " bash local.sh start ai # 启动 ai 全部"
|
||||
echo " bash local.sh start issue assets # 只启 issue + assets"
|
||||
echo " bash local.sh stop www-ai # 只停 www-ai"
|
||||
echo " bash local.sh status # 查看所有状态"
|
||||
echo " bash sites-manage-local.sh start all # 启动全部"
|
||||
echo " bash sites-manage-local.sh start ai # 启动 ai 全部"
|
||||
echo " bash sites-manage-local.sh start issue assets # 只启 issue + assets"
|
||||
echo " bash sites-manage-local.sh stop www-ai # 只停 www-ai"
|
||||
echo " bash sites-manage-local.sh status # 查看所有状态"
|
||||
echo ""
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue