mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 09:07:20 +00:00
376 lines
16 KiB
Bash
Executable File
376 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ==============================================
|
||
# AzerothCore Podman Deployment & Health Check Script (Distrobox Compatible)
|
||
# ==============================================
|
||
# This script deploys the complete AzerothCore stack using Podman via distrobox-host-exec
|
||
# Usage: ./deploy-and-check-distrobox.sh [--skip-deploy] [--quick-check]
|
||
|
||
set -e # Exit on any error
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Script options
|
||
SKIP_DEPLOY=false
|
||
QUICK_CHECK=false
|
||
|
||
# Parse command line arguments
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--skip-deploy)
|
||
SKIP_DEPLOY=true
|
||
shift
|
||
;;
|
||
--quick-check)
|
||
QUICK_CHECK=true
|
||
shift
|
||
;;
|
||
-h|--help)
|
||
echo "Usage: $0 [--skip-deploy] [--quick-check]"
|
||
echo " --skip-deploy Skip deployment, only run health checks"
|
||
echo " --quick-check Run basic health checks only"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "Unknown option $1"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Function to print colored output
|
||
print_status() {
|
||
local status=$1
|
||
local message=$2
|
||
case $status in
|
||
"INFO")
|
||
echo -e "${BLUE}ℹ️ ${message}${NC}"
|
||
;;
|
||
"SUCCESS")
|
||
echo -e "${GREEN}✅ ${message}${NC}"
|
||
;;
|
||
"WARNING")
|
||
echo -e "${YELLOW}⚠️ ${message}${NC}"
|
||
;;
|
||
"ERROR")
|
||
echo -e "${RED}❌ ${message}${NC}"
|
||
;;
|
||
"HEADER")
|
||
echo -e "\n${BLUE}=== ${message} ===${NC}"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# Function to check if a port is accessible
|
||
check_port() {
|
||
local port=$1
|
||
local service_name=$2
|
||
local timeout=${3:-5}
|
||
|
||
if timeout $timeout bash -c "echo >/dev/tcp/localhost/$port" 2>/dev/null; then
|
||
print_status "SUCCESS" "$service_name (port $port): CONNECTED"
|
||
return 0
|
||
else
|
||
print_status "ERROR" "$service_name (port $port): FAILED"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to wait for a service to be ready
|
||
wait_for_service() {
|
||
local service_name=$1
|
||
local max_attempts=$2
|
||
local check_command=$3
|
||
|
||
print_status "INFO" "Waiting for $service_name to be ready..."
|
||
|
||
for i in $(seq 1 $max_attempts); do
|
||
if eval "$check_command" &>/dev/null; then
|
||
print_status "SUCCESS" "$service_name is ready!"
|
||
return 0
|
||
fi
|
||
|
||
if [ $i -eq $max_attempts ]; then
|
||
print_status "ERROR" "$service_name failed to start after $max_attempts attempts"
|
||
return 1
|
||
fi
|
||
|
||
echo -n "."
|
||
sleep 5
|
||
done
|
||
}
|
||
|
||
# Function to check container health
|
||
check_container_health() {
|
||
local container_name=$1
|
||
|
||
# Check if container is running
|
||
if distrobox-host-exec podman ps --format '{{.Names}}' 2>/dev/null | grep -q "^${container_name}$"; then
|
||
print_status "SUCCESS" "$container_name: running"
|
||
return 0
|
||
else
|
||
print_status "ERROR" "$container_name: not running"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to deploy the stack
|
||
deploy_stack() {
|
||
print_status "HEADER" "DEPLOYING AZEROTHCORE STACK"
|
||
|
||
# Check if environment files exist
|
||
for env_file in "docker-compose-azerothcore-database.env" "docker-compose-azerothcore-services.env"; do
|
||
if [ ! -f "$env_file" ]; then
|
||
print_status "ERROR" "Environment file $env_file not found"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
print_status "INFO" "Step 1: Cleaning up existing containers..."
|
||
distrobox-host-exec bash -c "podman rm -f ac-mysql ac-backup ac-db-init ac-db-import ac-authserver ac-worldserver ac-client-data 2>/dev/null || true"
|
||
|
||
print_status "INFO" "Step 2: Creating required directories..."
|
||
mkdir -p storage/azerothcore/{mysql-data,backups,config,data,logs,modules,lua_scripts,cache}
|
||
|
||
print_status "INFO" "Step 3: Creating network..."
|
||
distrobox-host-exec bash -c "podman network create azerothcore --subnet 172.20.0.0/16 --gateway 172.20.0.1 2>/dev/null || true"
|
||
|
||
print_status "INFO" "Step 4: Starting MySQL..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-mysql --network azerothcore --network-alias ac-mysql -p 64306:3306 \
|
||
-e MYSQL_ROOT_PASSWORD=azerothcore123 -e MYSQL_ROOT_HOST='%' -e MYSQL_ALLOW_EMPTY_PASSWORD=no \
|
||
-v ./storage/azerothcore/mysql-data:/var/lib/mysql-persistent \
|
||
-v ./storage/azerothcore/backups:/backups \
|
||
--tmpfs /var/lib/mysql-runtime:size=2G \
|
||
--restart unless-stopped \
|
||
docker.io/library/mysql:8.0 \
|
||
mysqld --datadir=/var/lib/mysql-runtime --default-authentication-plugin=mysql_native_password \
|
||
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max_connections=1000 \
|
||
--innodb-buffer-pool-size=256M --innodb-log-file-size=64M"
|
||
|
||
# Wait for MySQL
|
||
wait_for_service "MySQL" 24 "distrobox-host-exec podman exec ac-mysql mysql -uroot -pazerothcore123 -e 'SELECT 1' 2>/dev/null"
|
||
|
||
print_status "INFO" "Step 5: Starting backup service..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-backup --network azerothcore \
|
||
-e MYSQL_HOST=ac-mysql -e MYSQL_PORT=3306 -e MYSQL_USER=root -e MYSQL_PASSWORD=azerothcore123 \
|
||
-e BACKUP_RETENTION_DAYS=3 -e BACKUP_RETENTION_HOURS=6 -e BACKUP_DAILY_TIME=09 \
|
||
-e DB_AUTH_NAME=acore_auth -e DB_WORLD_NAME=acore_world -e DB_CHARACTERS_NAME=acore_characters -e TZ=UTC \
|
||
-v ./storage/azerothcore/backups:/backups -w /tmp --restart unless-stopped \
|
||
docker.io/library/mysql:8.0 /bin/bash -c \
|
||
'microdnf install -y curl || yum install -y curl; \
|
||
curl -fsSL https://raw.githubusercontent.com/uprightbass360/acore-compose/main/scripts/backup-scheduler.sh -o /tmp/backup-scheduler.sh; \
|
||
chmod +x /tmp/backup-scheduler.sh; /tmp/backup-scheduler.sh'"
|
||
|
||
print_status "INFO" "Step 6: Initializing databases..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-db-init --network azerothcore \
|
||
-e MYSQL_PWD=azerothcore123 -e MYSQL_HOST=ac-mysql -e MYSQL_USER=root -e MYSQL_ROOT_PASSWORD=azerothcore123 \
|
||
-e DB_WAIT_RETRIES=60 -e DB_WAIT_SLEEP=10 \
|
||
-e DB_AUTH_NAME=acore_auth -e DB_WORLD_NAME=acore_world -e DB_CHARACTERS_NAME=acore_characters \
|
||
-e MYSQL_CHARACTER_SET=utf8mb4 -e MYSQL_COLLATION=utf8mb4_unicode_ci \
|
||
-v ./storage/azerothcore/mysql-data:/var/lib/mysql-persistent --restart no \
|
||
docker.io/library/mysql:8.0 sh -c \
|
||
'microdnf install -y curl || yum install -y curl; \
|
||
curl -fsSL https://raw.githubusercontent.com/uprightbass360/acore-compose/main/scripts/db-init.sh -o /tmp/db-init.sh; \
|
||
chmod +x /tmp/db-init.sh; /tmp/db-init.sh'"
|
||
|
||
# Wait for db-init to complete
|
||
wait_for_service "Database Init" 36 "distrobox-host-exec podman ps -a --format '{{.Names}} {{.Status}}' | grep 'ac-db-init' | grep -q 'Exited (0)'"
|
||
|
||
print_status "INFO" "Step 7: Importing database..."
|
||
sudo chmod -R 777 storage/azerothcore/config 2>/dev/null || true
|
||
distrobox-host-exec bash -c "podman run -d --name ac-db-import --network azerothcore --privileged \
|
||
-e AC_DATA_DIR=/azerothcore/data -e AC_LOGS_DIR=/azerothcore/logs \
|
||
-e AC_LOGIN_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_auth' \
|
||
-e AC_WORLD_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_world' \
|
||
-e AC_CHARACTER_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_characters' \
|
||
-e AC_CLOSE_IDLE_CONNECTIONS=false -e AC_UPDATES_ENABLE_DATABASES=7 -e AC_UPDATES_AUTO_SETUP=1 \
|
||
-e AC_LOG_LEVEL=1 -e AC_LOGGER_ROOT_CONFIG='1,Console' -e AC_LOGGER_SERVER_CONFIG='1,Console' -e AC_APPENDER_CONSOLE_CONFIG='1,2,0' \
|
||
-v ./storage/azerothcore/config:/azerothcore/env/dist/etc -u 0:0 --restart no \
|
||
docker.io/acore/ac-wotlk-db-import:14.0.0-dev"
|
||
|
||
# Wait for db-import to complete
|
||
wait_for_service "Database Import" 60 "distrobox-host-exec podman ps -a --format '{{.Names}} {{.Status}}' | grep 'ac-db-import' | grep -q 'Exited (0)'"
|
||
|
||
print_status "INFO" "Step 8: Starting client data download..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-client-data --network azerothcore --privileged \
|
||
-v ./storage/azerothcore/data:/azerothcore/data -v ./storage/azerothcore/cache:/cache -w /tmp --restart no \
|
||
docker.io/library/alpine:latest sh -c \
|
||
'apk add --no-cache curl unzip wget ca-certificates p7zip jq; \
|
||
chown -R 1001:1001 /azerothcore/data /cache 2>/dev/null || true; mkdir -p /cache; \
|
||
curl -fsSL https://raw.githubusercontent.com/uprightbass360/acore-compose/main/scripts/download-client-data.sh -o /tmp/download-client-data.sh; \
|
||
chmod +x /tmp/download-client-data.sh; /tmp/download-client-data.sh'" &
|
||
|
||
print_status "INFO" "Step 9: Starting Auth Server..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-authserver --network azerothcore --privileged -p 3784:3724 \
|
||
-e AC_LOGIN_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_auth' \
|
||
-e AC_UPDATES_ENABLE_DATABASES=0 -e AC_BIND_IP='0.0.0.0' -e AC_LOG_LEVEL=1 \
|
||
-e AC_LOGGER_ROOT_CONFIG='1,Console' -e AC_LOGGER_SERVER_CONFIG='1,Console' -e AC_APPENDER_CONSOLE_CONFIG='1,2,0' \
|
||
-v ./storage/azerothcore/config:/azerothcore/env/dist/etc --cap-add SYS_NICE --restart unless-stopped \
|
||
docker.io/acore/ac-wotlk-authserver:14.0.0-dev"
|
||
|
||
# Wait for authserver
|
||
wait_for_service "Auth Server" 12 "check_container_health ac-authserver"
|
||
|
||
print_status "INFO" "Step 10: Waiting for client data (this may take 10-20 minutes)..."
|
||
print_status "INFO" "World Server will start once data download completes..."
|
||
|
||
print_status "SUCCESS" "Deployment in progress! Client data downloading in background."
|
||
print_status "INFO" "World Server will be started manually once client data is ready."
|
||
}
|
||
|
||
# Function to start worldserver
|
||
start_worldserver() {
|
||
print_status "INFO" "Starting World Server..."
|
||
distrobox-host-exec bash -c "podman run -d --name ac-worldserver --network azerothcore --privileged -t -p 8215:8085 -p 7778:7878 \
|
||
-e AC_LOGIN_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_auth' \
|
||
-e AC_WORLD_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_world' \
|
||
-e AC_CHARACTER_DATABASE_INFO='ac-mysql;3306;root;azerothcore123;acore_characters' \
|
||
-e AC_UPDATES_ENABLE_DATABASES=0 -e AC_BIND_IP='0.0.0.0' -e AC_DATA_DIR='/azerothcore/data' \
|
||
-e AC_SOAP_PORT=7878 -e AC_PROCESS_PRIORITY=0 -e PLAYERBOT_ENABLED=1 -e PLAYERBOT_MAX_BOTS=40 -e AC_LOG_LEVEL=2 \
|
||
-v ./storage/azerothcore/data:/azerothcore/data \
|
||
-v ./storage/azerothcore/config:/azerothcore/env/dist/etc \
|
||
-v ./storage/azerothcore/logs:/azerothcore/logs \
|
||
-v ./storage/azerothcore/modules:/azerothcore/modules \
|
||
-v ./storage/azerothcore/lua_scripts:/azerothcore/lua_scripts \
|
||
--cap-add SYS_NICE --restart unless-stopped \
|
||
docker.io/acore/ac-wotlk-worldserver:14.0.0-dev"
|
||
|
||
wait_for_service "World Server" 12 "check_container_health ac-worldserver"
|
||
}
|
||
|
||
# Function to perform health checks
|
||
perform_health_checks() {
|
||
print_status "HEADER" "CONTAINER HEALTH STATUS"
|
||
|
||
# Check all containers
|
||
local containers=("ac-mysql" "ac-backup" "ac-authserver" "ac-worldserver")
|
||
local container_failures=0
|
||
|
||
for container in "${containers[@]}"; do
|
||
if distrobox-host-exec podman ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^${container}$"; then
|
||
if ! check_container_health "$container"; then
|
||
((container_failures++))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
print_status "HEADER" "PORT CONNECTIVITY TESTS"
|
||
|
||
# Database Layer
|
||
print_status "INFO" "Database Layer:"
|
||
local port_failures=0
|
||
if ! check_port 64306 "MySQL"; then ((port_failures++)); fi
|
||
|
||
# Services Layer
|
||
print_status "INFO" "Services Layer:"
|
||
if ! check_port 3784 "Auth Server"; then ((port_failures++)); fi
|
||
if distrobox-host-exec podman ps --format '{{.Names}}' 2>/dev/null | grep -q "^ac-worldserver$"; then
|
||
if ! check_port 8215 "World Server"; then ((port_failures++)); fi
|
||
if ! check_port 7778 "SOAP API"; then ((port_failures++)); fi
|
||
else
|
||
print_status "INFO" "World Server: not started yet (waiting for client data)"
|
||
fi
|
||
|
||
if [ "$QUICK_CHECK" = false ]; then
|
||
print_status "HEADER" "DATABASE CONNECTIVITY TEST"
|
||
|
||
# Test database connectivity and verify schemas
|
||
if distrobox-host-exec podman exec ac-mysql mysql -uroot -pazerothcore123 -e "SHOW DATABASES;" 2>/dev/null | grep -q "acore_auth"; then
|
||
print_status "SUCCESS" "Database schemas: verified"
|
||
else
|
||
print_status "ERROR" "Database schemas: verification failed"
|
||
((container_failures++))
|
||
fi
|
||
|
||
# Test realm configuration
|
||
realm_count=$(distrobox-host-exec podman exec ac-mysql mysql -uroot -pazerothcore123 -e "USE acore_auth; SELECT COUNT(*) FROM realmlist;" 2>/dev/null | tail -1)
|
||
if [ "$realm_count" -gt 0 ] 2>/dev/null; then
|
||
print_status "SUCCESS" "Realm configuration: $realm_count realm(s) configured"
|
||
else
|
||
print_status "WARNING" "Realm configuration: no realms configured yet (post-install needed)"
|
||
fi
|
||
|
||
# Check for playerbots database
|
||
if distrobox-host-exec podman exec ac-mysql mysql -uroot -pazerothcore123 -e "SHOW DATABASES;" 2>/dev/null | grep -q "acore_playerbots"; then
|
||
print_status "SUCCESS" "Playerbots database: detected"
|
||
else
|
||
print_status "INFO" "Playerbots database: not present (standard installation)"
|
||
fi
|
||
fi
|
||
|
||
print_status "HEADER" "DEPLOYMENT SUMMARY"
|
||
|
||
# Summary
|
||
local total_failures=$((container_failures + port_failures))
|
||
|
||
if [ $total_failures -eq 0 ]; then
|
||
print_status "SUCCESS" "All services are healthy and operational!"
|
||
print_status "INFO" "Available services:"
|
||
echo " 🎮 Game Server: localhost:8215"
|
||
echo " 🔐 Auth Server: localhost:3784"
|
||
echo " 🔧 SOAP API: localhost:7778"
|
||
echo " 🗄️ MySQL: localhost:64306"
|
||
echo ""
|
||
print_status "INFO" "Default credentials:"
|
||
echo " 🗄️ MySQL: root / azerothcore123"
|
||
return 0
|
||
else
|
||
print_status "WARNING" "Health check completed with $total_failures issue(s)"
|
||
print_status "INFO" "Check container logs for details: distrobox-host-exec podman logs <container-name>"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to show container status
|
||
show_container_status() {
|
||
print_status "HEADER" "CONTAINER STATUS OVERVIEW"
|
||
|
||
echo -e "${BLUE}Container Name\t\tStatus${NC}"
|
||
echo "=============================================="
|
||
distrobox-host-exec podman ps -a --format "table {{.Names}}\t{{.Status}}" 2>/dev/null | grep ac- || echo "No containers found"
|
||
}
|
||
|
||
# Main execution
|
||
main() {
|
||
print_status "HEADER" "AZEROTHCORE DEPLOYMENT & HEALTH CHECK (DISTROBOX/PODMAN)"
|
||
|
||
# Check if distrobox-host-exec is available
|
||
if ! command -v distrobox-host-exec &> /dev/null; then
|
||
print_status "ERROR" "distrobox-host-exec is not available - are you running in a distrobox?"
|
||
exit 1
|
||
fi
|
||
|
||
# Check if podman is available on host
|
||
if ! distrobox-host-exec podman version &> /dev/null; then
|
||
print_status "ERROR" "Podman is not available on the host system"
|
||
exit 1
|
||
fi
|
||
|
||
# Deploy the stack unless skipped
|
||
if [ "$SKIP_DEPLOY" = false ]; then
|
||
deploy_stack
|
||
else
|
||
print_status "INFO" "Skipping deployment, running health checks only..."
|
||
fi
|
||
|
||
# Show container status
|
||
show_container_status
|
||
|
||
# Perform health checks
|
||
if perform_health_checks; then
|
||
print_status "SUCCESS" "🎉 AzerothCore stack deployment successful!"
|
||
exit 0
|
||
else
|
||
print_status "INFO" "⚠️ Some services may still be starting - check status with: distrobox-host-exec podman ps -a"
|
||
exit 0
|
||
fi
|
||
}
|
||
|
||
# Run main function
|
||
main "$@"
|