diff --git a/.env b/.env index 5351bfe..c9b903f 100644 --- a/.env +++ b/.env @@ -84,7 +84,7 @@ DEPLOYMENT_MODE=local # Storage configuration for Portainer NFS deployments # Leave empty for local development with named volumes -STORAGE_PATH_CONTAINERS= +STORAGE_PATH_CONTAINERS=/nfs/containers # Use named volumes (true for local, false for Portainer) USE_NAMED_VOLUMES=true diff --git a/portainer-diagnostics.sh b/portainer-diagnostics.sh new file mode 100755 index 0000000..6b6e7fb --- /dev/null +++ b/portainer-diagnostics.sh @@ -0,0 +1,151 @@ +#!/bin/bash +# Portainer Diagnostics Script for AzerothCore Docker Compose +# Run this on your slower Portainer machine to diagnose timeout issues + +echo "===============================================" +echo "AzerothCore Portainer Diagnostics" +echo "===============================================" +echo "Date: $(date)" +echo "Machine: $(hostname)" +echo "" + +# System Resources +echo "🖥️ SYSTEM RESOURCES" +echo "-------------------" +echo "CPU Cores: $(nproc)" +echo "Memory: $(free -h | grep '^Mem:' | awk '{print $2 " total, " $7 " available"}')" +echo "Disk Space: $(df -h / | tail -1 | awk '{print $4 " available on " $6}')" +echo "Load Average: $(uptime | awk -F'load average:' '{print $2}')" +echo "" + +# Podman Status +echo "🐳 PODMAN STATUS" +echo "----------------" +podman --version +echo "Podman Service Status: $(systemctl is-active podman 2>/dev/null || echo 'Unknown')" +echo "Podman Memory Limit: $(podman system info 2>/dev/null | grep 'memTotal' || echo 'Unable to determine')" +echo "" + +# Network Connectivity Tests +echo "🌐 NETWORK CONNECTIVITY" +echo "-----------------------" +echo "Testing GitHub connectivity (for client data download):" +curl -s -w "Response Time: %{time_total}s\n" -o /dev/null https://api.github.com/repos/wowgaming/client-data/releases/latest || echo "❌ GitHub API unreachable" + +echo "Testing GitHub download speed (5MB test):" +timeout 30 wget -O /tmp/speed_test.zip https://github.com/wowgaming/client-data/releases/download/v16/data.zip --progress=dot 2>&1 | tail -5 || echo "❌ Download test failed" +rm -f /tmp/speed_test.zip + +echo "" + +# Check for existing volumes/data +echo "📁 EXISTING DATA CHECK" +echo "---------------------" +VOLUMES_PATH="${STORAGE_PATH_CONTAINERS:-./volumes}" +echo "Checking volumes path: $VOLUMES_PATH" + +if [ -d "$VOLUMES_PATH/azerothcore/data" ]; then + echo "✅ Data directory exists" + if [ -d "$VOLUMES_PATH/azerothcore/data/maps" ] && [ -d "$VOLUMES_PATH/azerothcore/data/vmaps" ]; then + echo "✅ Game data appears complete - client download should be skipped" + else + echo "⚠️ Game data incomplete - client download will be required" + fi +else + echo "❌ No existing data - full download required (~15GB)" +fi + +if [ -d "$VOLUMES_PATH/azerothcore/mysql" ]; then + echo "✅ MySQL data directory exists" + if [ -f "$VOLUMES_PATH/azerothcore/mysql/acore_world/creature.ibd" ]; then + echo "✅ Database appears populated - import should be skipped" + else + echo "⚠️ Database may need importing" + fi +else + echo "❌ No existing MySQL data - full import required" +fi + +echo "" + +# Podman Compose Services Status +echo "🔧 PODMAN COMPOSE STATUS" +echo "------------------------" +if [ -f "docker-compose.yml" ]; then + echo "Docker Compose file found" + podman-compose ps 2>/dev/null || echo "Podman Compose not running or not available" +else + echo "❌ docker-compose.yml not found in current directory" +fi + +echo "" + +# Resource-intensive operation simulation +echo "⏱️ PERFORMANCE TESTS" +echo "--------------------" +echo "Testing disk I/O (1GB file):" +timeout 60 dd if=/dev/zero of=/tmp/test_io bs=1M count=1024 2>&1 | grep -E '(copied|MB/s)' || echo "❌ I/O test failed or too slow" +rm -f /tmp/test_io + +echo "Testing compression/extraction speed:" +timeout 30 sh -c 'echo "test data" | gzip > /tmp/test.gz && gunzip /tmp/test.gz && echo "✅ Compression test OK"' || echo "❌ Compression test failed" +rm -f /tmp/test.gz /tmp/test + +echo "" + +# Memory pressure test +echo "🧠 MEMORY PRESSURE TEST" +echo "-----------------------" +echo "Available memory before test:" +free -h | grep '^Mem:' + +echo "Testing memory allocation (512MB):" +timeout 10 sh -c 'python3 -c "import time; data = b\"x\" * (512 * 1024 * 1024); time.sleep(2); print(\"✅ Memory allocation test OK\")"' 2>/dev/null || echo "❌ Memory allocation test failed" + +echo "Available memory after test:" +free -h | grep '^Mem:' + +echo "" + +# Container runtime test +echo "🏃 CONTAINER RUNTIME TEST" +echo "-------------------------" +echo "Testing basic container startup time:" +START_TIME=$(date +%s) +podman run --rm alpine:latest echo "Container startup test" 2>/dev/null || echo "❌ Container startup failed" +END_TIME=$(date +%s) +DURATION=$((END_TIME - START_TIME)) +echo "Container startup took: ${DURATION}s" + +if [ $DURATION -gt 10 ]; then + echo "⚠️ Container startup is slow (>10s)" +else + echo "✅ Container startup time is acceptable" +fi + +echo "" + +# Recommendations +echo "💡 RECOMMENDATIONS" +echo "------------------" + +# Check if we have enough resources +AVAILABLE_GB=$(df / | tail -1 | awk '{print int($4/1024/1024)}') +MEMORY_GB=$(free -g | grep '^Mem:' | awk '{print $2}') + +if [ $AVAILABLE_GB -lt 20 ]; then + echo "⚠️ Low disk space ($AVAILABLE_GB GB available). Need at least 20GB for full setup." +fi + +if [ $MEMORY_GB -lt 2 ]; then + echo "⚠️ Low memory ($MEMORY_GB GB). Consider increasing to 4GB+ for better performance." +fi + +echo "" +echo "🚀 SUGGESTED PORTAINER DEPLOYMENT STRATEGY:" +echo "1. Pre-download client data on faster machine and copy to Portainer server" +echo "2. Use 'DEPLOYMENT_MODE=portainer' environment variable for simplified setup" +echo "3. Increase Portainer deployment timeouts to 30+ minutes" +echo "4. Deploy services in phases rather than all at once" +echo "" +echo "Diagnostics complete. Save this output for troubleshooting." \ No newline at end of file diff --git a/portainer-verify.sh b/portainer-verify.sh new file mode 100755 index 0000000..543a476 --- /dev/null +++ b/portainer-verify.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# Real-time monitoring script for Portainer deployment +# Run this DURING deployment to monitor progress and catch issues + +echo "===============================================" +echo "AzerothCore Portainer Deployment Monitor" +echo "===============================================" + +# Function to monitor container logs +monitor_container() { + local container_name=$1 + local max_wait=${2:-300} # Default 5 minutes + local start_time=$(date +%s) + + echo "🔍 Monitoring $container_name (max wait: ${max_wait}s)" + + while [ $(($(date +%s) - start_time)) -lt $max_wait ]; do + if podman ps --filter "name=$container_name" --format "table {{.Names}}\t{{.Status}}" | grep -q "$container_name"; then + local status=$(podman ps --filter "name=$container_name" --format "{{.Status}}") + echo "[$container_name] Status: $status" + + # Show last few log lines + echo "[$container_name] Recent logs:" + podman logs --tail 5 "$container_name" 2>&1 | sed 's/^/ /' + echo "" + + # Check if container exited + if echo "$status" | grep -q "Exited"; then + local exit_code=$(podman ps -a --filter "name=$container_name" --format "{{.Status}}" | grep -o "Exited ([0-9]*)" | grep -o "[0-9]*") + if [ "$exit_code" = "0" ]; then + echo "✅ $container_name completed successfully" + return 0 + else + echo "❌ $container_name failed (exit code: $exit_code)" + echo "Full error logs:" + podman logs "$container_name" 2>&1 | tail -20 | sed 's/^/ /' + return 1 + fi + fi + else + echo "⏳ Waiting for $container_name to start..." + fi + + sleep 10 + done + + echo "⏰ Timeout waiting for $container_name" + return 1 +} + +# Function to monitor network download progress +monitor_download() { + local container_name="ac-client-data" + echo "📥 Monitoring client data download progress..." + + while podman ps --filter "name=$container_name" --format "{{.Names}}" | grep -q "$container_name"; do + # Look for download progress in logs + podman logs "$container_name" 2>&1 | tail -10 | grep -E "(downloading|download|MB|GB|%)" | tail -3 | sed 's/^/ /' + + # Check disk usage in data directory + if podman exec "$container_name" ls -la /azerothcore/data/ 2>/dev/null; then + echo " 📁 Current data directory contents:" + podman exec "$container_name" du -sh /azerothcore/data/* 2>/dev/null | sed 's/^/ /' || echo " (empty or not accessible)" + fi + + echo "---" + sleep 30 + done +} + +# Function to check database import progress +monitor_db_import() { + local container_name="ac-db-import" + echo "🗄️ Monitoring database import progress..." + + while podman ps --filter "name=$container_name" --format "{{.Names}}" | grep -q "$container_name"; do + echo "[$container_name] Recent activity:" + podman logs "$container_name" 2>&1 | tail -5 | sed 's/^/ /' + + # Check database size growth + echo " 📊 Database status:" + podman exec ac-mysql mysql -uroot -p${DOCKER_DB_ROOT_PASSWORD:-password} -e " + SELECT + table_schema as 'Database', + ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as 'Size (MB)' + FROM information_schema.tables + WHERE table_schema IN ('acore_auth', 'acore_world', 'acore_characters') + GROUP BY table_schema; + " 2>/dev/null | sed 's/^/ /' || echo " Database not accessible yet" + + echo "---" + sleep 20 + done +} + +# Main monitoring loop +echo "🚀 Starting deployment monitoring..." +echo "Press Ctrl+C to stop monitoring" +echo "" + +# Load environment variables if .env exists +if [ -f ".env" ]; then + export $(grep -v '^#' .env | xargs) +fi + +# Monitor the deployment phases +echo "Phase 1: MySQL startup" +monitor_container "ac-mysql" 120 + +echo "Phase 2: Database initialization" +monitor_container "ac-db-init" 60 + +echo "Phase 3: Client data download (this will take longest)" +monitor_download & +DOWNLOAD_PID=$! +monitor_container "ac-client-data" 2400 # 40 minutes max +kill $DOWNLOAD_PID 2>/dev/null + +echo "Phase 4: Database import" +monitor_db_import & +IMPORT_PID=$! +monitor_container "ac-db-import" 1800 # 30 minutes max +kill $IMPORT_PID 2>/dev/null + +echo "Phase 5: Application servers" +monitor_container "ac-authserver" 120 +monitor_container "ac-worldserver" 180 + +echo "" +echo "🏁 Monitoring complete!" +echo "" +echo "💡 If you see timeouts or failures:" +echo "1. Check 'podman-compose logs [service-name]' for detailed errors" +echo "2. Restart individual failed services with 'podman-compose up [service-name]'" +echo "3. Consider running services one at a time instead of all at once" \ No newline at end of file diff --git a/quick-fix-portainer.sh b/quick-fix-portainer.sh new file mode 100755 index 0000000..45494b6 --- /dev/null +++ b/quick-fix-portainer.sh @@ -0,0 +1,248 @@ +#!/bin/bash +# Quick fixes for common Portainer timeout issues +# Run this script to apply optimizations for slower machines + +echo "===============================================" +echo "AzerothCore Portainer Quick Fixes" +echo "===============================================" + +# Create optimized .env for Portainer +create_portainer_env() { + echo "📝 Creating Portainer-optimized .env file..." + + cat > .env.portainer << 'EOF' +# Portainer Optimized Configuration +DEPLOYMENT_MODE=portainer + +# Reduce resource usage +PLAYERBOT_MAX_BOTS=10 +MODULE_PLAYERBOTS=1 +MODULE_AOE_LOOT=0 +MODULE_LEARN_SPELLS=0 +MODULE_FIREWORKS=0 +MODULE_INDIVIDUAL_PROGRESSION=0 + +# Database optimizations for slower machines +DOCKER_DB_ROOT_PASSWORD=password + +# Monitoring disabled for performance +INFLUXDB_INIT_MODE=disabled +GF_INSTALL_PLUGINS="" + +# Backup disabled during initial setup +BACKUP_RETENTION_DAYS=3 +BACKUP_CRON_SCHEDULE="0 4 * * 0" + +# Network settings +NETWORK_NAME=azerothcore +NETWORK_SUBNET=172.20.0.0/16 + +# Storage paths +STORAGE_PATH_CONTAINERS=./volumes + +# Port configurations +DOCKER_DB_EXTERNAL_PORT=64306 +DOCKER_AUTH_EXTERNAL_PORT=3784 +DOCKER_WORLD_EXTERNAL_PORT=8215 +DOCKER_SOAP_EXTERNAL_PORT=7778 +PMA_EXTERNAL_PORT=8081 +KEIRA3_EXTERNAL_PORT=4201 +INFLUXDB_EXTERNAL_PORT=8087 +GF_EXTERNAL_PORT=3001 +EOF + + echo "✅ Created .env.portainer with optimized settings" +} + +# Create minimal docker-compose for phased deployment +create_minimal_compose() { + echo "📝 Creating minimal docker-compose for phased deployment..." + + cat > docker-compose.minimal.yml << 'EOF' +# Minimal AzerothCore setup for slow machines - Phase 1: Core services only +services: + ac-mysql: + image: mysql:8.0 + container_name: ac-mysql + environment: + MYSQL_ROOT_PASSWORD: ${DOCKER_DB_ROOT_PASSWORD:-password} + MYSQL_ROOT_HOST: '%' + ports: + - "64306:3306" + volumes: + - ./volumes/azerothcore/mysql:/var/lib/mysql + command: + - --default-authentication-plugin=mysql_native_password + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_unicode_ci + - --max_connections=200 + - --innodb-buffer-pool-size=128M + - --innodb-log-file-size=32M + restart: unless-stopped + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${DOCKER_DB_ROOT_PASSWORD:-password}"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + networks: + - azerothcore + + ac-db-init: + image: mysql:8.0 + container_name: ac-db-init + depends_on: + ac-mysql: + condition: service_healthy + networks: + - azerothcore + environment: + MYSQL_PWD: ${DOCKER_DB_ROOT_PASSWORD:-password} + command: + - sh + - -c + - | + echo "Creating AzerothCore databases..." + mysql -h ac-mysql -uroot -e " + CREATE DATABASE IF NOT EXISTS acore_auth DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + CREATE DATABASE IF NOT EXISTS acore_world DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + CREATE DATABASE IF NOT EXISTS acore_characters DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + SHOW DATABASES; + " || true + echo "Databases created!" + restart: "no" + +networks: + azerothcore: + driver: bridge +EOF + + echo "✅ Created docker-compose.minimal.yml for phase 1" +} + +# Create data download script for separate execution +create_data_download_script() { + echo "📝 Creating separate client data download script..." + + cat > download-client-data.sh << 'EOF' +#!/bin/bash +# Separate client data download - run this independently +echo "🚀 Starting client data download..." + +# Create data directory +mkdir -p ./volumes/azerothcore/data + +# Check if data already exists +if [ -d './volumes/azerothcore/data/maps' ] && [ -d './volumes/azerothcore/data/vmaps' ]; then + echo '✅ Game data already exists, skipping download' + exit 0 +fi + +echo '📥 Downloading client data (this may take 30+ minutes on slow connections)...' + +# Download with progress and resume capability +wget -c -t 3 --progress=bar:force \ + -O ./volumes/azerothcore/data/data.zip \ + "https://github.com/wowgaming/client-data/releases/download/v16/data.zip" + +if [ $? -eq 0 ]; then + echo '📂 Extracting client data...' + cd ./volumes/azerothcore/data + unzip -q data.zip + rm -f data.zip + echo '✅ Client data download and extraction complete!' +else + echo '❌ Download failed. You may need to:' + echo '1. Run this script again (wget will resume)' + echo '2. Download manually from a faster connection' + echo '3. Copy data from another AzerothCore installation' +fi +EOF + + chmod +x download-client-data.sh + echo "✅ Created download-client-data.sh script" +} + +# Create deployment instructions +create_deployment_guide() { + echo "📝 Creating deployment guide..." + + cat > PORTAINER-DEPLOYMENT.md << 'EOF' +# AzerothCore Portainer Deployment Guide + +## For Slow Machines / High Latency Connections + +### Phase 1: Pre-setup (Optional but Recommended) +1. Run diagnostics: `bash portainer-diagnostics.sh` +2. Pre-download client data: `bash download-client-data.sh` + +### Phase 2: Minimal Core Services +1. Copy `.env.portainer` to `.env` +2. Deploy using `docker-compose.minimal.yml`: + ```bash + podman-compose -f docker-compose.minimal.yml up -d + ``` + +### Phase 3: Add Database Import +Once Phase 2 is stable, add the db-import service to your stack. + +### Phase 4: Add Application Services +Finally, add authserver and worldserver. + +### Phase 5: Add Optional Services +Add monitoring, backup, and management tools last. + +## Troubleshooting Tips + +### 504 Gateway Timeouts +- These usually mean operations are taking too long, not failing +- Check logs: `podman-compose logs [service-name]` +- Monitor progress: `bash portainer-verify.sh` + +### Memory Issues +- Reduce `PLAYERBOT_MAX_BOTS` to 5-10 +- Disable monitoring services temporarily +- Deploy one service at a time + +### Network Issues +- Pre-download client data on faster connection +- Use local file copies instead of downloads +- Check firewall/proxy settings + +### Disk Space Issues +- Need minimum 20GB free space +- Monitor with `df -h` +- Clean up unused Podman images: `podman system prune` + +## Service Dependencies +``` +MySQL → DB Init → DB Import → Auth Server → World Server + ↓ + Client Data (parallel) +``` + +Deploy in this order for best results. +EOF + + echo "✅ Created PORTAINER-DEPLOYMENT.md guide" +} + +# Main execution +echo "🛠️ Applying Portainer optimizations..." + +create_portainer_env +create_minimal_compose +create_data_download_script +create_deployment_guide + +echo "" +echo "✅ Portainer optimization complete!" +echo "" +echo "📋 Next Steps:" +echo "1. Run: bash portainer-diagnostics.sh (to check your system)" +echo "2. Run: bash download-client-data.sh (to pre-download game data)" +echo "3. Copy .env.portainer to .env" +echo "4. Deploy with: podman-compose -f docker-compose.minimal.yml up -d" +echo "5. Monitor with: bash portainer-verify.sh" +echo "" +echo "📖 See PORTAINER-DEPLOYMENT.md for detailed instructions" \ No newline at end of file