mirror of
https://github.com/m1ngsama/automa.git
synced 2025-12-24 10:51:20 +00:00
feat: add operational utilities for monitoring and backup
Add healthcheck.sh for service status monitoring - Check container health and port accessibility - Support individual service or all-services check Add backup.sh for data protection - Backup service data and configurations - List existing backups - Cleanup old backups with retention policy Unix philosophy: small sharp tools that do one thing well
This commit is contained in:
parent
01054f7b22
commit
2e55194f5c
2 changed files with 340 additions and 0 deletions
198
bin/backup.sh
Executable file
198
bin/backup.sh
Executable file
|
|
@ -0,0 +1,198 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Backup utility for all services
|
||||||
|
# Usage: ./bin/backup.sh [service]
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly RED='\033[0;31m'
|
||||||
|
readonly GREEN='\033[0;32m'
|
||||||
|
readonly YELLOW='\033[1;33m'
|
||||||
|
readonly NC='\033[0m'
|
||||||
|
|
||||||
|
readonly BACKUP_ROOT="${BACKUP_ROOT:-./backups}"
|
||||||
|
readonly TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||||
|
|
||||||
|
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||||
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||||
|
|
||||||
|
ensure_backup_dir() {
|
||||||
|
local dir="$1"
|
||||||
|
mkdir -p "$dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_minecraft() {
|
||||||
|
log_info "Backing up Minecraft server..."
|
||||||
|
|
||||||
|
local backup_dir="$BACKUP_ROOT/minecraft/$TIMESTAMP"
|
||||||
|
ensure_backup_dir "$backup_dir"
|
||||||
|
|
||||||
|
# Backup world data
|
||||||
|
if [[ -d "minecraft/data" ]]; then
|
||||||
|
log_info " Archiving world data..."
|
||||||
|
tar -czf "$backup_dir/world-data.tar.gz" -C minecraft data 2>/dev/null || {
|
||||||
|
log_error " Failed to backup world data"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
log_info " ✓ World data backed up"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Backup configs
|
||||||
|
if [[ -d "minecraft/configs" ]]; then
|
||||||
|
log_info " Archiving configs..."
|
||||||
|
tar -czf "$backup_dir/configs.tar.gz" -C minecraft configs 2>/dev/null || {
|
||||||
|
log_warn " Failed to backup configs"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create manifest
|
||||||
|
cat > "$backup_dir/manifest.txt" <<EOF
|
||||||
|
Minecraft Backup
|
||||||
|
Created: $(date)
|
||||||
|
Location: $backup_dir
|
||||||
|
Contents:
|
||||||
|
- World data
|
||||||
|
- Configuration files
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_info " ✓ Backup complete: $backup_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_teamspeak() {
|
||||||
|
log_info "Backing up TeamSpeak server..."
|
||||||
|
|
||||||
|
local backup_dir="$BACKUP_ROOT/teamspeak/$TIMESTAMP"
|
||||||
|
ensure_backup_dir "$backup_dir"
|
||||||
|
|
||||||
|
# Export Docker volume
|
||||||
|
if docker volume ls | grep -q teamspeak_data; then
|
||||||
|
log_info " Exporting volume data..."
|
||||||
|
docker run --rm -v teamspeak_data:/data -v "$PWD/$backup_dir":/backup \
|
||||||
|
alpine tar -czf /backup/teamspeak-data.tar.gz -C /data . 2>/dev/null || {
|
||||||
|
log_error " Failed to export volume"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
log_info " ✓ Volume data backed up"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info " ✓ Backup complete: $backup_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_nextcloud() {
|
||||||
|
log_info "Backing up Nextcloud..."
|
||||||
|
|
||||||
|
local backup_dir="$BACKUP_ROOT/nextcloud/$TIMESTAMP"
|
||||||
|
ensure_backup_dir "$backup_dir"
|
||||||
|
|
||||||
|
# Backup database
|
||||||
|
log_info " Backing up database..."
|
||||||
|
docker exec nextcloud-db mariadb-dump -unextcloud -p"${MYSQL_PASSWORD:-ChangeDb123!}" nextcloud \
|
||||||
|
> "$backup_dir/database.sql" 2>/dev/null || {
|
||||||
|
log_error " Database backup failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Export volumes
|
||||||
|
for vol in nextcloud_html nextcloud_data nextcloud_config nextcloud_apps; do
|
||||||
|
if docker volume ls | grep -q "$vol"; then
|
||||||
|
log_info " Exporting $vol..."
|
||||||
|
docker run --rm -v "$vol":/data -v "$PWD/$backup_dir":/backup \
|
||||||
|
alpine tar -czf "/backup/${vol}.tar.gz" -C /data . 2>/dev/null || {
|
||||||
|
log_warn " Failed to export $vol"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create manifest
|
||||||
|
cat > "$backup_dir/manifest.txt" <<EOF
|
||||||
|
Nextcloud Backup
|
||||||
|
Created: $(date)
|
||||||
|
Location: $backup_dir
|
||||||
|
Contents:
|
||||||
|
- MariaDB database dump
|
||||||
|
- Application volumes
|
||||||
|
- User data
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_info " ✓ Backup complete: $backup_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
list_backups() {
|
||||||
|
log_info "Available backups:"
|
||||||
|
echo
|
||||||
|
|
||||||
|
for service in minecraft teamspeak nextcloud; do
|
||||||
|
if [[ -d "$BACKUP_ROOT/$service" ]]; then
|
||||||
|
echo "=== $service ==="
|
||||||
|
ls -lh "$BACKUP_ROOT/$service" | tail -n +2
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_old_backups() {
|
||||||
|
local keep_days="${1:-7}"
|
||||||
|
|
||||||
|
log_info "Cleaning up backups older than $keep_days days..."
|
||||||
|
|
||||||
|
find "$BACKUP_ROOT" -type f -name "*.tar.gz" -mtime +"$keep_days" -delete
|
||||||
|
find "$BACKUP_ROOT" -type d -empty -delete
|
||||||
|
|
||||||
|
log_info " ✓ Cleanup complete"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local action="${1:-backup}"
|
||||||
|
local service="${2:-all}"
|
||||||
|
|
||||||
|
case "$action" in
|
||||||
|
backup)
|
||||||
|
case "$service" in
|
||||||
|
minecraft)
|
||||||
|
backup_minecraft
|
||||||
|
;;
|
||||||
|
teamspeak)
|
||||||
|
backup_teamspeak
|
||||||
|
;;
|
||||||
|
nextcloud)
|
||||||
|
backup_nextcloud
|
||||||
|
;;
|
||||||
|
all)
|
||||||
|
backup_minecraft || true
|
||||||
|
backup_teamspeak || true
|
||||||
|
backup_nextcloud || true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 backup [minecraft|teamspeak|nextcloud|all]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
list)
|
||||||
|
list_backups
|
||||||
|
;;
|
||||||
|
cleanup)
|
||||||
|
cleanup_old_backups "${service:-7}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 <command> [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
backup [service] Create backup (default: all)
|
||||||
|
list List available backups
|
||||||
|
cleanup [days] Remove backups older than N days (default: 7)
|
||||||
|
|
||||||
|
Services:
|
||||||
|
minecraft, teamspeak, nextcloud, all
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 backup minecraft
|
||||||
|
$0 list
|
||||||
|
$0 cleanup 30
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
142
bin/healthcheck.sh
Executable file
142
bin/healthcheck.sh
Executable file
|
|
@ -0,0 +1,142 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Health check script for all services
|
||||||
|
# Usage: ./bin/healthcheck.sh [service]
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
readonly RED='\033[0;31m'
|
||||||
|
readonly GREEN='\033[0;32m'
|
||||||
|
readonly YELLOW='\033[1;33m'
|
||||||
|
readonly NC='\033[0m'
|
||||||
|
|
||||||
|
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||||
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||||
|
|
||||||
|
check_container_health() {
|
||||||
|
local container_name="$1"
|
||||||
|
|
||||||
|
if ! docker ps --filter "name=$container_name" --format '{{.Names}}' | grep -q "$container_name"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local status
|
||||||
|
status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null)
|
||||||
|
|
||||||
|
if [[ "$status" == "running" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_port() {
|
||||||
|
local host="${1:-localhost}"
|
||||||
|
local port="$2"
|
||||||
|
|
||||||
|
if timeout 2 bash -c "cat < /dev/null > /dev/tcp/$host/$port" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_minecraft() {
|
||||||
|
log_info "Checking Minecraft server..."
|
||||||
|
|
||||||
|
if check_container_health "mc-fabric-1.21.1"; then
|
||||||
|
log_info " ✓ Container is running"
|
||||||
|
else
|
||||||
|
log_error " ✗ Container is not running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_port "localhost" 25565; then
|
||||||
|
log_info " ✓ Server port 25565 is accessible"
|
||||||
|
else
|
||||||
|
log_warn " ⚠ Server port 25565 is not accessible"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_port "localhost" 25575; then
|
||||||
|
log_info " ✓ RCON port 25575 is accessible"
|
||||||
|
else
|
||||||
|
log_warn " ⚠ RCON port 25575 is not accessible"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_teamspeak() {
|
||||||
|
log_info "Checking TeamSpeak server..."
|
||||||
|
|
||||||
|
if check_container_health "teamspeak-server"; then
|
||||||
|
log_info " ✓ Container is running"
|
||||||
|
else
|
||||||
|
log_error " ✗ Container is not running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_port "localhost" 10011; then
|
||||||
|
log_info " ✓ File transfer port 10011 is accessible"
|
||||||
|
else
|
||||||
|
log_warn " ⚠ Port 10011 is not accessible"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_nextcloud() {
|
||||||
|
log_info "Checking Nextcloud..."
|
||||||
|
|
||||||
|
if check_container_health "nextcloud"; then
|
||||||
|
log_info " ✓ Nextcloud container is running"
|
||||||
|
else
|
||||||
|
log_error " ✗ Nextcloud container is not running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_container_health "nextcloud-db"; then
|
||||||
|
log_info " ✓ Database container is running"
|
||||||
|
else
|
||||||
|
log_error " ✗ Database container is not running"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_container_health "nextcloud-redis"; then
|
||||||
|
log_info " ✓ Redis container is running"
|
||||||
|
else
|
||||||
|
log_warn " ⚠ Redis container is not running"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_port "localhost" 8080; then
|
||||||
|
log_info " ✓ Web interface port 8080 is accessible"
|
||||||
|
else
|
||||||
|
log_warn " ⚠ Port 8080 is not accessible"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local service="${1:-all}"
|
||||||
|
|
||||||
|
case "$service" in
|
||||||
|
minecraft)
|
||||||
|
check_minecraft
|
||||||
|
;;
|
||||||
|
teamspeak)
|
||||||
|
check_teamspeak
|
||||||
|
;;
|
||||||
|
nextcloud)
|
||||||
|
check_nextcloud
|
||||||
|
;;
|
||||||
|
all)
|
||||||
|
echo "=== Health Check Report ==="
|
||||||
|
echo
|
||||||
|
check_minecraft || true
|
||||||
|
echo
|
||||||
|
check_teamspeak || true
|
||||||
|
echo
|
||||||
|
check_nextcloud || true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [minecraft|teamspeak|nextcloud|all]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Loading…
Reference in a new issue