apps/startup-scripts/README.md
A comprehensive suite of scripts for managing AzerothCore server instances with advanced session management, automatic restart capabilities, and production-ready service management.
The AzerothCore startup scripts provide multiple approaches to running server instances:
All scripts are integrated into the acore.sh dashboard for easy access.
Important: When you compile AzerothCore using the acore dashboard (./acore.sh compiler build), all startup scripts are automatically copied from apps/startup-scripts/src/ to your bin/ folder. This means:
bin/ folder to different serversThis makes it easy to deploy your compiled binaries along with the management scripts to production environments where you may not have the full AzerothCore source code.
run-engine: Advanced script with session management and configuration prioritysimple-restarter: Wrapper around starter with restart functionality (legacy compatibility)starter: Basic binary execution with optional GDB supportservice-manager.sh: Production service management with PM2/systemdconf.sh.dist: Default configuration templateconf.sh: User configuration (create from .dist)gdb.conf: GDB debugging configurationrestarter-auth.sh: Auth server restart examplerestarter-world.sh: World server restart examplestarter-auth.sh: Auth server basic start examplestarter-world.sh: World server basic start example# Start authserver directly
./starter /path/to/bin authserver
# Start worldserver with config
./starter /path/to/bin worldserver "" /path/to/worldserver.conf
# Using simple-restarter (legacy)
./simple-restarter /path/to/bin authserver
# Using run-engine (recommended)
./run-engine restart authserver --bin-path /path/to/bin
# Create and start a service
./service-manager.sh create auth authserver --bin-path /path/to/bin
# List all services
./service-manager.sh list
# Stop a service
./service-manager.sh stop auth
# Interactive dashboard
./acore.sh
# Direct commands
./acore.sh run-authserver # Start authserver with restart
./acore.sh run-worldserver # Start worldserver with restart
./acore.sh service-manager # Access service manager
conf.sh - User configuration fileRUN_ENGINE_* variablesconf.sh.dist - Default configuration# Copy default configuration
cp scripts/conf.sh.dist scripts/conf.sh
# Edit your configuration
nano scripts/conf.sh
# Binary settings
export BINPATH="/path/to/azerothcore/bin"
export SERVERBIN="worldserver" # or "authserver"
export CONFIG="/path/to/worldserver.conf"
# Session management
export SESSION_MANAGER="tmux" # none|auto|tmux|screen
export SESSION_NAME="ac-world"
# Interactive mode control
export AC_DISABLE_INTERACTIVE="0" # Set to 1 to disable interactive prompts (useful for non-interactive services)
# Debugging
export GDB_ENABLED="1" # 0 or 1
export GDB="/path/to/gdb.conf"
# Logging
export LOGS_PATH="/path/to/logs"
export CRASHES_PATH="/path/to/crashes"
export LOG_PREFIX_NAME="realm1"
The run-engine is the most advanced script with multiple operation modes:
# Start server once
./run-engine start worldserver --bin-path /path/to/bin
# Start with configuration file
./run-engine start worldserver --config ./conf-world.sh
# Start with specific server config
./run-engine start worldserver --server-config /path/to/worldserver.conf
# Automatic restart on crash
./run-engine restart worldserver --bin-path /path/to/bin
# Restart with session management
./run-engine restart worldserver --session-manager tmux
# Start in tmux session
./run-engine start worldserver --session-manager tmux
# Attach to existing session
tmux attach-session -t worldserver
# Start in screen session
./run-engine start worldserver --session-manager screen
# Attach to screen session
screen -r worldserver
./run-engine restart worldserver \
--bin-path /path/to/bin \
--server-config /path/to/worldserver.conf \
--session-manager tmux \
--gdb-enabled 1 \
--logs-path /path/to/logs \
--crashes-path /path/to/crashes
Legacy-compatible wrapper with restart functionality:
# Basic restart
./simple-restarter /path/to/bin worldserver
# With full parameters
./simple-restarter \
/path/to/bin \
worldserver \
./gdb.conf \
/path/to/worldserver.conf \
/path/to/system.log \
/path/to/system.err \
1 \
/path/to/crashes
Parameters:
Basic execution script without restart functionality:
# Simple start
./starter /path/to/bin worldserver
# With GDB debugging
./starter /path/to/bin worldserver ./gdb.conf /path/to/worldserver.conf "" "" 1
Production-ready service management:
# Auto-detect provider (PM2 or systemd)
./service-manager.sh create auth authserver --bin-path /path/to/bin
# Force PM2
./service-manager.sh create world worldserver --provider pm2 --bin-path /path/to/bin
# Force systemd
./service-manager.sh create world worldserver --provider systemd --bin-path /path/to/bin
# Create service with restart policy
./service-manager.sh create world worldserver --bin-path /path/to/bin --restart-policy always
Services support two restart policies:
on-failure (default): Restart only on crashes or errors (exit code != 0, only works with PM2 or systemd without tmux/screen)always: Restart on any exit, including clean shutdown (exit code 0)Important: When using --restart-policy always, the in-game command server shutdown X will behave like server restart X - the service will automatically restart after shutdown. Only the shutdown message differs from a restart message.
# Service that restarts only on crashes (default behavior)
./service-manager.sh create auth authserver --bin-path /path/to/bin --restart-policy on-failure
# Service that always restarts (even on manual shutdown)
./service-manager.sh create world worldserver --bin-path /path/to/bin --restart-policy always
# Update existing service restart policy
./service-manager.sh update worldserver --restart-policy always
# Start/stop services
./service-manager.sh start auth
./service-manager.sh stop world
./service-manager.sh restart auth
# View logs
./service-manager.sh logs world
./service-manager.sh logs world --follow
# Attach to console (interactive)
./service-manager.sh attach world
# List services
./service-manager.sh list
./service-manager.sh list pm2
./service-manager.sh list systemd
# Delete service
./service-manager.sh delete auth
Use these commands to programmatically check service health and interact with the console (used by CI workflows):
# Check if service is currently running (exit 0 if running)
./service-manager.sh is-running world
# Print current uptime in seconds (fails if not running)
./service-manager.sh uptime-seconds world
# Wait until uptime >= 10s (optional timeout 240s)
./service-manager.sh wait-uptime world 10 240
# Send a console command (uses pm2 send or tmux/screen)
./service-manager.sh send world "server info"
# Show provider, configs and run-engine settings
./service-manager.sh show-config world
Notes:
send, PM2 provider uses pm2 send with the process ID; systemd provider requires a session manager (tmux/screen). If no attachable session is configured, the command fails.wait-uptime fails with a non-zero exit code if the service does not reach the requested uptime within the timeout window.# Update service settings
./service-manager.sh update world --session-manager screen --gdb-enabled 1
# Edit configuration
./service-manager.sh edit world
# Restore missing services from registry
./service-manager.sh restore
# Create multiple world server instances with different restart policies
./service-manager.sh create world1 worldserver \
--bin-path /path/to/bin \
--server-config /path/to/worldserver-realm1.conf \
--restart-policy on-failure
./service-manager.sh create world2 worldserver \
--bin-path /path/to/bin \
--server-config /path/to/worldserver-realm2.conf \
--restart-policy always
# Single auth server for all realms (always restart for stability)
./service-manager.sh create auth authserver \
--bin-path /path/to/bin \
--server-config /path/to/authserver.conf \
--restart-policy always
Create separate configuration files for each realm:
conf-realm1.sh:
export BINPATH="/path/to/bin"
export SERVERBIN="worldserver"
export CONFIG="/path/to/worldserver-realm1.conf"
export SESSION_NAME="ac-realm1"
export LOG_PREFIX_NAME="realm1"
export LOGS_PATH="/path/to/logs/realm1"
conf-realm2.sh:
export BINPATH="/path/to/bin"
export SERVERBIN="worldserver"
export CONFIG="/path/to/worldserver-realm2.conf"
export SESSION_NAME="ac-realm2"
export LOG_PREFIX_NAME="realm2"
export LOGS_PATH="/path/to/logs/realm2"
Start each realm:
./run-engine restart worldserver --config ./conf-realm1.sh
./run-engine restart worldserver --config ./conf-realm2.sh
Copy and modify the example scripts:
# Copy examples
cp examples/restarter-world.sh restarter-realm1.sh
cp examples/restarter-world.sh restarter-realm2.sh
# Edit each script to point to different configuration files
# Then run:
./restarter-realm1.sh
./restarter-realm2.sh
The service manager includes a comprehensive registry system that tracks all created services and enables automatic restoration:
# Check for missing services and restore them
./service-manager.sh restore
# List all registered services (includes status)
./service-manager.sh list
# Services are automatically added to registry on creation
./service-manager.sh create auth authserver --bin-path /path/to/bin
You can customize where service configurations and PM2/systemd files are stored:
# Set custom directories
export AC_SERVICE_CONFIG_DIR="/path/to/your/project/services"
# Now all service operations will use these custom directories
./service-manager.sh create auth authserver --bin-path /path/to/bin
This is particularly useful for:
The service manager automatically stores binary and configuration paths as relative paths when they are located under the AC_SERVICE_CONFIG_DIR, making service configurations portable across environments:
# Set up a portable project structure
export AC_SERVICE_CONFIG_DIR="/opt/myproject/services"
mkdir -p "$AC_SERVICE_CONFIG_DIR"/{bin,etc}
# Copy your binaries and configs
cp /path/to/compiled/authserver "$AC_SERVICE_CONFIG_DIR/bin/"
cp /path/to/authserver.conf "$AC_SERVICE_CONFIG_DIR/etc/"
# Create service - paths under AC_SERVICE_CONFIG_DIR will be stored as relative
./service-manager.sh create auth authserver \
--bin-path "$AC_SERVICE_CONFIG_DIR/bin" \
--server-config "$AC_SERVICE_CONFIG_DIR/etc/authserver.conf"
# Registry will contain relative paths like "bin/authserver" and "etc/authserver.conf"
# instead of absolute paths, making the entire directory portable
Benefits:
How it works:
AC_SERVICE_CONFIG_DIR are automatically stored as relative pathsAC_SERVICE_CONFIG_DIR are stored as absolute paths for safetyAC_SERVICE_CONFIG_DIRAC_SERVICE_CONFIG_DIR is not set, all paths are stored as absolute paths (traditional behavior)If you have existing services in the old format, use the migration script:
# Migrate existing registry to new format
./migrate-registry.sh
# The script will:
# - Detect old format automatically
# - Create a backup of the old registry
# - Convert to new format with proper tracking
# - Preserve all existing service information
When using PM2 as the service provider:
Automatic PM2 Persistence: The service manager automatically configures PM2 for persistence across reboots by:
pm2 startup to set up the startup scriptpm2 save after each service creation/modificationNOTE: pm2 cannot run tmux/screen sessions, but you can always use the attach command to connect to the service console because pm2 supports interactive mode.
The startup scripts recognize several environment variables for configuration and runtime behavior:
AC_SERVICE_CONFIG_DIR: Override the default configuration directory for services registry and configurations
${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/servicesAC_LAUNCHED_BY_PM2: Set to 1 when launched by PM2 (automatically set by service-manager)
unbuffer command for output captureAC_DISABLE_INTERACTIVE: Controls interactive mode (0=enabled, 1=disabled)
RUN_ENGINE_*: See Configuration section for complete listSERVICE_MODE: Set to true to enable service-specific behaviorSESSION_MANAGER: Override session manager choice (tmux, screen, none, auto)When using systemd as the service provider:
# Systemd commands
systemctl --user status acore-auth # Check status
systemctl --user logs acore-auth # View logs
systemctl --user restart acore-auth # Restart
systemctl --user enable acore-auth # Enable auto-start
# For system services (requires sudo)
sudo systemctl status acore-auth
sudo systemctl enable acore-auth
Enhanced systemd Integration:
Type=forking for proper daemon behaviorExecStop commands to properly terminate tmux/screen sessions when stopping the serviceAC_DISABLE_INTERACTIVE=1 to prevent hanging on promptsServices can be configured with session managers for interactive access:
# Create service with tmux
./service-manager.sh create world worldserver \
--bin-path /path/to/bin \
--session-manager tmux
# Attach to the session
./service-manager.sh attach world
# or directly:
tmux attach-session -t worldserver
The startup scripts are fully integrated into the AzerothCore dashboard:
# Run servers with simple restart (development/testing)
./acore.sh run-worldserver # Option 11 or 'rw'
./acore.sh run-authserver # Option 12 or 'ra'
# Access service manager (production)
./acore.sh service-manager # Option 15 or 'sm'
# Examples:
./acore.sh rw # Quick worldserver start
./acore.sh ra # Quick authserver start
./acore.sh sm create auth authserver --bin-path /path/to/bin
simple-restarter with appropriate binaryError: Binary '/path/to/bin/worldserver' not found
Solution: Check binary path and ensure servers are compiled
# Check if binary exists
ls -la /path/to/bin/worldserver
# Compile if needed
./acore.sh compiler build
Error: Configuration file not found
Solution: Create configuration from template
cp scripts/conf.sh.dist scripts/conf.sh
# Edit conf.sh with correct paths
Warning: tmux not found, falling back to direct execution
Solution: Install required session manager
# Ubuntu/Debian
sudo apt install tmux screen
# CentOS/RHEL
sudo yum install tmux screen
Failed to create systemd service
Solution: Check user permissions or use --system flag
# For user services (no sudo required)
./service-manager.sh create auth authserver --bin-path /path/to/bin
# For system services (requires sudo)
./service-manager.sh create auth authserver --bin-path /path/to/bin --system
Error: PM2 is not installed
Solution: Install PM2
npm install -g pm2
# or
sudo npm install -g pm2
# If the service registry shows services that don't actually exist
Solution: Use registry sync or restore
# Check and restore missing services (also cleans up orphaned entries)
./service-manager.sh restore
# If you have a very old registry format, migrate it
./migrate-registry.sh