Add high-reliability 30s auto-sync configuration (Systemd Timer)

This commit is contained in:
2025-12-27 22:29:15 +11:00
parent f253b8678f
commit aebd9934e5
5 changed files with 211 additions and 80 deletions

View File

@@ -273,86 +273,93 @@ curl -I http://localhost
--- ---
## 🔄 Step 6: Setup Auto-Sync (Every 5 Minutes) ## 🔄 Step 6: Setup Auto-Sync (Every 30 Seconds)
### 6.1 Create auto-sync script We use **Systemd Timers** instead of Cron because they support sub-minute intervals and prevent overlapping execution.
```bash ### 6.1 Create robust auto-sync script
cat > /var/www/your-app-name/auto-sync.sh << 'EOF'
#!/bin/bash ```bash
cat > /var/www/your-app-name/auto-sync.sh << 'EOF'
set -e #!/bin/bash
APP_NAME="your-app-name" # Configuration
APP_DIR="/var/www/$APP_NAME" APP_NAME="your-app-name"
LOG_FILE="/var/log/$APP_NAME-autosync.log" APP_DIR="/var/www/$APP_NAME"
LOG_FILE="/var/log/$APP_NAME-autosync.log"
log() { LOCK_FILE="/var/lock/$APP_NAME-sync.lock"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
} # Singleton execution with flock (prevents overlap)
exec 9>"$LOCK_FILE"
log "=========================================" if ! flock -n 9; then
log "Starting auto-sync check..." exit 0
fi
cd "$APP_DIR" || exit 1
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"; }
# Fetch latest from remote
git fetch origin main 2>&1 | tee -a "$LOG_FILE" cd "$APP_DIR" || exit 1
# Check if local is behind remote # Fetch and check
LOCAL=$(git rev-parse HEAD) if ! git fetch origin main --quiet; then exit 1; fi
REMOTE=$(git rev-parse origin/main)
LOCAL=$(git rev-parse HEAD)
if [ "$LOCAL" = "$REMOTE" ]; then REMOTE=$(git rev-parse origin/main)
log "✅ Already up to date. No changes detected."
exit 0 if [ "$LOCAL" != "$REMOTE" ]; then
fi log "🔄 Changes detected! Pulling..."
git pull origin main >> "$LOG_FILE" 2>&1
log "🔄 Changes detected! Pulling updates..."
if git diff --name-only "$LOCAL" "$REMOTE" | grep -q "package.json"; then
# Pull changes log "📦 package.json changed. Installing dependencies..."
git pull origin main 2>&1 | tee -a "$LOG_FILE" npm install --production >> "$LOG_FILE" 2>&1 || exit 1
fi
# Install/update dependencies if package.json changed
if git diff --name-only $LOCAL $REMOTE | grep -q "package.json"; then log "🔄 Restarting service..."
log "📦 package.json changed. Running npm install..." systemctl restart "$APP_NAME"
npm install 2>&1 | tee -a "$LOG_FILE" log "✅ Sync complete."
fi fi
EOF
# Restart the service
log "🔄 Restarting $APP_NAME service..." chmod +x /var/www/your-app-name/auto-sync.sh
systemctl restart "$APP_NAME" 2>&1 | tee -a "$LOG_FILE" ```
# Wait and check status ### 6.2 Create Systemd Timer Units
sleep 2
if systemctl is-active --quiet "$APP_NAME"; then Create the Service (What to run):
log "✅ Service restarted successfully!" ```bash
else cat > /etc/systemd/system/your-app-name-sync.service << 'EOF'
log "❌ WARNING: Service may have failed to start!" [Unit]
systemctl status "$APP_NAME" --no-pager 2>&1 | tee -a "$LOG_FILE" Description=Auto-sync Service
fi [Service]
Type=oneshot
log "✅ Auto-sync completed!" ExecStart=/var/www/your-app-name/auto-sync.sh
log "=========================================" User=root
EOF EOF
```
# Make executable
chmod +x /var/www/your-app-name/auto-sync.sh Create the Timer (When to run):
```bash
# Create log file cat > /etc/systemd/system/your-app-name-sync.timer << 'EOF'
touch /var/log/your-app-name-autosync.log [Unit]
chmod 644 /var/log/your-app-name-autosync.log Description=Run auto-sync every 30 seconds
```
[Timer]
### 6.2 Add to crontab OnBootSec=1min
OnUnitActiveSec=30s
```bash Unit=your-app-name-sync.service
# Add cron job (every 5 minutes)
echo "*/5 * * * * cd /var/www/your-app-name && /bin/bash auto-sync.sh" | crontab - [Install]
WantedBy=timers.target
# Verify it was added EOF
crontab -l ```
```
### 6.3 Enable the Timer
```bash
systemctl daemon-reload
systemctl enable --now your-app-name-sync.timer
systemctl list-timers --all
```
--- ---

