diff --git a/.env.prebuilt b/.env.prebuilt
new file mode 100644
index 0000000..68a9dc9
--- /dev/null
+++ b/.env.prebuilt
@@ -0,0 +1,321 @@
+# ================================================================================
+# AzerothCore RealmMaster - Pre-Built Images Configuration
+# ================================================================================
+# Use this minimal configuration file to deploy pre-built RealmMaster images
+# from Docker Hub. No local building required!
+#
+# Quick Start:
+# 1. Copy this file: cp .env.prebuilt .env
+# 2. Set your DOCKERHUB_USERNAME below
+# 3. Run: ./deploy.sh
+#
+# The pre-built images include 32 modules from the RealmMaster profile:
+# - Playerbots, Transmog, Solo LFG, Eluna, NPC Buffer, and 27 more
+# - See config/module-profiles/RealmMaster.json for full list
+# ================================================================================
+
+# =====================
+# REQUIRED: Docker Hub Configuration
+# =====================
+# Set this to your Docker Hub username where the images are published
+DOCKERHUB_USERNAME=your-dockerhub-username
+
+# =====================
+# Project Configuration
+# =====================
+COMPOSE_PROJECT_NAME=azerothcore-realmmaster
+
+# =====================
+# Module Profile Selection
+# =====================
+# Choose which module profile build to use:
+# - realmmaster: 32 modules (playerbots, transmog, solo-lfg, eluna, etc.) - ✅ Available now (Recommended)
+#
+# Additional profiles (available soon - will be built on demand):
+# - suggested-modules: Alternative suggested module set
+# - all-modules: All supported modules
+# - playerbots-only: Just playerbots
+#
+# Note: Only 'realmmaster' images are currently published to Docker Hub.
+# Other profiles will be available when built via GitHub Actions workflow.
+MODULE_PROFILE=realmmaster
+
+# =====================
+# Pre-Built Images from Docker Hub
+# =====================
+# These images are built nightly with different module profiles
+# Using profile-specific tags ensures you get the exact module set you want
+AC_AUTHSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:authserver-${MODULE_PROFILE}-latest
+AC_WORLDSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:worldserver-${MODULE_PROFILE}-latest
+
+# Alternative: Use date-tagged images for version pinning
+# AC_AUTHSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:authserver-${MODULE_PROFILE}-20260109
+# AC_WORLDSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:worldserver-${MODULE_PROFILE}-20260109
+
+# Alternative: Use generic latest tags (default: realmmaster profile)
+# AC_AUTHSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:authserver-latest
+# AC_WORLDSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:worldserver-latest
+
+# Standard images (fallback if modules images not available)
+AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:master
+AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:master
+
+# Playerbots images (referenced by docker-compose, even if using modules profile)
+AC_AUTHSERVER_IMAGE_PLAYERBOTS=${COMPOSE_PROJECT_NAME}:authserver-playerbots
+AC_WORLDSERVER_IMAGE_PLAYERBOTS=${COMPOSE_PROJECT_NAME}:worldserver-playerbots
+AC_CLIENT_DATA_IMAGE_PLAYERBOTS=${COMPOSE_PROJECT_NAME}:client-data-playerbots
+
+# Database and client data images
+AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:master
+AC_CLIENT_DATA_IMAGE=acore/ac-wotlk-client-data:master
+
+# Helper images
+ALPINE_IMAGE=alpine:latest
+MYSQL_IMAGE=mysql:8.0
+
+# =====================
+# Storage Paths
+# =====================
+STORAGE_PATH=./storage
+STORAGE_PATH_LOCAL=./local-storage
+STORAGE_CONFIG_PATH=${STORAGE_PATH}/config
+STORAGE_LOGS_PATH=${STORAGE_PATH}/logs
+STORAGE_MODULES_PATH=${STORAGE_PATH}/modules
+STORAGE_LUA_SCRIPTS_PATH=${STORAGE_PATH}/lua_scripts
+STORAGE_MODULE_SQL_PATH=${STORAGE_PATH}/module-sql-updates
+STORAGE_INSTALL_MARKERS_PATH=${STORAGE_PATH}/install-markers
+STORAGE_CLIENT_DATA_PATH=${STORAGE_PATH}/client-data
+BACKUP_PATH=${STORAGE_PATH}/backups
+
+# =====================
+# Timezone
+# =====================
+HOST_ZONEINFO_PATH=/usr/share/zoneinfo
+TZ=UTC
+
+# =====================
+# Networking
+# =====================
+NETWORK_NAME=azerothcore
+NETWORK_SUBNET=172.20.0.0/16
+NETWORK_GATEWAY=172.20.0.1
+
+# =====================
+# Server Address & Realm
+# =====================
+# Change this to your server's public IP or domain name
+SERVER_ADDRESS=127.0.0.1
+REALM_PORT=8215
+
+# =====================
+# Ports
+# =====================
+# Authentication server
+AUTH_EXTERNAL_PORT=3784
+AUTH_PORT=3724
+
+# World server
+WORLD_EXTERNAL_PORT=8215
+WORLD_PORT=8085
+
+# SOAP/Remote access
+SOAP_EXTERNAL_PORT=7778
+SOAP_PORT=7878
+
+# MySQL database (for external access)
+MYSQL_EXTERNAL_PORT=64306
+
+# phpMyAdmin web interface
+PMA_EXTERNAL_PORT=8081
+
+# Keira3 editor interface
+KEIRA3_EXTERNAL_PORT=4201
+
+# =====================
+# MySQL Database Configuration
+# =====================
+MYSQL_IMAGE=mysql:8.0
+CONTAINER_MYSQL=ac-mysql
+MYSQL_HOST=ac-mysql
+MYSQL_PORT=3306
+
+# Security: Change these passwords!
+MYSQL_ROOT_PASSWORD=azerothcore123
+MYSQL_ROOT_HOST=%
+MYSQL_USER=root
+
+# Database names
+DB_AUTH_NAME=acore_auth
+DB_WORLD_NAME=acore_world
+DB_CHARACTERS_NAME=acore_characters
+DB_PLAYERBOTS_NAME=acore_playerbots
+
+# Database performance settings
+MYSQL_CHARACTER_SET=utf8mb4
+MYSQL_COLLATION=utf8mb4_unicode_ci
+MYSQL_MAX_CONNECTIONS=1000
+MYSQL_INNODB_BUFFER_POOL_SIZE=256M
+MYSQL_INNODB_LOG_FILE_SIZE=64M
+MYSQL_INNODB_REDO_LOG_CAPACITY=512M
+
+# MySQL tmpfs (RAM disk) for performance
+MYSQL_RUNTIME_TMPFS_SIZE=8G
+MYSQL_DISABLE_BINLOG=1
+
+# Database connection settings
+DB_WAIT_RETRIES=60
+DB_WAIT_SLEEP=10
+DB_RECONNECT_SECONDS=5
+DB_RECONNECT_ATTEMPTS=5
+
+# Database worker threads
+DB_LOGIN_WORKER_THREADS=1
+DB_WORLD_WORKER_THREADS=1
+DB_CHARACTER_WORKER_THREADS=1
+DB_LOGIN_SYNCH_THREADS=1
+DB_WORLD_SYNCH_THREADS=1
+DB_CHARACTER_SYNCH_THREADS=1
+
+# =====================
+# Automated Backups
+# =====================
+BACKUP_RETENTION_DAYS=3
+BACKUP_RETENTION_HOURS=6
+BACKUP_DAILY_TIME=09:00
+BACKUP_INTERVAL_MINUTES=60
+BACKUP_EXTRA_DATABASES=
+BACKUP_HEALTHCHECK_MAX_MINUTES=1440
+BACKUP_HEALTHCHECK_GRACE_SECONDS=4500
+
+# =====================
+# Module Configuration (Pre-Built)
+# =====================
+# These settings tell the system that modules are already built into the images
+STACK_IMAGE_MODE=modules
+STACK_SOURCE_VARIANT=playerbots
+
+# Key modules enabled (needed for profile detection)
+# The RealmMaster profile includes playerbots, so we need this set for deploy.sh to use the correct profile
+MODULE_PLAYERBOTS=1
+
+# Note: MODULES_ENABLED_LIST varies by profile - the list below is for the 'realmmaster' profile
+# For other profiles, see the corresponding JSON in config/module-profiles/
+MODULES_ENABLED_LIST=MODULE_PLAYERBOTS,MODULE_TRANSMOG,MODULE_SOLO_LFG,MODULE_ELUNA,MODULE_AIO,MODULE_NPC_BUFFER,MODULE_NPC_BEASTMASTER,MODULE_SOLOCRAFT,MODULE_1V1_ARENA,MODULE_ACCOUNT_ACHIEVEMENTS,MODULE_ACTIVE_CHAT,MODULE_ARAC,MODULE_ASSISTANT,MODULE_AUTO_REVIVE,MODULE_BLACK_MARKET_AUCTION_HOUSE,MODULE_BOSS_ANNOUNCER,MODULE_BREAKING_NEWS,MODULE_ELUNA_SCRIPTS,MODULE_EVENT_SCRIPTS,MODULE_FIREWORKS,MODULE_GAIN_HONOR_GUARD,MODULE_GLOBAL_CHAT,MODULE_GUILDHOUSE,MODULE_INSTANCE_RESET,MODULE_ITEM_LEVEL_UP,MODULE_LEARN_SPELLS,MODULE_MORPHSUMMON,MODULE_NPC_ENCHANTER,MODULE_NPC_FREE_PROFESSIONS,MODULE_RANDOM_ENCHANTS,MODULE_REAGENT_BANK,MODULE_TIME_IS_TIME
+MODULES_CPP_LIST=
+MODULES_REQUIRES_CUSTOM_BUILD=0
+MODULES_REQUIRES_PLAYERBOT_SOURCE=1
+
+# =====================
+# Playerbot Runtime Configuration
+# =====================
+# Enable/disable playerbots and set population
+PLAYERBOT_ENABLED=1
+PLAYERBOT_MIN_BOTS=40
+PLAYERBOT_MAX_BOTS=200
+
+# =====================
+# Client Data
+# =====================
+# Client data version (auto-detected when blank)
+CLIENT_DATA_VERSION=
+CLIENT_DATA_PATH=
+
+# =====================
+# Server Configuration Preset
+# =====================
+# Apply a configuration preset during deployment
+# Options: none, blizzlike, fast-leveling, hardcore-pvp, casual-pve
+SERVER_CONFIG_PRESET=none
+
+# =====================
+# Eluna Lua Scripting
+# =====================
+AC_ELUNA_ENABLED=1
+AC_ELUNA_TRACE_BACK=1
+AC_ELUNA_AUTO_RELOAD=1
+AC_ELUNA_BYTECODE_CACHE=1
+AC_ELUNA_SCRIPT_PATH=lua_scripts
+AC_ELUNA_REQUIRE_PATHS=
+AC_ELUNA_REQUIRE_CPATHS=
+AC_ELUNA_AUTO_RELOAD_INTERVAL=1
+
+# =====================
+# Container Management
+# =====================
+CONTAINER_USER=0:0
+CONTAINER_DB_IMPORT=ac-db-import
+CONTAINER_DB_INIT=ac-db-init
+CONTAINER_DB_GUARD=ac-db-guard
+CONTAINER_BACKUP=ac-backup
+CONTAINER_MODULES=ac-modules
+CONTAINER_POST_INSTALL=ac-post-install
+
+# =====================
+# Database Guard
+# =====================
+DB_GUARD_RECHECK_SECONDS=120
+DB_GUARD_RETRY_SECONDS=10
+DB_GUARD_WAIT_ATTEMPTS=60
+DB_GUARD_HEALTH_MAX_AGE=180
+DB_GUARD_HEALTHCHECK_INTERVAL=30s
+DB_GUARD_HEALTHCHECK_TIMEOUT=10s
+DB_GUARD_HEALTHCHECK_RETRIES=5
+DB_GUARD_VERIFY_INTERVAL_SECONDS=86400
+
+# =====================
+# Health Checks
+# =====================
+# MySQL health checks
+MYSQL_HEALTHCHECK_INTERVAL=20s
+MYSQL_HEALTHCHECK_TIMEOUT=15s
+MYSQL_HEALTHCHECK_RETRIES=25
+MYSQL_HEALTHCHECK_START_PERIOD=120s
+
+# Auth server health checks
+AUTH_HEALTHCHECK_INTERVAL=30s
+AUTH_HEALTHCHECK_TIMEOUT=10s
+AUTH_HEALTHCHECK_RETRIES=3
+AUTH_HEALTHCHECK_START_PERIOD=60s
+
+# World server health checks
+WORLD_HEALTHCHECK_INTERVAL=30s
+WORLD_HEALTHCHECK_TIMEOUT=10s
+WORLD_HEALTHCHECK_RETRIES=3
+WORLD_HEALTHCHECK_START_PERIOD=120s
+
+# Backup health checks
+BACKUP_HEALTHCHECK_INTERVAL=60s
+BACKUP_HEALTHCHECK_TIMEOUT=30s
+BACKUP_HEALTHCHECK_RETRIES=3
+BACKUP_HEALTHCHECK_START_PERIOD=120s
+
+# =====================
+# Management Tools
+# =====================
+# phpMyAdmin configuration
+PMA_HOST=ac-mysql
+PMA_PORT=3306
+PMA_USER=root
+PMA_ARBITRARY=1
+PMA_ABSOLUTE_URI=
+PMA_UPLOAD_LIMIT=300M
+PMA_MEMORY_LIMIT=512M
+PMA_MAX_EXECUTION_TIME=600
+
+# Keira3 configuration
+KEIRA_DATABASE_HOST=ac-mysql
+KEIRA_DATABASE_PORT=3306
+
+# =====================
+# Compose Overrides
+# =====================
+# Enable optional compose overrides (set to 1 to enable)
+COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=0
+COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=0
+
+# =====================
+# DO NOT MODIFY BELOW (Build-related, not used with pre-built images)
+# =====================
+AUTO_REBUILD_ON_DEPLOY=0
+DB_UPDATES_ALLOWED_MODULES=all
+DB_UPDATES_REDUNDANCY=1
diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml
new file mode 100644
index 0000000..eb2263f
--- /dev/null
+++ b/.github/workflows/build-and-publish.yml
@@ -0,0 +1,248 @@
+name: Build and Publish
+
+# This workflow builds AzerothCore with configurable module profiles
+# and publishes profile-tagged Docker images to Docker Hub for easy deployment.
+#
+# Default Profile: RealmMaster (32 modules including playerbots, transmog, solo-lfg, eluna, etc.)
+# Available Profiles: RealmMaster, suggested-modules, all-modules, playerbots-only, or custom
+# Profile Configuration: See config/module-profiles/
+# Documentation: See docs/CICD.md
+#
+# Published Image Tags:
+# - authserver-{profile}-latest (e.g., authserver-realmmaster-latest)
+# - authserver-{profile}-YYYYMMDD (e.g., authserver-realmmaster-20260109)
+# - authserver-latest (generic tag, defaults to RealmMaster)
+# - worldserver-{profile}-latest
+# - worldserver-{profile}-YYYYMMDD
+# - worldserver-latest (generic tag, defaults to RealmMaster)
+
+on:
+ schedule:
+ # Run nightly at 2 AM UTC
+ - cron: '0 2 * * *'
+ workflow_dispatch:
+ inputs:
+ module_profile:
+ description: 'Module profile to build (e.g., RealmMaster, suggested-modules, all-modules)'
+ required: false
+ type: string
+ default: 'RealmMaster'
+ force_rebuild:
+ description: 'Force rebuild even if no changes detected'
+ required: false
+ type: boolean
+ default: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Git
+ run: |
+ # Configure git for module repository cloning
+ git config --global user.name "GitHub Actions Bot"
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git --version
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Prepare build environment
+ env:
+ TERM: xterm
+ run: |
+ # Determine which module profile to use
+ if [ "${{ github.event_name }}" = "schedule" ]; then
+ MODULE_PROFILE="RealmMaster"
+ else
+ MODULE_PROFILE="${{ github.event.inputs.module_profile }}"
+ MODULE_PROFILE="${MODULE_PROFILE:-RealmMaster}"
+ fi
+
+ echo "📋 Using module profile: ${MODULE_PROFILE}"
+ echo "🔧 Running setup.sh to generate proper .env file..."
+
+ # Use setup.sh to generate .env with proper configuration
+ # Benefits of this approach:
+ # - Uses the same setup logic as local builds (consistency)
+ # - Handles all path variables correctly (no manual sed patching needed)
+ # - Automatically determines source variant (standard vs playerbots)
+ # - Applies module profile and dependencies correctly
+ # - Centralizes configuration logic in one place (setup.sh)
+ ./setup.sh \
+ --non-interactive \
+ --module-config "${MODULE_PROFILE}" \
+ --deployment-type local \
+ --force
+
+ echo "✅ Environment configuration generated successfully"
+
+ # Extract values for GitHub environment
+ PROJECT_NAME=$(grep '^COMPOSE_PROJECT_NAME=' .env | cut -d'=' -f2 | tr -d '\r' | sed 's/[[:space:]]*#.*//' | sed 's/[[:space:]]*$//')
+ echo "PROJECT_NAME=${PROJECT_NAME}" >> $GITHUB_ENV
+
+ # Store profile name for image tagging (lowercase, replace underscores with hyphens)
+ PROFILE_TAG=$(echo "${MODULE_PROFILE}" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
+ echo "PROFILE_TAG=${PROFILE_TAG}" >> $GITHUB_ENV
+ echo "MODULE_PROFILE=${MODULE_PROFILE}" >> $GITHUB_ENV
+
+ # Count enabled modules
+ MODULE_COUNT=$(grep -c '^MODULE_.*=1' .env || echo "0")
+ echo "MODULE_COUNT=${MODULE_COUNT}" >> $GITHUB_ENV
+
+ # Display configuration summary
+ echo ""
+ echo "📊 Build Configuration Summary:"
+ echo " Project: ${PROJECT_NAME}"
+ echo " Profile: ${MODULE_PROFILE}"
+ echo " Profile Tag: ${PROFILE_TAG}"
+ echo " Modules: ${MODULE_COUNT} enabled"
+ echo ""
+ echo "Enabled modules (first 10):"
+ grep '^MODULE_.*=1' .env | head -10 || true
+ echo ""
+
+ # Show key paths for verification
+ echo "📂 Key Paths:"
+ grep '^STORAGE_PATH_LOCAL=' .env || echo " STORAGE_PATH_LOCAL not found"
+ grep '^MODULES_REBUILD_SOURCE_PATH=' .env || echo " MODULES_REBUILD_SOURCE_PATH not found"
+ grep '^STACK_SOURCE_VARIANT=' .env || echo " STACK_SOURCE_VARIANT not found"
+ echo ""
+
+ # Verify all Docker images are configured
+ echo "🐳 Docker Images (that we build and push):"
+ grep -E '^AC_AUTHSERVER_IMAGE_PLAYERBOTS=' .env || echo " AC_AUTHSERVER_IMAGE_PLAYERBOTS not found"
+ grep -E '^AC_WORLDSERVER_IMAGE_PLAYERBOTS=' .env || echo " AC_WORLDSERVER_IMAGE_PLAYERBOTS not found"
+ grep -E '^AC_AUTHSERVER_IMAGE_MODULES=' .env || echo " AC_AUTHSERVER_IMAGE_MODULES not found"
+ grep -E '^AC_WORLDSERVER_IMAGE_MODULES=' .env || echo " AC_WORLDSERVER_IMAGE_MODULES not found"
+
+ - name: Cache Go build cache
+ uses: actions/cache@v4
+ with:
+ path: .gocache
+ key: ${{ runner.os }}-gocache-${{ hashFiles('**/go.sum') }}
+ restore-keys: |
+ ${{ runner.os }}-gocache-
+
+ - name: Cache local storage
+ uses: actions/cache@v4
+ with:
+ path: local-storage/source
+ key: ${{ runner.os }}-source-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-source-
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+
+ - name: Run build
+ run: |
+ # The build.sh script will automatically:
+ # 1. Generate module state from the enabled modules in .env
+ # 2. Set up the AzerothCore source repository
+ # 3. Fetch and clone all enabled module repositories from GitHub
+ # 4. Stage modules to the source directory
+ # 5. Compile AzerothCore with all modules
+ # 6. Tag the resulting Docker images
+
+ BUILD_ARGS="--yes"
+
+ # Add force flag if manually triggered with force_rebuild
+ if [ "${{ github.event.inputs.force_rebuild }}" = "true" ]; then
+ BUILD_ARGS="${BUILD_ARGS} --force"
+ fi
+
+ echo "🔨 Starting build process with ${BUILD_ARGS}..."
+ echo "This will fetch and build all ${MODULE_COUNT} enabled modules from the ${MODULE_PROFILE} profile"
+
+ ./build.sh ${BUILD_ARGS}
+
+ - name: Tag images for Docker Hub
+ run: |
+ DATE_TAG=$(date +%Y%m%d)
+
+ # Tag authserver images with profile name
+ docker tag ${PROJECT_NAME}:authserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-latest
+ docker tag ${PROJECT_NAME}:authserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-${DATE_TAG}
+
+ # Also tag as generic 'latest' for backward compatibility
+ docker tag ${PROJECT_NAME}:authserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-latest
+
+ # Tag worldserver images with profile name
+ docker tag ${PROJECT_NAME}:worldserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-latest
+ docker tag ${PROJECT_NAME}:worldserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-${DATE_TAG}
+
+ # Also tag as generic 'latest' for backward compatibility
+ docker tag ${PROJECT_NAME}:worldserver-modules-latest \
+ ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-latest
+
+ echo "Tagged images with profile '${PROFILE_TAG}' and date '${DATE_TAG}'"
+
+ - name: Push images to Docker Hub
+ run: |
+ DATE_TAG=$(date +%Y%m%d)
+
+ # Push authserver images (all tags)
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-latest
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-${DATE_TAG}
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-latest
+
+ # Push worldserver images (all tags)
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-latest
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-${DATE_TAG}
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-latest
+
+ echo "✅ Pushed all image tags to Docker Hub"
+
+ - name: Build summary
+ run: |
+ DATE_TAG=$(date +%Y%m%d)
+
+ echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Build completed successfully" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ echo "### Configuration" >> $GITHUB_STEP_SUMMARY
+ echo "- **Module Profile**: ${MODULE_PROFILE}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Enabled Modules**: ${MODULE_COUNT}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View enabled modules
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ grep '^MODULE_.*=1' .env | sed 's/=1//' || true >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ echo "### Published Images" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "#### Profile-Specific Tags" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-latest\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-${PROFILE_TAG}-${DATE_TAG}\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-latest\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-${PROFILE_TAG}-${DATE_TAG}\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "#### Generic Tags (backward compatibility)" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:authserver-latest\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ secrets.DOCKERHUB_USERNAME }}/${PROJECT_NAME}:worldserver-latest\`" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml
new file mode 100644
index 0000000..b2a5ada
--- /dev/null
+++ b/.github/workflows/create-release.yml
@@ -0,0 +1,246 @@
+name: Create Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Release version (e.g., v1.0.0)'
+ required: true
+ type: string
+ profile:
+ description: 'Module profile for this release'
+ required: false
+ type: string
+ default: 'RealmMaster'
+ prerelease:
+ description: 'Mark as pre-release'
+ required: false
+ type: boolean
+ default: false
+
+jobs:
+ create-release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Prepare release variables
+ run: |
+ VERSION="${{ github.event.inputs.version }}"
+ PROFILE="${{ github.event.inputs.profile }}"
+ PROFILE_TAG=$(echo "${PROFILE}" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
+
+ echo "VERSION=${VERSION}" >> $GITHUB_ENV
+ echo "PROFILE=${PROFILE}" >> $GITHUB_ENV
+ echo "PROFILE_TAG=${PROFILE_TAG}" >> $GITHUB_ENV
+
+ # Get build date from Docker Hub image (or use current date)
+ BUILD_DATE=$(date +%Y%m%d)
+ echo "BUILD_DATE=${BUILD_DATE}" >> $GITHUB_ENV
+
+ # Get AzerothCore commit from local-storage if available
+ if [ -d "local-storage/source/azerothcore-playerbots" ]; then
+ ACORE_COMMIT=$(cd local-storage/source/azerothcore-playerbots && git rev-parse --short HEAD)
+ else
+ ACORE_COMMIT="unknown"
+ fi
+ echo "ACORE_COMMIT=${ACORE_COMMIT}" >> $GITHUB_ENV
+
+ - name: Read module list from profile
+ run: |
+ PROFILE_FILE="config/module-profiles/${PROFILE}.json"
+
+ if [ ! -f "$PROFILE_FILE" ]; then
+ echo "ERROR: Profile file not found: $PROFILE_FILE"
+ exit 1
+ fi
+
+ # Extract module count
+ MODULE_COUNT=$(python3 -c "import json; data=json.load(open('$PROFILE_FILE')); print(len(data.get('modules', [])))")
+ echo "MODULE_COUNT=${MODULE_COUNT}" >> $GITHUB_ENV
+
+ # Extract modules for release notes
+ python3 -c "import json; data=json.load(open('$PROFILE_FILE')); print('\n'.join(['- ' + m for m in data.get('modules', [])]))" > modules.txt
+
+ - name: Create deployment package
+ run: |
+ PACKAGE_NAME="azerothcore-realmmaster-${VERSION}-${PROFILE_TAG}"
+ mkdir -p "${PACKAGE_NAME}"
+
+ # Copy essential deployment files
+ cp .env.prebuilt "${PACKAGE_NAME}/.env.prebuilt"
+ cp docker-compose.yml "${PACKAGE_NAME}/docker-compose.yml"
+ cp deploy.sh "${PACKAGE_NAME}/deploy.sh"
+ cp status.sh "${PACKAGE_NAME}/status.sh"
+ cp cleanup.sh "${PACKAGE_NAME}/cleanup.sh"
+ cp README.md "${PACKAGE_NAME}/README.md"
+
+ # Copy scripts directory
+ cp -r scripts "${PACKAGE_NAME}/scripts"
+
+ # Copy config directory
+ cp -r config "${PACKAGE_NAME}/config"
+
+ # Copy docs directory
+ cp -r docs "${PACKAGE_NAME}/docs"
+
+ # Create a quick start guide specific to this release
+ cat > "${PACKAGE_NAME}/QUICKSTART.md" <> $GITHUB_ENV
+
+ - name: Generate release notes
+ run: |
+ cat > release_notes.md <> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Version**: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY
+ echo "**Profile**: ${{ env.PROFILE }}" >> $GITHUB_STEP_SUMMARY
+ echo "**Modules**: ${{ env.MODULE_COUNT }}" >> $GITHUB_STEP_SUMMARY
+ echo "**Package**: ${{ env.PACKAGE_NAME }}.zip" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📦 Release available at:" >> $GITHUB_STEP_SUMMARY
+ echo "https://github.com/${{ github.repository }}/releases/tag/${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY
diff --git a/README.md b/README.md
index 4453d59..3861b24 100644
--- a/README.md
+++ b/README.md
@@ -11,11 +11,13 @@ A complete containerized deployment of AzerothCore WoW 3.3.5a (Wrath of the Lich
- [Quick Start](#quick-start)
- [What You Get](#what-you-get)
- [Getting Started](#getting-started) → **[docs/GETTING_STARTED.md](docs/GETTING_STARTED.md)**
+- [Using Pre-Built Images](#using-pre-built-images-no-build-required) → **[docs/PREBUILT_IMAGES.md](docs/PREBUILT_IMAGES.md)**
- [Complete Module Catalog](#complete-module-catalog) → **[docs/MODULES.md](docs/MODULES.md)**
- [Management & Operations](#management--operations) → **[docs/GETTING_STARTED.md](docs/GETTING_STARTED.md)**
- [Advanced Configuration](#advanced-configuration) → **[docs/ADVANCED.md](docs/ADVANCED.md)**
- [Custom NPCs Guide](#custom-npcs-guide) → **[docs/NPCS.md](docs/NPCS.md)**
- [Script Reference](#script-reference) → **[docs/SCRIPTS.md](docs/SCRIPTS.md)**
+- [CI/CD & Pre-Built Images](#cicd--pre-built-images) → **[docs/CICD.md](docs/CICD.md)**
- [Troubleshooting](#troubleshooting) → **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)**
- [Credits & Next Steps](#credits--next-steps)
@@ -45,6 +47,25 @@ cd AzerothCore-RealmMaster
**First deployment takes 30-60 minutes** for database setup and client data download. Subsequent starts are much faster.
+### Using Pre-Built Images (No Build Required!)
+
+Skip the build process and deploy with pre-built Docker images:
+
+```bash
+# 1. Clone the repository
+git clone https://github.com/uprightbass360/AzerothCore-RealmMaster.git
+cd AzerothCore-RealmMaster
+
+# 2. Use pre-built configuration
+cp .env.prebuilt .env
+
+# 3. Edit .env and set DOCKERHUB_USERNAME
+# 4. Deploy
+./deploy.sh
+```
+
+Pre-built images include the **RealmMaster profile** (32 modules) and are automatically built nightly. See **[docs/PREBUILT_IMAGES.md](docs/PREBUILT_IMAGES.md)** for details.
+
See [Getting Started](#getting-started) for detailed walkthrough.
## What You Get
diff --git a/docs/CICD.md b/docs/CICD.md
new file mode 100644
index 0000000..898b936
--- /dev/null
+++ b/docs/CICD.md
@@ -0,0 +1,321 @@
+# CI/CD Documentation
+
+This document describes the continuous integration and deployment workflows configured for the AzerothCore RealmMaster project.
+
+## Build and Publish Workflow
+
+The `build-and-publish.yml` workflow automatically builds AzerothCore with your configured modules and publishes Docker images to Docker Hub.
+
+### Trigger Schedule
+
+- **Nightly builds**: Runs automatically at 2 AM UTC every day
+- **Manual trigger**: Can be triggered manually via GitHub Actions UI with optional force rebuild
+
+### What It Does
+
+1. **Checks out the repository** - Gets the RealmMaster project code
+2. **Sets up Git** - Configures git for module repository cloning
+3. **Sets up Docker Buildx** - Enables optimized Docker builds
+4. **Logs in to Docker Hub** - Authenticates for image publishing
+5. **Prepares the build environment**:
+ - Runs `./setup.sh --non-interactive --module-config RealmMaster --force`
+ - Uses the same setup process as local builds (ensures consistency)
+ - Applies the **RealmMaster module profile** from `config/module-profiles/RealmMaster.json`
+ - Creates `.env` with proper paths and configured modules (32 modules)
+ - Automatically selects correct source variant (standard or playerbots)
+6. **Caches build artifacts** to speed up subsequent builds:
+ - Go build cache (`.gocache`)
+ - Source repository (`local-storage/source`)
+7. **Sets up Python 3.11** - Required for module management scripts
+8. **Runs `./build.sh --yes`** - This is where the magic happens:
+ - **Step 1**: Sets up the AzerothCore source repository
+ - **Step 2**: Detects build requirements
+ - **Step 3**: Syncs module metadata
+ - **Step 4**: **Fetches all module repositories** - Automatically clones all 32 enabled module repos from GitHub
+ - **Step 5**: **Compiles AzerothCore** with all fetched modules integrated
+ - **Step 6**: Tags the compiled images
+9. **Tags images for Docker Hub** - Prepares `latest` and date-based tags
+10. **Pushes images to Docker Hub** - Publishes the built images
+11. **Generates a build summary** - Shows enabled modules and published images
+
+### Module Fetching Process
+
+The workflow **automatically fetches all module repositories** during the build. Here's how it works:
+
+- The `build.sh` script reads the enabled modules from `.env` (set by the RealmMaster profile)
+- For each enabled module, it clones the repository from GitHub (all modules are public repos)
+- Module repositories are cloned into the AzerothCore source tree under `modules/`
+- Examples of fetched repositories:
+ - `mod-playerbots` from https://github.com/mod-playerbots/mod-playerbots.git
+ - `mod-transmog` from https://github.com/azerothcore/mod-transmog.git
+ - `mod-solo-lfg` from https://github.com/azerothcore/mod-solo-lfg.git
+ - ...and 29 more
+
+**No manual module setup required!** The build process handles everything automatically.
+
+### Published Images
+
+The workflow publishes images with **profile-specific tags** so you know exactly which modules are included:
+
+**Profile-Tagged Images** (recommended):
+- `/azerothcore-realmmaster:authserver-realmmaster-latest` ✅ Built nightly
+- `/azerothcore-realmmaster:authserver-realmmaster-YYYYMMDD` ✅ Built nightly
+- `/azerothcore-realmmaster:worldserver-realmmaster-latest` ✅ Built nightly
+- `/azerothcore-realmmaster:worldserver-realmmaster-YYYYMMDD` ✅ Built nightly
+
+**Generic Tags** (backward compatibility, defaults to RealmMaster profile):
+- `/azerothcore-realmmaster:authserver-latest` ✅ Built nightly
+- `/azerothcore-realmmaster:worldserver-latest` ✅ Built nightly
+
+**Other Profile Tags** (built on-demand via manual workflow trigger):
+- `authserver-suggested-modules-latest` - Available when built
+- `authserver-all-modules-latest` - Available when built
+- `authserver-playerbots-only-latest` - Available when built
+
+**Note**: Only the RealmMaster profile is built automatically on schedule. Other profiles can be built by manually triggering the workflow with different profile names.
+
+## Required GitHub Secrets
+
+To enable the build and publish workflow, you must configure the following secrets in your GitHub repository:
+
+### Setting Up Secrets
+
+1. Go to your GitHub repository
+2. Click **Settings** → **Secrets and variables** → **Actions**
+3. Click **New repository secret**
+4. Add the following secrets:
+
+#### DOCKERHUB_USERNAME
+
+Your Docker Hub username.
+
+**Example**: `yourusername`
+
+#### DOCKERHUB_TOKEN
+
+A Docker Hub access token (recommended) or your Docker Hub password.
+
+**How to create a Docker Hub access token**:
+
+1. Log in to [Docker Hub](https://hub.docker.com/)
+2. Click on your username in the top right → **Account Settings**
+3. Go to **Security** → **Personal Access Tokens** → **Generate New Token**
+4. Give it a description (e.g., "GitHub Actions")
+5. Set permissions: **Read & Write**
+6. Click **Generate**
+7. Copy the token (you won't be able to see it again)
+8. Add this token as the `DOCKERHUB_TOKEN` secret in GitHub
+
+## Module Configuration
+
+### Default Profile: RealmMaster
+
+The workflow uses the **RealmMaster** module profile by default, which includes 32 carefully selected modules:
+
+- MODULE_PLAYERBOTS - AI-controlled player characters
+- MODULE_TRANSMOG - Transmogrification system
+- MODULE_SOLO_LFG - Solo dungeon finder
+- MODULE_NPC_BUFFER - Buff NPC
+- MODULE_ELUNA - Lua scripting engine
+- MODULE_AIO - All-in-one interface
+- ...and 26 more modules
+
+See the full list in `config/module-profiles/RealmMaster.json`.
+
+### Customizing the Module Profile
+
+To use a different module profile in the CI/CD workflow:
+
+1. **Choose or create a profile** in `config/module-profiles/`:
+ - `RealmMaster.json` - Default (32 modules)
+ - `suggested-modules.json` - Alternative suggested set
+ - `playerbots-only.json` - Just playerbots
+ - `all-modules.json` - All supported modules
+ - Create your own JSON file
+
+2. **Edit the workflow** at `.github/workflows/build-and-publish.yml`:
+
+ ```yaml
+ # Change this line in the "Prepare build environment" step:
+ python3 scripts/python/apply_module_profile.py RealmMaster \
+
+ # To use a different profile:
+ python3 scripts/python/apply_module_profile.py suggested-modules \
+ ```
+
+3. **Update the build summary** (optional):
+ ```yaml
+ # Change this line in the "Build summary" step:
+ echo "- **Module Profile**: RealmMaster" >> $GITHUB_STEP_SUMMARY
+
+ # To:
+ echo "- **Module Profile**: suggested-modules" >> $GITHUB_STEP_SUMMARY
+ ```
+
+### Testing Module Profiles Locally
+
+You can test the module profile script locally before committing:
+
+```bash
+# List modules that will be enabled
+python3 scripts/python/apply_module_profile.py RealmMaster --list-modules
+
+# Apply a profile to create .env
+python3 scripts/python/apply_module_profile.py RealmMaster
+
+# Verify the result
+grep '^MODULE_.*=1' .env | wc -l
+```
+
+## Cache Strategy
+
+The workflow uses GitHub Actions cache to speed up builds:
+
+- **Go build cache**: Cached in `.gocache` directory
+- **Source repository**: Cached in `local-storage/source` directory
+
+This significantly reduces build times for subsequent runs.
+
+## Manual Workflow Trigger
+
+To manually trigger the workflow:
+
+1. Go to **Actions** tab in your GitHub repository
+2. Click on **Build and Publish** workflow
+3. Click **Run workflow**
+4. **Choose module profile** (default: RealmMaster):
+ - Enter profile name (e.g., `RealmMaster`, `suggested-modules`, `all-modules`, `playerbots-only`)
+ - Profile must exist in `config/module-profiles/`
+5. Optionally check **Force rebuild** to rebuild even if no changes detected
+6. Click **Run workflow**
+
+The workflow will build with the selected profile and tag images accordingly (e.g., `authserver-realmmaster-latest` for RealmMaster profile).
+
+## Troubleshooting
+
+### Build fails with "missing required command"
+
+The workflow runs on Ubuntu and has Docker and Python 3.11 pre-installed. If you see missing command errors, ensure the build script dependencies are available.
+
+### Authentication errors
+
+If you see Docker Hub authentication errors:
+
+- Verify `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` secrets are set correctly
+- Ensure the Docker Hub token has **Read & Write** permissions
+- Check that the token hasn't expired
+
+### Build timeout
+
+The workflow has a 120-minute timeout. If builds consistently exceed this:
+
+- Consider optimizing the build process
+- Check if all module sources are accessible
+- Review cache effectiveness
+
+## Using Pre-Built Images
+
+After images are published to Docker Hub, users can deploy RealmMaster **without building locally**!
+
+### For End Users
+
+See the complete guide at **[docs/PREBUILT_IMAGES.md](PREBUILT_IMAGES.md)** for step-by-step instructions.
+
+**Quick start for users**:
+
+```bash
+# Clone the repository
+git clone https://github.com/uprightbass360/AzerothCore-RealmMaster.git
+cd AzerothCore-RealmMaster
+
+# Use pre-built configuration
+cp .env.prebuilt .env
+
+# Edit .env and set DOCKERHUB_USERNAME=your-dockerhub-username
+
+# Deploy (no build required!)
+./deploy.sh
+```
+
+### For Developers
+
+To test the published images:
+
+```bash
+# Pull latest RealmMaster profile images
+docker pull /azerothcore-realmmaster:authserver-realmmaster-latest
+docker pull /azerothcore-realmmaster:worldserver-realmmaster-latest
+
+# Or pull specific date-tagged images
+docker pull /azerothcore-realmmaster:authserver-realmmaster-20260109
+docker pull /azerothcore-realmmaster:worldserver-realmmaster-20260109
+
+# Or use generic latest tags (defaults to RealmMaster profile)
+docker pull /azerothcore-realmmaster:authserver-latest
+docker pull /azerothcore-realmmaster:worldserver-latest
+```
+
+### Pre-Built Configuration File
+
+The `.env.prebuilt` template provides a minimal configuration that:
+- References Docker Hub images instead of local builds
+- Removes all build-related variables
+- Includes only runtime configuration
+- Is ready to use with minimal editing (just set DOCKERHUB_USERNAME)
+
+**Benefits of pre-built images**:
+- ✅ Skip 15-45 minute build time
+- ✅ No build dependencies required
+- ✅ Same 32 RealmMaster modules included
+- ✅ Automatic nightly updates available
+- ✅ Date-tagged versions for stability
+- ✅ Profile-tagged images for clear identification
+
+## Building Multiple Profiles
+
+You can build different module profiles by manually triggering the workflow:
+
+### Example: Build All Modules Profile
+
+1. Go to **Actions** → **Build and Publish**
+2. Click **Run workflow**
+3. Set **module_profile** to `all-modules`
+4. Click **Run workflow**
+
+This will create:
+- `authserver-all-modules-latest`
+- `authserver-all-modules-YYYYMMDD`
+- `worldserver-all-modules-latest`
+- `worldserver-all-modules-YYYYMMDD`
+
+### Creating Custom Profile Builds
+
+To build a custom profile:
+
+1. **Create profile JSON** in `config/module-profiles/my-custom-profile.json`:
+ ```json
+ {
+ "modules": [
+ "MODULE_PLAYERBOTS",
+ "MODULE_TRANSMOG",
+ "MODULE_SOLO_LFG"
+ ],
+ "label": "My Custom Profile",
+ "description": "Custom module selection",
+ "order": 100
+ }
+ ```
+
+2. **Trigger workflow** with profile name `my-custom-profile`
+
+3. **Images created**:
+ - `authserver-my-custom-profile-latest`
+ - `worldserver-my-custom-profile-latest`
+
+### Scheduled Builds
+
+The nightly scheduled build always uses the **RealmMaster** profile. To schedule builds for different profiles, you can:
+
+1. Create additional workflow files (e.g., `.github/workflows/build-all-modules.yml`)
+2. Set different cron schedules
+3. Hardcode the profile name in the workflow
diff --git a/docs/PREBUILT_IMAGES.md b/docs/PREBUILT_IMAGES.md
new file mode 100644
index 0000000..f520cc1
--- /dev/null
+++ b/docs/PREBUILT_IMAGES.md
@@ -0,0 +1,339 @@
+# Deploying Pre-Built RealmMaster Images
+
+This guide explains how to deploy AzerothCore RealmMaster using pre-built Docker images from Docker Hub. **No local building required!**
+
+## What's Included in Pre-Built Images
+
+The pre-built images are automatically built nightly with the **RealmMaster module profile**, which includes **32 carefully selected modules**:
+
+- **MODULE_PLAYERBOTS** - AI-controlled player characters
+- **MODULE_TRANSMOG** - Transmogrification system
+- **MODULE_SOLO_LFG** - Solo dungeon finder
+- **MODULE_ELUNA** - Lua scripting engine
+- **MODULE_AIO** - All-in-one interface
+- **MODULE_NPC_BUFFER** - Buff NPC
+- **MODULE_NPC_BEASTMASTER** - Pet management
+- **MODULE_SOLOCRAFT** - Solo dungeon scaling
+- **MODULE_1V1_ARENA** - 1v1 arena system
+- **MODULE_ACCOUNT_ACHIEVEMENTS** - Account-wide achievements
+- ...and 22 more modules!
+
+See `config/module-profiles/RealmMaster.json` for the complete list.
+
+## Prerequisites
+
+- Docker with Docker Compose v2
+- 16GB+ RAM
+- 64GB+ storage
+- Linux/macOS/WSL2
+
+## Quick Start
+
+### 1. Clone the Repository
+
+```bash
+git clone https://github.com/uprightbass360/AzerothCore-RealmMaster.git
+cd AzerothCore-RealmMaster
+```
+
+### 2. Create Configuration File
+
+```bash
+# Copy the pre-built images template
+cp .env.prebuilt .env
+```
+
+### 3. Configure Docker Hub Username
+
+Edit `.env` and set your Docker Hub username:
+
+```bash
+# Change this line:
+DOCKERHUB_USERNAME=your-dockerhub-username
+
+# To (example):
+DOCKERHUB_USERNAME=uprightbass360
+```
+
+### 4. Optional: Customize Settings
+
+Edit `.env` to customize:
+
+- **Server address**: `SERVER_ADDRESS=your-server-ip`
+- **Passwords**: `MYSQL_ROOT_PASSWORD=your-password`
+- **Playerbot population**: `PLAYERBOT_MIN_BOTS` and `PLAYERBOT_MAX_BOTS`
+- **Server preset**: `SERVER_CONFIG_PRESET=fast-leveling` (or blizzlike, hardcore-pvp, casual-pve)
+
+### 5. Deploy
+
+```bash
+./deploy.sh
+```
+
+The deployment will:
+- Pull pre-built images from Docker Hub
+- Set up MySQL database with all module SQL
+- Configure client data
+- Start all services
+
+**First deployment takes 30-60 minutes** for database setup and client data download.
+
+## Image Tags
+
+The CI/CD workflow publishes images with **profile-specific tags** so you know exactly which modules are included:
+
+### Profile-Tagged Images (Recommended)
+
+Each module profile gets its own tag:
+
+- **`:authserver-realmmaster-latest`** - RealmMaster profile (32 modules)
+- **`:worldserver-realmmaster-latest`** - RealmMaster profile (32 modules)
+- **`:authserver-realmmaster-YYYYMMDD`** - Date-tagged RealmMaster builds
+- **`:worldserver-realmmaster-YYYYMMDD`** - Date-tagged RealmMaster builds
+
+Other profiles (available when built via GitHub Actions):
+- **`:authserver-suggested-modules-latest`** - Suggested modules profile (not yet published)
+- **`:authserver-all-modules-latest`** - All modules profile (not yet published)
+- **`:authserver-playerbots-only-latest`** - Playerbots only (not yet published)
+
+**Note**: Currently only the RealmMaster profile is built nightly. Other profiles can be built on-demand by manually triggering the CI/CD workflow.
+
+### Generic Tags (Backward Compatibility)
+
+- **`:authserver-latest`** - Latest build (defaults to RealmMaster profile)
+- **`:worldserver-latest`** - Latest build (defaults to RealmMaster profile)
+
+### Choosing a Profile
+
+In `.env.prebuilt`, set the `MODULE_PROFILE` variable:
+
+```bash
+# Choose your profile
+MODULE_PROFILE=realmmaster # 32 modules (default, recommended)
+# MODULE_PROFILE=suggested-modules # Alternative module set
+# MODULE_PROFILE=all-modules # All supported modules
+# MODULE_PROFILE=playerbots-only # Just playerbots
+
+# Images automatically reference the selected profile
+AC_AUTHSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:authserver-${MODULE_PROFILE}-latest
+AC_WORLDSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:worldserver-${MODULE_PROFILE}-latest
+```
+
+### Using Date-Tagged Images
+
+To pin to a specific build date, edit `.env`:
+
+```bash
+# Set your profile
+MODULE_PROFILE=realmmaster
+
+# Pin to a specific date (example: January 9, 2026)
+AC_AUTHSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:authserver-${MODULE_PROFILE}-20260109
+AC_WORLDSERVER_IMAGE_MODULES=${DOCKERHUB_USERNAME}/${COMPOSE_PROJECT_NAME}:worldserver-${MODULE_PROFILE}-20260109
+```
+
+## Differences from Local Build
+
+### What You DON'T Need
+
+When using pre-built images, you **skip**:
+- ❌ Running `./setup.sh` (module selection)
+- ❌ Running `./build.sh` (compilation)
+- ❌ 15-45 minute build time
+- ❌ Build dependencies (Go compiler, etc.)
+
+### What's the Same
+
+Everything else works identically:
+- ✅ Database setup and migrations
+- ✅ Module SQL installation
+- ✅ Configuration management
+- ✅ Backup system
+- ✅ All management commands
+- ✅ phpMyAdmin and Keira3 tools
+
+## Verifying Your Deployment
+
+After deployment completes:
+
+### 1. Check Container Status
+
+```bash
+./status.sh
+```
+
+You should see all services running:
+- ✅ ac-mysql
+- ✅ ac-authserver
+- ✅ ac-worldserver
+- ✅ ac-phpmyadmin
+- ✅ ac-keira3
+
+### 2. Verify Modules Are Loaded
+
+Check the worldserver logs:
+
+```bash
+docker logs ac-worldserver | grep "module"
+```
+
+You should see messages about 32 modules being loaded.
+
+### 3. Access Management Tools
+
+- **phpMyAdmin**: http://localhost:8081
+- **Keira3**: http://localhost:4201
+
+## Post-Installation
+
+### Create Admin Account
+
+1. Attach to the worldserver container:
+
+```bash
+docker attach ac-worldserver
+```
+
+2. Create an account and set GM level:
+
+```
+account create admin password
+account set gmlevel admin 3 -1
+```
+
+3. Detach: Press `Ctrl+P` then `Ctrl+Q`
+
+### Configure Client
+
+Edit your WoW 3.3.5a client's `realmlist.wtf`:
+
+```
+set realmlist 127.0.0.1
+```
+
+(Replace `127.0.0.1` with your server's IP if remote)
+
+## Updating to Latest Images
+
+To update to the latest nightly build:
+
+```bash
+# Pull latest images
+docker compose pull
+
+# Restart services
+docker compose down
+docker compose up -d
+```
+
+**Note**: Database schema updates will be applied automatically on restart.
+
+## Switching Between Pre-Built and Local Build
+
+### From Pre-Built to Local Build
+
+If you want to customize modules and build locally:
+
+```bash
+# Remove pre-built .env
+rm .env
+
+# Run interactive setup
+./setup.sh
+
+# Build with your custom modules
+./build.sh
+
+# Deploy
+./deploy.sh
+```
+
+### From Local Build to Pre-Built
+
+If you want to use pre-built images instead:
+
+```bash
+# Back up your current .env
+mv .env .env.custom
+
+# Use pre-built configuration
+cp .env.prebuilt .env
+
+# Edit DOCKERHUB_USERNAME in .env
+
+# Deploy
+./deploy.sh
+```
+
+## Troubleshooting
+
+### Image Pull Errors
+
+**Problem**: `Error response from daemon: manifest not found`
+
+**Solutions**:
+1. Verify `DOCKERHUB_USERNAME` is set correctly in `.env`
+2. Check that the images exist at: https://hub.docker.com/u/your-username
+3. Ensure the CI/CD workflow has run successfully
+
+### Module SQL Not Applied
+
+**Problem**: Modules don't seem to be working
+
+**Solution**: The module SQL is automatically applied during deployment. Check:
+
+```bash
+# Verify module SQL staging
+ls -la storage/module-sql-updates/
+
+# Check database for module tables
+docker exec -it ac-mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SHOW TABLES" acore_world | grep -i module
+```
+
+### Performance Issues
+
+**Problem**: Server is slow or laggy
+
+**Solutions**:
+1. Increase MySQL tmpfs size in `.env`: `MYSQL_RUNTIME_TMPFS_SIZE=16G`
+2. Reduce playerbot population: `PLAYERBOT_MAX_BOTS=100`
+3. Check system resources: `docker stats`
+
+## Advanced Configuration
+
+### Custom Module Selection
+
+Pre-built images include all RealmMaster modules. To disable specific modules:
+
+1. Edit server configuration files in `storage/config/`
+2. Set module enable flags to 0
+3. Restart worldserver: `docker compose restart ac-worldserver`
+
+**Note**: You can only disable modules, not add new ones (requires local build).
+
+### Server Configuration Presets
+
+Apply configuration presets for different server types:
+
+```bash
+# In .env, set one of these presets:
+SERVER_CONFIG_PRESET=blizzlike # Authentic WotLK experience (1x rates)
+SERVER_CONFIG_PRESET=fast-leveling # 3x XP rates, QoL improvements
+SERVER_CONFIG_PRESET=hardcore-pvp # Competitive PvP (1.5x rates)
+SERVER_CONFIG_PRESET=casual-pve # Relaxed PvE (2x rates)
+```
+
+Restart after changing: `docker compose restart ac-worldserver`
+
+## Getting Help
+
+- **Documentation**: See other guides in `docs/`
+- **GitHub Issues**: https://github.com/uprightbass360/AzerothCore-RealmMaster/issues
+- **AzerothCore Discord**: https://discord.gg/gkt4y2x
+
+## Next Steps
+
+- [Database Management](DATABASE_MANAGEMENT.md) - Backups, restores, migrations
+- [Getting Started Guide](GETTING_STARTED.md) - Detailed walkthrough
+- [Troubleshooting](TROUBLESHOOTING.md) - Common issues and solutions
+- [Module Catalog](MODULES.md) - Complete list of available modules
diff --git a/docs/RELEASES.md b/docs/RELEASES.md
new file mode 100644
index 0000000..5079da6
--- /dev/null
+++ b/docs/RELEASES.md
@@ -0,0 +1,213 @@
+# Release Strategy
+
+This document explains how AzerothCore RealmMaster releases work and what they contain.
+
+## Release Philosophy
+
+Since **Docker images are stored on Docker Hub**, GitHub releases serve as **deployment packages** rather than source distributions. Each release contains everything users need to deploy pre-built images without building from source.
+
+## What's in a Release?
+
+### Release Assets (ZIP Archive)
+
+Each release includes a downloadable `.zip` file containing:
+
+```
+azerothcore-realmmaster-v1.0.0-realmmaster.zip
+├── .env.prebuilt # Pre-configured for Docker Hub images
+├── docker-compose.yml # Service definitions
+├── deploy.sh # Deployment script
+├── status.sh # Status monitoring
+├── cleanup.sh # Cleanup utilities
+├── scripts/ # Required Python/Bash scripts
+├── config/ # Module manifest and presets
+├── docs/ # Complete documentation
+├── QUICKSTART.md # Release-specific quick start
+└── README.md # Project overview
+```
+
+### Release Notes
+
+Each release includes:
+- Module profile and count
+- Docker Hub image tags (date-specific and latest)
+- Quick start instructions
+- Complete module list
+- Build information (commit, date, source variant)
+- Links to documentation
+- Known issues
+
+## Release Types
+
+### 1. Profile-Based Releases
+
+Each module profile gets its own release variant:
+
+- **v1.0.0-realmmaster** - RealmMaster profile (32 modules, recommended)
+- **v1.0.0-suggested-modules** - Alternative suggested module set
+- **v1.0.0-all-modules** - All supported modules
+- **v1.0.0-playerbots-only** - Just playerbots
+
+Users choose the release that matches their desired module set.
+
+### 2. Version Numbering
+
+We use semantic versioning:
+- **Major** (v1.0.0 → v2.0.0): Breaking changes, major feature additions
+- **Minor** (v1.0.0 → v1.1.0): New modules, feature enhancements
+- **Patch** (v1.0.0 → v1.0.1): Bug fixes, documentation updates
+
+## Docker Hub Image Tags
+
+Releases reference specific Docker Hub tags:
+
+### Date-Tagged Images (Recommended for Production)
+```
+uprightbass360/azerothcore-realmmaster:authserver-realmmaster-20260109
+uprightbass360/azerothcore-realmmaster:worldserver-realmmaster-20260109
+```
+- **Immutable**: Never change
+- **Stable**: Guaranteed to match the release
+- **Recommended**: For production deployments
+
+### Latest Tags (Auto-Updated)
+```
+uprightbass360/azerothcore-realmmaster:authserver-realmmaster-latest
+uprightbass360/azerothcore-realmmaster:worldserver-realmmaster-latest
+```
+- **Mutable**: Updated nightly by CI/CD
+- **Convenient**: Always get the newest build
+- **Use case**: Development, testing, staying current
+
+## Creating a Release
+
+### Automated (Recommended)
+
+Use the GitHub Actions workflow:
+
+1. Go to **Actions** → **Create Release**
+2. Click **Run workflow**
+3. Fill in:
+ - **Version**: `v1.0.0`
+ - **Profile**: `RealmMaster` (or other profile)
+ - **Pre-release**: Check if beta/RC
+4. Click **Run workflow**
+
+The workflow automatically:
+- Creates deployment package with all files
+- Generates release notes with module list
+- Uploads ZIP archive as release asset
+- Creates GitHub release with proper tags
+
+### Manual
+
+If you need to create a release manually:
+
+```bash
+# 1. Tag the release
+git tag -a v1.0.0 -m "Release v1.0.0 - RealmMaster Profile"
+git push origin v1.0.0
+
+# 2. Create deployment package
+./scripts/create-release-package.sh v1.0.0 RealmMaster
+
+# 3. Create GitHub release
+# Go to GitHub → Releases → Draft a new release
+# - Tag: v1.0.0
+# - Title: RealmMaster v1.0.0 - RealmMaster Profile
+# - Upload: azerothcore-realmmaster-v1.0.0-realmmaster.zip
+# - Add release notes
+```
+
+## Release Checklist
+
+Before creating a release:
+
+- [ ] Verify CI/CD build succeeded
+- [ ] Test Docker Hub images work correctly
+- [ ] Update CHANGELOG.md
+- [ ] Update version in documentation if needed
+- [ ] Verify all module SQL migrations are included
+- [ ] Test deployment on clean system
+- [ ] Update known issues section
+
+## For Users: Using a Release
+
+### Quick Start
+
+```bash
+# 1. Download release
+wget https://github.com/uprightbass360/AzerothCore-RealmMaster/releases/download/v1.0.0/azerothcore-realmmaster-v1.0.0-realmmaster.zip
+
+# 2. Extract
+unzip azerothcore-realmmaster-v1.0.0-realmmaster.zip
+cd azerothcore-realmmaster-v1.0.0-realmmaster
+
+# 3. Configure
+nano .env.prebuilt
+# Set: DOCKERHUB_USERNAME=uprightbass360
+
+# 4. Deploy
+mv .env.prebuilt .env
+./deploy.sh
+```
+
+### Upgrading Between Releases
+
+```bash
+# 1. Backup your data
+./scripts/bash/backup.sh
+
+# 2. Download new release
+wget https://github.com/.../releases/download/v1.1.0/...
+
+# 3. Extract to new directory
+unzip azerothcore-realmmaster-v1.1.0-realmmaster.zip
+
+# 4. Copy your .env and data
+cp old-version/.env new-version/.env
+cp -r old-version/storage new-version/storage
+
+# 5. Deploy new version
+cd new-version
+./deploy.sh
+```
+
+## Release Schedule
+
+- **Nightly Builds**: Images built automatically at 2 AM UTC
+- **Releases**: Created as needed when significant changes accumulate
+- **LTS Releases**: Planned quarterly for long-term support
+
+## Support
+
+- **Release Issues**: https://github.com/uprightbass360/AzerothCore-RealmMaster/issues
+- **Documentation**: Included in each release ZIP
+- **Discord**: https://discord.gg/gkt4y2x
+
+## FAQ
+
+### Why are images on Docker Hub and not in releases?
+
+Docker images can be 1-2GB each. GitHub has a 2GB file limit and releases should be lightweight. Docker Hub is designed for hosting images, GitHub releases are for deployment packages.
+
+### Can I use latest tags in production?
+
+We recommend **date-tagged images** for production (e.g., `authserver-realmmaster-20260109`). Latest tags are updated nightly and may have untested changes.
+
+### How do I know which image version a release uses?
+
+Check the release notes - they include the specific Docker Hub tags (date-stamped) that were tested with that release.
+
+### What if I want to build from source instead?
+
+Clone the repository and use `./setup.sh` + `./build.sh` instead of using pre-built releases. See [GETTING_STARTED.md](GETTING_STARTED.md) for instructions.
+
+### Are releases required?
+
+No! You can:
+1. **Use releases**: Download ZIP, deploy pre-built images (easiest)
+2. **Use nightly images**: Pull latest tags directly from Docker Hub
+3. **Build from source**: Clone repo, build locally (most flexible)
+
+Releases are just convenient snapshots for users who want stability.
diff --git a/scripts/python/apply_module_profile.py b/scripts/python/apply_module_profile.py
new file mode 100755
index 0000000..35c73a4
--- /dev/null
+++ b/scripts/python/apply_module_profile.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python3
+"""
+Apply a module profile to .env file for CI/CD builds.
+
+This script reads a module profile JSON and enables the specified modules
+in the .env file, ready for automated builds.
+"""
+
+import argparse
+import json
+import sys
+from pathlib import Path
+from typing import List, Set
+
+
+def load_profile(profile_path: Path) -> List[str]:
+ """Load module list from a profile JSON file."""
+ try:
+ with open(profile_path, 'r') as f:
+ data = json.load(f)
+ except FileNotFoundError:
+ print(f"ERROR: Profile not found: {profile_path}", file=sys.stderr)
+ sys.exit(1)
+ except json.JSONDecodeError as e:
+ print(f"ERROR: Invalid JSON in profile: {e}", file=sys.stderr)
+ sys.exit(1)
+
+ modules = data.get('modules', [])
+ if not isinstance(modules, list):
+ print("ERROR: 'modules' must be a list in profile JSON", file=sys.stderr)
+ sys.exit(1)
+
+ return [m.strip() for m in modules if m.strip()]
+
+
+def read_env_template(template_path: Path) -> List[str]:
+ """Read the .env.template file."""
+ try:
+ with open(template_path, 'r') as f:
+ return f.readlines()
+ except FileNotFoundError:
+ print(f"ERROR: Template not found: {template_path}", file=sys.stderr)
+ sys.exit(1)
+
+
+def apply_profile_to_env(template_lines: List[str], enabled_modules: Set[str]) -> List[str]:
+ """
+ Process template lines and enable specified modules.
+
+ Sets MODULE_* variables to 1 if they're in enabled_modules, otherwise keeps template value.
+ """
+ output_lines = []
+
+ for line in template_lines:
+ stripped = line.strip()
+
+ # Check if this is a MODULE_ variable line
+ if stripped.startswith('MODULE_') and '=' in stripped:
+ # Extract the module name (before the =)
+ module_name = stripped.split('=')[0].strip()
+
+ if module_name in enabled_modules:
+ # Enable this module
+ output_lines.append(f"{module_name}=1\n")
+ else:
+ # Keep original line (usually =0 or commented)
+ output_lines.append(line)
+ else:
+ # Not a module line, keep as-is
+ output_lines.append(line)
+
+ return output_lines
+
+
+def write_env_file(env_path: Path, lines: List[str]):
+ """Write the processed lines to .env file."""
+ try:
+ with open(env_path, 'w') as f:
+ f.writelines(lines)
+ print(f"✅ Applied profile to {env_path}")
+ except IOError as e:
+ print(f"ERROR: Failed to write .env file: {e}", file=sys.stderr)
+ sys.exit(1)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Apply a module profile to .env file for automated builds'
+ )
+ parser.add_argument(
+ 'profile',
+ help='Name of the profile (e.g., RealmMaster) or path to profile JSON'
+ )
+ parser.add_argument(
+ '--env-template',
+ default='.env.template',
+ help='Path to .env.template file (default: .env.template)'
+ )
+ parser.add_argument(
+ '--env-output',
+ default='.env',
+ help='Path to output .env file (default: .env)'
+ )
+ parser.add_argument(
+ '--profiles-dir',
+ default='config/module-profiles',
+ help='Directory containing profile JSON files (default: config/module-profiles)'
+ )
+ parser.add_argument(
+ '--list-modules',
+ action='store_true',
+ help='List modules that will be enabled and exit'
+ )
+
+ args = parser.parse_args()
+
+ # Resolve profile path
+ profile_path = Path(args.profile)
+ if not profile_path.exists():
+ # Try treating it as a profile name
+ profile_path = Path(args.profiles_dir) / f"{args.profile}.json"
+
+ if not profile_path.exists():
+ print(f"ERROR: Profile not found: {args.profile}", file=sys.stderr)
+ print(f" Tried: {Path(args.profile)}", file=sys.stderr)
+ print(f" Tried: {profile_path}", file=sys.stderr)
+ sys.exit(1)
+
+ # Load the profile
+ print(f"📋 Loading profile: {profile_path.name}")
+ enabled_modules = set(load_profile(profile_path))
+
+ if args.list_modules:
+ print(f"\nModules to be enabled ({len(enabled_modules)}):")
+ for module in sorted(enabled_modules):
+ print(f" • {module}")
+ return
+
+ print(f"✓ Found {len(enabled_modules)} modules in profile")
+
+ # Read template
+ template_path = Path(args.env_template)
+ template_lines = read_env_template(template_path)
+
+ # Apply profile
+ output_lines = apply_profile_to_env(template_lines, enabled_modules)
+
+ # Write output
+ env_path = Path(args.env_output)
+ write_env_file(env_path, output_lines)
+
+ print(f"✓ Profile '{profile_path.stem}' applied successfully")
+ print(f"\nEnabled modules:")
+ for module in sorted(enabled_modules)[:10]: # Show first 10
+ print(f" • {module}")
+ if len(enabled_modules) > 10:
+ print(f" ... and {len(enabled_modules) - 10} more")
+
+
+if __name__ == '__main__':
+ main()