Testing: - Add pytest configuration (pytest.ini) - Add test fixtures (tests/conftest.py) - Add ContentGenerator tests (13 tests) - Add ContentScheduler tests (16 tests) - Add PublisherManager tests (16 tests) - All 45 tests passing Production Docker: - Add docker-compose.prod.yml with healthchecks, resource limits - Add Dockerfile.prod with multi-stage build, non-root user - Add nginx.prod.conf with SSL, rate limiting, security headers - Add .env.prod.example template Maintenance Scripts: - Add backup.sh for database and media backups - Add restore.sh for database restoration - Add cleanup.sh for log rotation and Docker cleanup - Add healthcheck.sh with Telegram alerts Documentation: - Add DEPLOY.md with complete deployment guide Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
155 lines
4.5 KiB
Bash
Executable File
155 lines
4.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# ===========================================
|
|
# Health Check Script for Social Media Automation
|
|
# Run every 5 minutes via cron:
|
|
# */5 * * * * /path/to/healthcheck.sh
|
|
# ===========================================
|
|
|
|
# Configuration
|
|
APP_URL="${APP_URL:-http://localhost:8000}"
|
|
TELEGRAM_BOT_TOKEN="${TELEGRAM_BOT_TOKEN:-}"
|
|
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-}"
|
|
ALERT_FILE="/tmp/social_automation_alert_sent"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log() {
|
|
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
|
}
|
|
|
|
send_telegram() {
|
|
if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then
|
|
message="$1"
|
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
|
-d "chat_id=${TELEGRAM_CHAT_ID}" \
|
|
-d "text=${message}" \
|
|
-d "parse_mode=HTML" > /dev/null 2>&1
|
|
fi
|
|
}
|
|
|
|
check_service() {
|
|
local name=$1
|
|
local container=$2
|
|
|
|
if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
|
|
echo -e "${GREEN}✓${NC} $name"
|
|
return 0
|
|
else
|
|
echo -e "${RED}✗${NC} $name"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
log "Running health checks..."
|
|
|
|
ERRORS=0
|
|
STATUS=""
|
|
|
|
# ===========================================
|
|
# 1. CHECK DOCKER CONTAINERS
|
|
# ===========================================
|
|
echo ""
|
|
echo "Container Status:"
|
|
|
|
check_service "App (FastAPI)" "social-automation-app" || ((ERRORS++))
|
|
check_service "Worker (Celery)" "social-automation-worker" || ((ERRORS++))
|
|
check_service "Beat (Scheduler)" "social-automation-beat" || ((ERRORS++))
|
|
check_service "Database (PostgreSQL)" "social-automation-db" || ((ERRORS++))
|
|
check_service "Redis" "social-automation-redis" || ((ERRORS++))
|
|
check_service "Nginx" "social-automation-nginx" || ((ERRORS++))
|
|
|
|
# ===========================================
|
|
# 2. CHECK API HEALTH
|
|
# ===========================================
|
|
echo ""
|
|
echo "API Status:"
|
|
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$APP_URL/api/health" 2>/dev/null || echo "000")
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
echo -e "${GREEN}✓${NC} API responding (HTTP $HTTP_CODE)"
|
|
else
|
|
echo -e "${RED}✗${NC} API not responding (HTTP $HTTP_CODE)"
|
|
((ERRORS++))
|
|
fi
|
|
|
|
# ===========================================
|
|
# 3. CHECK DATABASE CONNECTION
|
|
# ===========================================
|
|
echo ""
|
|
echo "Database Status:"
|
|
|
|
if docker exec social-automation-db pg_isready -U social_user -d social_automation > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✓${NC} PostgreSQL accepting connections"
|
|
else
|
|
echo -e "${RED}✗${NC} PostgreSQL not accepting connections"
|
|
((ERRORS++))
|
|
fi
|
|
|
|
# ===========================================
|
|
# 4. CHECK REDIS
|
|
# ===========================================
|
|
echo ""
|
|
echo "Redis Status:"
|
|
|
|
if docker exec social-automation-redis redis-cli ping 2>/dev/null | grep -q "PONG"; then
|
|
echo -e "${GREEN}✓${NC} Redis responding"
|
|
else
|
|
echo -e "${RED}✗${NC} Redis not responding"
|
|
((ERRORS++))
|
|
fi
|
|
|
|
# ===========================================
|
|
# 5. CHECK DISK SPACE
|
|
# ===========================================
|
|
echo ""
|
|
echo "System Resources:"
|
|
|
|
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
|
|
if [ "$DISK_USAGE" -lt 90 ]; then
|
|
echo -e "${GREEN}✓${NC} Disk usage: ${DISK_USAGE}%"
|
|
else
|
|
echo -e "${RED}✗${NC} Disk usage: ${DISK_USAGE}% (CRITICAL)"
|
|
((ERRORS++))
|
|
fi
|
|
|
|
# Memory
|
|
MEM_USAGE=$(free | awk 'NR==2 {printf "%.0f", $3/$2*100}')
|
|
if [ "$MEM_USAGE" -lt 90 ]; then
|
|
echo -e "${GREEN}✓${NC} Memory usage: ${MEM_USAGE}%"
|
|
else
|
|
echo -e "${YELLOW}!${NC} Memory usage: ${MEM_USAGE}% (HIGH)"
|
|
fi
|
|
|
|
# ===========================================
|
|
# 6. SUMMARY & ALERTS
|
|
# ===========================================
|
|
echo ""
|
|
echo "─────────────────────────────────────────"
|
|
|
|
if [ $ERRORS -eq 0 ]; then
|
|
echo -e "${GREEN}All systems operational${NC}"
|
|
|
|
# Clear alert file if exists (system recovered)
|
|
if [ -f "$ALERT_FILE" ]; then
|
|
rm "$ALERT_FILE"
|
|
send_telegram "✅ <b>Social Media Automation - RECOVERED</b>%0A%0AAll systems are back to normal."
|
|
fi
|
|
else
|
|
echo -e "${RED}$ERRORS error(s) detected${NC}"
|
|
|
|
# Send alert only if not already sent
|
|
if [ ! -f "$ALERT_FILE" ]; then
|
|
touch "$ALERT_FILE"
|
|
send_telegram "🚨 <b>Social Media Automation - ALERT</b>%0A%0A$ERRORS service(s) are down!%0ACheck server immediately."
|
|
fi
|
|
fi
|
|
|
|
echo "─────────────────────────────────────────"
|
|
|
|
exit $ERRORS
|