mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 07:22:49 +08:00
- 新增 source/stack/docker-dev-sync/ 模式目录 - 宿主代码映射到 /var/www/source(bind mount 中转) - 容器内 rsync 定时同步到 /var/www/html(原生文件系统) - vendor 由 Docker build 管理,不参与同步 - rsync 使用 --no-perms 避免保留 Windows 源文件权限 - 排除 docker-dev/、runtime/、.git/ 等无关目录 - SYNC_INTERVAL 环境变量可配置轮询间隔(默认 3 秒) - 更新 stack.json 注册模式并声明 sync.sh 为托管文件 - 调整 CI 构建流程:先安装依赖再切换 stack 模式
130 lines
3.5 KiB
Bash
130 lines
3.5 KiB
Bash
#!/bin/bash
|
|
|
|
# ============================================
|
|
# sync.sh - Host-to-Container code sync script
|
|
# ============================================
|
|
# Syncs code from /var/www/source (bind mount from host)
|
|
# to /var/www/html (container-native filesystem, fast I/O).
|
|
#
|
|
# Usage:
|
|
# sync.sh init - Perform initial full sync, then exit
|
|
# sync.sh watch - Run periodic incremental sync (blocking)
|
|
# sync.sh - Same as: init + watch
|
|
#
|
|
# Environment variables:
|
|
# SYNC_INTERVAL - Polling interval in seconds (default: 3)
|
|
# SYNC_EXTRAS - Additional rsync exclude patterns (space-separated)
|
|
# ============================================
|
|
|
|
SOURCE_DIR="/var/www/source/"
|
|
TARGET_DIR="/var/www/html/"
|
|
SYNC_INTERVAL=${SYNC_INTERVAL:-3}
|
|
|
|
# Build rsync exclude patterns
|
|
build_exclude_args() {
|
|
EXCLUDE_ARGS=(
|
|
--exclude='.git'
|
|
--exclude='.gitignore'
|
|
--exclude='.sisyphus'
|
|
--exclude='.opencode'
|
|
--exclude='.agents'
|
|
--exclude='.docker-dev-sync'
|
|
--exclude='.docker-dev.env'
|
|
--exclude='.docker-dev'
|
|
--exclude='docker-dev'
|
|
--exclude='docker-dev-sync'
|
|
--exclude='node_modules'
|
|
--exclude='runtime'
|
|
--exclude='.idea'
|
|
--exclude='.vscode'
|
|
--exclude='*.sock'
|
|
--exclude='.env'
|
|
# vendor is managed by Docker build (composer install), do not overwrite
|
|
--exclude='vendor'
|
|
)
|
|
|
|
# Add extra excludes if provided
|
|
if [ -n "$SYNC_EXTRAS" ]; then
|
|
for pattern in $SYNC_EXTRAS; do
|
|
EXCLUDE_ARGS+=(--exclude="$pattern")
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Sync .env separately (excluded from rsync to avoid overwriting on rebuild)
|
|
sync_env() {
|
|
if [ -f "/var/www/source/.env" ]; then
|
|
cp /var/www/source/.env /var/www/html/.env 2>/dev/null
|
|
fi
|
|
}
|
|
|
|
# rsync common flags
|
|
# --no-perms --no-owner --no-group: don't preserve source permissions (Windows mounts have bad perms)
|
|
RSYNC_FLAGS="-a --no-perms --no-owner --no-group"
|
|
|
|
# ---- Initial full sync ----
|
|
do_init() {
|
|
build_exclude_args
|
|
|
|
echo "============================================"
|
|
echo "[sync] Starting initial full sync..."
|
|
echo "[sync] Source: ${SOURCE_DIR}"
|
|
echo "[sync] Target: ${TARGET_DIR}"
|
|
echo "============================================"
|
|
|
|
rsync ${RSYNC_FLAGS} --delete "${EXCLUDE_ARGS[@]}" "$SOURCE_DIR" "$TARGET_DIR"
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "[sync] Initial sync complete."
|
|
else
|
|
echo "[sync] WARNING: Initial sync had errors (source may not be mounted yet)."
|
|
fi
|
|
|
|
sync_env
|
|
}
|
|
|
|
# ---- Periodic incremental sync (blocking) ----
|
|
do_watch() {
|
|
build_exclude_args
|
|
|
|
echo "[sync] Starting periodic sync (interval: ${SYNC_INTERVAL}s)..."
|
|
|
|
while true; do
|
|
sleep "$SYNC_INTERVAL"
|
|
|
|
# Check if source directory is mounted and accessible
|
|
if [ ! -d "/var/www/source" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Incremental sync (only changed files)
|
|
rsync ${RSYNC_FLAGS} --delete "${EXCLUDE_ARGS[@]}" "$SOURCE_DIR" "$TARGET_DIR" 2>/dev/null
|
|
|
|
# Sync .env separately
|
|
sync_env
|
|
done
|
|
}
|
|
|
|
# ---- Main ----
|
|
MODE="${1:-all}"
|
|
|
|
case "$MODE" in
|
|
init)
|
|
do_init
|
|
;;
|
|
watch)
|
|
do_watch
|
|
;;
|
|
all|"")
|
|
do_init
|
|
do_watch
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [init|watch]"
|
|
echo " init - Initial full sync, then exit"
|
|
echo " watch - Periodic incremental sync (blocking)"
|
|
echo " (no args) - init + watch"
|
|
exit 1
|
|
;;
|
|
esac
|