66
auto-sync-robust.sh Normal file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
# Configuration
APP_NAME="web-page-performance-test"
APP_DIR="/var/www/$APP_NAME"
LOG_FILE="/var/log/$APP_NAME-autosync.log"
LOCK_FILE="/var/lock/$APP_NAME-sync.lock"
# Singleton execution with flock
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
# Lock is busy, skip this run (logging optional to avoid spam)
exit 0
fi
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# Ensure we are in the correct directory
cd "$APP_DIR" || { log "❌ Error: Could not change to $APP_DIR"; exit 1; }
# Fetch remote updates
if ! git fetch origin main --quiet; then
log "❌ Error: Git fetch failed"
exit 1
fi
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse origin/main)
if [ "$LOCAL" = "$REMOTE" ]; then
# No changes, exit silently
exit 0
fi
log "🔄 Changes detected! Local: ${LOCAL:0:7} -> Remote: ${REMOTE:0:7}"
# Pull changes
if ! git pull origin main; then
log "❌ Error: Git pull failed"
exit 1
fi
# Check for dependency changes
RESTART_NEEDED=false
if git diff --name-only "$LOCAL" "$REMOTE" | grep -q "package.json"; then
log "📦 package.json changed. Running npm install..."
if npm install --production; then
RESTART_NEEDED=true
else
log "❌ Error: npm install failed"
fi
else
RESTART_NEEDED=true
fi
# Restart service if needed
if [ "$RESTART_NEEDED" = true ]; then
log "🔄 Restarting service..."
if systemctl restart "$APP_NAME"; then
log "✅ Service restarted successfully"
else
log "❌ Error: Failed to restart service"
fi
fi

38
deploy-sync-upgrade.ps1 Normal file
View File

@@ -0,0 +1,38 @@
$Server = "172.16.69.219"
$User = "root"
$Pass = "Q4dv!Z`$nCe#`$OT&h"
$RemotePath = "/var/www/web-page-performance-test"
function Send-File {
param($LocalFile, $RemotePath)
echo "📄 Sending $LocalFile..."
Get-Content -Raw $LocalFile | plink -batch -pw "$Pass" "$User@$Server" "cat > $RemotePath"
if ($LASTEXITCODE -ne 0) { throw "Failed to send $LocalFile" }
}
try {
# Copy files via plink pipe (more reliable than pscp here)
Send-File ".\auto-sync-robust.sh" "$RemotePath/auto-sync.sh"
Send-File ".\web-page-performance-test-sync.service" "/etc/systemd/system/web-page-performance-test-sync.service"
Send-File ".\web-page-performance-test-sync.timer" "/etc/systemd/system/web-page-performance-test-sync.timer"
# Configure server
echo "⚙️ Configuring Systemd Timer on server..."
$Commands = @(
"chmod +x $RemotePath/auto-sync.sh",
"crontab -l | grep -v 'auto-sync.sh' | crontab -", # Remove old cron job
"systemctl daemon-reload",
"systemctl enable web-page-performance-test-sync.timer",
"systemctl start web-page-performance-test-sync.timer",
"systemctl status web-page-performance-test-sync.timer --no-pager",
"echo '✅ Systemd Timer Upgrade Complete!'"
)
$CommandStr = $Commands -join " && "
plink -batch -pw "$Pass" "$User@$Server" $CommandStr
}
catch {
echo "❌ Error: $_"
exit 1
}

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Auto-sync Web Page Performance Test from GitHub
After=network.target
[Service]
Type=oneshot
ExecStart=/var/www/web-page-performance-test/auto-sync.sh
User=root
StandardOutput=append:/var/log/web-page-performance-test-autosync.log
StandardError=append:/var/log/web-page-performance-test-autosync.log

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Run auto-sync every 30 seconds
[Timer]
OnBootSec=1min
OnUnitActiveSec=30s
Unit=web-page-performance-test-sync.service
[Install]
WantedBy=timers.target