mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 00:58:34 +00:00
finalizing source rebuild process, docs in progress
This commit is contained in:
128
.env
128
.env
@@ -1,128 +0,0 @@
|
||||
# Generated by ac-compose/setup.sh
|
||||
|
||||
COMPOSE_PROJECT_NAME=ac-compose
|
||||
|
||||
STORAGE_PATH=./storage
|
||||
TZ=UTC
|
||||
|
||||
# Database
|
||||
MYSQL_IMAGE=mysql:8.0
|
||||
CONTAINER_MYSQL=ac-mysql
|
||||
MYSQL_ROOT_PASSWORD=azerothcore123
|
||||
MYSQL_ROOT_HOST=%
|
||||
MYSQL_USER=root
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_EXTERNAL_PORT=64306
|
||||
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
|
||||
DB_AUTH_NAME=acore_auth
|
||||
DB_WORLD_NAME=acore_world
|
||||
DB_CHARACTERS_NAME=acore_characters
|
||||
AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:14.0.0-dev
|
||||
|
||||
# Services (images)
|
||||
AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:14.0.0-dev
|
||||
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev
|
||||
AC_AUTHSERVER_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot
|
||||
AC_WORLDSERVER_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot
|
||||
|
||||
# Client data images
|
||||
AC_CLIENT_DATA_IMAGE=acore/ac-wotlk-client-data:14.0.0-dev
|
||||
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot
|
||||
|
||||
# Ports
|
||||
AUTH_EXTERNAL_PORT=3784
|
||||
AUTH_PORT=3724
|
||||
WORLD_EXTERNAL_PORT=8215
|
||||
WORLD_PORT=8085
|
||||
SOAP_EXTERNAL_PORT=7778
|
||||
SOAP_PORT=7878
|
||||
|
||||
# Realm
|
||||
SERVER_ADDRESS=127.0.0.1
|
||||
REALM_PORT=8215
|
||||
|
||||
# Backups
|
||||
BACKUP_RETENTION_DAYS=3
|
||||
BACKUP_RETENTION_HOURS=6
|
||||
BACKUP_DAILY_TIME=09
|
||||
|
||||
# Container user
|
||||
CONTAINER_USER=0:0
|
||||
|
||||
# Modules
|
||||
MODULE_PLAYERBOTS=1
|
||||
MODULE_AOE_LOOT=0
|
||||
MODULE_LEARN_SPELLS=1
|
||||
MODULE_FIREWORKS=1
|
||||
MODULE_INDIVIDUAL_PROGRESSION=0
|
||||
MODULE_AHBOT=1
|
||||
MODULE_AUTOBALANCE=1
|
||||
MODULE_TRANSMOG=1
|
||||
MODULE_NPC_BUFFER=1
|
||||
MODULE_DYNAMIC_XP=0
|
||||
MODULE_SOLO_LFG=1
|
||||
MODULE_1V1_ARENA=0
|
||||
MODULE_PHASED_DUELS=0
|
||||
MODULE_BREAKING_NEWS=0
|
||||
MODULE_BOSS_ANNOUNCER=0
|
||||
MODULE_ACCOUNT_ACHIEVEMENTS=0
|
||||
MODULE_AUTO_REVIVE=0
|
||||
MODULE_GAIN_HONOR_GUARD=0
|
||||
MODULE_ELUNA=1
|
||||
MODULE_ARAC=0
|
||||
MODULE_TIME_IS_TIME=0
|
||||
MODULE_POCKET_PORTAL=0
|
||||
MODULE_RANDOM_ENCHANTS=0
|
||||
MODULE_SOLOCRAFT=1
|
||||
MODULE_PVP_TITLES=0
|
||||
MODULE_NPC_BEASTMASTER=0
|
||||
MODULE_NPC_ENCHANTER=0
|
||||
MODULE_INSTANCE_RESET=0
|
||||
MODULE_LEVEL_GRANT=0
|
||||
MODULE_ASSISTANT=0
|
||||
MODULE_REAGENT_BANK=0
|
||||
MODULE_BLACK_MARKET_AUCTION_HOUSE=0
|
||||
|
||||
# Client data
|
||||
CLIENT_DATA_VERSION=v16
|
||||
|
||||
# Playerbot runtime
|
||||
PLAYERBOT_ENABLED=0
|
||||
PLAYERBOT_MAX_BOTS=40
|
||||
|
||||
# Rebuild automation
|
||||
AUTO_REBUILD_ON_DEPLOY=0
|
||||
MODULES_REBUILD_SOURCE_PATH=
|
||||
|
||||
# Eluna
|
||||
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
|
||||
|
||||
# Tools
|
||||
PMA_HOST=ac-mysql
|
||||
PMA_PORT=3306
|
||||
PMA_USER=root
|
||||
PMA_EXTERNAL_PORT=8081
|
||||
PMA_ARBITRARY=1
|
||||
PMA_ABSOLUTE_URI=
|
||||
PMA_UPLOAD_LIMIT=300M
|
||||
PMA_MEMORY_LIMIT=512M
|
||||
PMA_MAX_EXECUTION_TIME=600
|
||||
KEIRA3_EXTERNAL_PORT=4201
|
||||
KEIRA_DATABASE_HOST=ac-mysql
|
||||
KEIRA_DATABASE_PORT=3306
|
||||
|
||||
# Networking
|
||||
NETWORK_NAME=azerothcore
|
||||
NETWORK_SUBNET=172.20.0.0/16
|
||||
NETWORK_GATEWAY=172.20.0.1
|
||||
@@ -91,6 +91,7 @@ MODULE_PLAYERBOTS=0
|
||||
MODULE_AOE_LOOT=0
|
||||
MODULE_LEARN_SPELLS=0
|
||||
MODULE_FIREWORKS=0
|
||||
# Requires worldserver.conf tweaks (EnablePlayerSettings=1, DBC.EnforceItemAttributes=0)
|
||||
MODULE_INDIVIDUAL_PROGRESSION=0
|
||||
MODULE_AHBOT=0
|
||||
MODULE_AUTOBALANCE=0
|
||||
@@ -100,21 +101,26 @@ MODULE_DYNAMIC_XP=0
|
||||
MODULE_SOLO_LFG=0
|
||||
MODULE_1V1_ARENA=0
|
||||
MODULE_PHASED_DUELS=0
|
||||
# Needs BreakingNews HTML asset configured (BreakingNews.HtmlPath)
|
||||
MODULE_BREAKING_NEWS=0
|
||||
MODULE_BOSS_ANNOUNCER=0
|
||||
MODULE_ACCOUNT_ACHIEVEMENTS=0
|
||||
MODULE_AUTO_REVIVE=0
|
||||
MODULE_GAIN_HONOR_GUARD=0
|
||||
MODULE_ELUNA=1
|
||||
MODULE_ARAC=0
|
||||
# Requires optional SQL/DBC patches; leave off by default
|
||||
MODULE_TIME_IS_TIME=0
|
||||
# Requires in-game NPC placement/config; leave off by default
|
||||
MODULE_POCKET_PORTAL=0
|
||||
# Pending upstream verification; leave disabled until tested
|
||||
MODULE_RANDOM_ENCHANTS=0
|
||||
MODULE_SOLOCRAFT=0
|
||||
MODULE_PVP_TITLES=0
|
||||
# Custom NPC modules pending compatibility validation
|
||||
MODULE_NPC_BEASTMASTER=0
|
||||
MODULE_NPC_ENCHANTER=0
|
||||
MODULE_INSTANCE_RESET=0
|
||||
# mod-quest-count-level currently fails (uses removed sConfigMgr::GetBoolDefault)
|
||||
MODULE_LEVEL_GRANT=0
|
||||
MODULE_ASSISTANT=0
|
||||
MODULE_REAGENT_BANK=0
|
||||
@@ -124,12 +130,12 @@ MODULE_BLACK_MARKET_AUCTION_HOUSE=0
|
||||
# Rebuild automation
|
||||
# =====================
|
||||
AUTO_REBUILD_ON_DEPLOY=0
|
||||
MODULES_REBUILD_SOURCE_PATH=
|
||||
MODULES_REBUILD_SOURCE_PATH=./source/azerothcore
|
||||
|
||||
# =====================
|
||||
# Eluna runtime (worldserver.conf overrides)
|
||||
# =====================
|
||||
AC_ELUNA_ENABLED=1
|
||||
AC_ELUNA_ENABLED=1 # Power users may set to 0 to turn off bundled Eluna runtime
|
||||
AC_ELUNA_TRACE_BACK=1
|
||||
AC_ELUNA_AUTO_RELOAD=1
|
||||
AC_ELUNA_BYTECODE_CACHE=1
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,5 +2,7 @@ data/
|
||||
backups/
|
||||
local-data-tools/
|
||||
storage/
|
||||
source/
|
||||
.claude/
|
||||
*custom.env
|
||||
.env
|
||||
|
||||
|
||||
148
README.md
Normal file
148
README.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# ac-compose Deployment Guide
|
||||
|
||||
This guide walks through the end-to-end deployment workflow for the `ac-compose` stack. It focuses on the supported automation scripts, the order in which to run them, the default services/ports that come online, and the optional manual steps you may need when enabling additional modules.
|
||||
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
Before you begin:
|
||||
|
||||
- **Docker** and **Docker Compose v2** installed on the host.
|
||||
- A POSIX-compatible shell (the provided scripts target Bash).
|
||||
- Sufficient disk space for game assets, module clones, and source builds ( ≈ 20 GB recommended).
|
||||
- Network access to GitHub (or a local mirror) for cloning AzerothCore source and modules.
|
||||
|
||||
> Tip: If you use a distinct user/group mapping (e.g., NFS-backed storage) the setup wizard will let you pick non-root UIDs/GIDs.
|
||||
|
||||
|
||||
## 2. Generate `.env` via `setup.sh`
|
||||
|
||||
All environment configuration lives in `ac-compose/.env`. Generate or refresh it by running:
|
||||
|
||||
```bash
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
The wizard will ask you to confirm:
|
||||
|
||||
1. **Deployment type** (local, LAN, or public) – sets bind address and default ports.
|
||||
2. **Filesystem ownership** for container volumes.
|
||||
3. **Exterior ports** for Auth (default 3784), World (8215), SOAP (7778), and MySQL (64306).
|
||||
4. **Storage path** (default `./storage`) and backup retention.
|
||||
5. **Module preset**. The wizard defaults to a safe set (Solo LFG, Solocraft, Autobalance, Transmog, NPC Buffer, Learn Spells, Fireworks). Manual mode lets you toggle more modules, while warning you about unsafe or incompatible ones.
|
||||
|
||||
### Module notes from the wizard
|
||||
|
||||
- **AHBot** – remains disabled until the upstream module exports `Addmod_ahbotScripts()` (linker failure otherwise).
|
||||
- **Quest Count Level** – disabled: relies on deprecated ConfigMgr calls and fails to compile.
|
||||
- **Eluna** – bundled with AzerothCore by default. To disable the runtime later, edit the `AC_ELUNA_ENABLED` flag under “Eluna runtime” in `.env`.
|
||||
- Other disabled modules (Individual Progression, Breaking News, TimeIsTime, Pocket Portal, Random Enchants, NPC Beastmaster/Enchanter, Instance Reset, etc.) require additional SQL, DBC, or in-game configuration. Inline comments in `.env` describe these requirements.
|
||||
|
||||
When the wizard completes, it writes the fully populated `.env`. Re-run `./setup.sh` anytime you want to regenerate the file; make backups first if you have custom edits.
|
||||
|
||||
|
||||
## 3. (Optional) Clone AzerothCore Source
|
||||
|
||||
Certain modules require recompiling the AzerothCore core. If you plan to enable any of them, clone/update the source repository first:
|
||||
|
||||
```bash
|
||||
./scripts/setup-source.sh
|
||||
```
|
||||
|
||||
This script:
|
||||
|
||||
- Reads `MODULES_REBUILD_SOURCE_PATH` (default `./source/azerothcore`).
|
||||
- Clones or updates the repository (uses the Playerbot fork if `MODULE_PLAYERBOTS=1`).
|
||||
- Ensures the desired branch is checked out.
|
||||
|
||||
You can rerun it whenever you need to pull upstream updates.
|
||||
|
||||
|
||||
## 4. Deploy with `deploy.sh`
|
||||
|
||||
Use `deploy.sh` to perform a full module-aware deployment. Example:
|
||||
|
||||
```bash
|
||||
./deploy.sh --profile modules
|
||||
```
|
||||
|
||||
What the script does:
|
||||
|
||||
1. Stops any running stack (unless `--keep-running` is supplied) to avoid container-name conflicts.
|
||||
2. Runs the modules manager (`docker compose --profile db --profile modules up ac-modules`) to clone missing modules, apply configuration, and execute module SQL.
|
||||
3. Rebuilds AzerothCore from source if any C++ modules are enabled. The helper also tags the freshly-built images as `acore/ac-wotlk-{worldserver,authserver}:modules-latest` for subsequent compose runs.
|
||||
4. Stages the runtime profile by invoking `./scripts/stage-modules.sh --yes`.
|
||||
5. Tails the `ac-worldserver` logs by default (omit with `--no-watch`).
|
||||
|
||||
Useful flags:
|
||||
|
||||
- `--profile {standard|playerbots|modules}` – force a specific services profile instead of auto-detecting by module toggles.
|
||||
- `--skip-rebuild` – skip the source rebuild even if modules demand it (not recommended unless you are certain rebuilt images already exist).
|
||||
- `--keep-running` – do not stop existing containers before syncing modules (use sparingly; stale `ac-db-import` containers can block the rebuild stage).
|
||||
- `--no-watch` – exit after staging without tailing worldserver logs.
|
||||
|
||||
All Docker Compose commands run with the project name derived from `COMPOSE_PROJECT_NAME` in `.env` (default `ac-compose`).
|
||||
|
||||
|
||||
### If you prefer a health check after deployment
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
./verify-deployment.sh --skip-deploy --quick
|
||||
```
|
||||
|
||||
This script inspects container health states and key ports without altering the running stack.
|
||||
|
||||
|
||||
## 5. Service Inventory & Default Ports
|
||||
|
||||
| Service / Container | Role | Ports (host → container) | Profile(s) |
|
||||
|----------------------------|-------------------------------------|--------------------------|----------------------------|
|
||||
| `ac-mysql` | MySQL 8.0 database | `64306 → 3306` | `db` |
|
||||
| `ac-db-import` | One-shot DB import/update | – | `db` |
|
||||
| `ac-db-init` | Schema bootstrap helper | – | `db` |
|
||||
| `ac-authserver` | Auth server (no modules) | `3784 → 3724` | `services-standard` |
|
||||
| `ac-worldserver` | World server (no modules) | `8215 → 8085`, `7778 → 7878` (SOAP) | `services-standard` |
|
||||
| `ac-authserver-modules` | Auth server w/ custom build | `3784 → 3724` | `services-modules` |
|
||||
| `ac-worldserver-modules` | World server w/ custom build | `8215 → 8085`, `7778 → 7878` | `services-modules` |
|
||||
| `ac-authserver-playerbots` | Playerbots auth image | `3784 → 3724` | `services-playerbots` |
|
||||
| `ac-worldserver-playerbots`| Playerbots world image | `8215 → 8085`, `7778 → 7878` | `services-playerbots` |
|
||||
| `ac-client-data-standard` | Client-data fetcher | – | `client-data` |
|
||||
| `ac-modules` | Module management / SQL executor | – | `modules` |
|
||||
| `ac-phpmyadmin` | phpMyAdmin UI | `8081 → 80` | `tools` |
|
||||
| `ac-keira3` | Keira3 world editor | `4201 → 8080` | `tools` |
|
||||
|
||||
Additional services (e.g., backups, monitoring) can be enabled by editing `.env` and the compose file as needed.
|
||||
|
||||
|
||||
## 6. Manual Tasks & Advanced Options
|
||||
|
||||
- **Disabling Eluna**: Eluna’s runtime flags live near the end of `.env`. Set `AC_ELUNA_ENABLED=0` if you do not want Lua scripting loaded.
|
||||
- **Enabling experimental modules**: Edit `.env` toggles. Review the inline comments carefully—some modules require additional SQL, DBC patches, or configuration files before they work safely.
|
||||
- **Custom `.env` variants**: You can create `.env.custom` files and run `docker compose --env-file` if you maintain multiple environments. The setup wizard always writes `./.env`.
|
||||
- **Manual source rebuild**: If you prefer to rebuild without staging services, run `./scripts/rebuild-with-modules.sh --yes`. The script now stops and cleans up its own compose project to avoid lingering containers.
|
||||
- **Health check**: `verify-deployment.sh` can also be run without `--skip-deploy` to bring up a stack and verify container states using the default profiles.
|
||||
|
||||
|
||||
## 7. Clean-Up & Re-running
|
||||
|
||||
- To tear down everything: `docker compose --profile db --profile services-standard --profile services-playerbots --profile services-modules --profile client-data --profile modules --profile tools down`.
|
||||
- To force the module manager to re-run (e.g., after toggling modules in `.env`): `docker compose --profile db --profile modules up --build ac-modules`.
|
||||
- Storage (logs, configs, client data) lives under `./storage` by default; remove directories carefully if you need a clean slate.
|
||||
|
||||
|
||||
## 8. Further Reading
|
||||
|
||||
For a full description of individual modules, sample workflows, or deeper dive into AzerothCore internals, consult the original **V1 README** and linked documentation inside the `V1/` directory. Those docs provide module-specific CMake and SQL references you can adapt if you decide to maintain custom forks.
|
||||
|
||||
---
|
||||
|
||||
You now have a repeatable, script-driven deployment process:
|
||||
|
||||
1. Configure once with `setup.sh`.
|
||||
2. (Optional) Pull upstream source via `scripts/setup-source.sh`.
|
||||
3. Deploy and stage via `deploy.sh`.
|
||||
4. Verify with `verify-deployment.sh` or directly inspect `docker compose ps`.
|
||||
|
||||
Happy adventuring!
|
||||
44
cleanup.sh
44
cleanup.sh
@@ -30,8 +30,6 @@ print_status() {
|
||||
|
||||
usage(){
|
||||
cat <<EOF
|
||||
ac-compose Cleanup
|
||||
|
||||
Usage: $0 [CLEANUP_LEVEL] [OPTIONS]
|
||||
|
||||
CLEANUP LEVELS:
|
||||
@@ -105,18 +103,38 @@ fi
|
||||
STORAGE_PATH="${STORAGE_PATH:-$STORAGE_PATH_DEFAULT}"
|
||||
|
||||
soft_cleanup() {
|
||||
print_status HEADER "SOFT CLEANUP - Stop containers"
|
||||
print_status HEADER "SOFT CLEANUP - Stop runtime stack"
|
||||
confirm "This will stop all project containers (data preserved)."
|
||||
execute_command "Stopping containers" docker compose -f "$COMPOSE_FILE" down
|
||||
local profiles=(
|
||||
--profile services-standard
|
||||
--profile services-playerbots
|
||||
--profile services-modules
|
||||
--profile client-data
|
||||
--profile client-data-bots
|
||||
--profile modules
|
||||
--profile tools
|
||||
--profile db
|
||||
)
|
||||
execute_command "Stopping runtime profiles" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down
|
||||
print_status SUCCESS "Soft cleanup complete"
|
||||
}
|
||||
|
||||
hard_cleanup() {
|
||||
print_status HEADER "HARD CLEANUP - Remove containers + networks"
|
||||
confirm "This will remove containers and networks (volumes/images preserved)."
|
||||
execute_command "Removing containers and networks" docker compose -f "$COMPOSE_FILE" down --remove-orphans
|
||||
# Remove straggler containers matching ac-* (defensive)
|
||||
execute_command "Remove stray ac-* containers" "docker ps -a --format '{{.Names}}' | grep -E '^ac-' | xargs -r docker rm -f"
|
||||
local profiles=(
|
||||
--profile services-standard
|
||||
--profile services-playerbots
|
||||
--profile services-modules
|
||||
--profile client-data
|
||||
--profile client-data-bots
|
||||
--profile modules
|
||||
--profile tools
|
||||
--profile db
|
||||
)
|
||||
execute_command "Removing containers and networks" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down --remove-orphans
|
||||
# Remove straggler containers matching project name (defensive)
|
||||
execute_command "Remove stray project containers" "docker ps -a --format '{{.Names}}' | grep -E '^ac-' | xargs -r docker rm -f"
|
||||
# Remove project network if present and not automatically removed
|
||||
if [ -n "${NETWORK_NAME:-}" ]; then
|
||||
execute_command "Remove project network ${NETWORK_NAME}" "docker network rm ${NETWORK_NAME} 2>/dev/null || true"
|
||||
@@ -130,7 +148,17 @@ nuclear_cleanup() {
|
||||
confirm "Proceed with complete removal?"
|
||||
|
||||
# Down with volumes
|
||||
execute_command "Removing containers, networks and volumes" docker compose -f "$COMPOSE_FILE" down --volumes --remove-orphans
|
||||
local profiles=(
|
||||
--profile services-standard
|
||||
--profile services-playerbots
|
||||
--profile services-modules
|
||||
--profile client-data
|
||||
--profile client-data-bots
|
||||
--profile modules
|
||||
--profile tools
|
||||
--profile db
|
||||
)
|
||||
execute_command "Removing containers, networks and volumes" docker compose -f "$COMPOSE_FILE" "${profiles[@]}" down --volumes --remove-orphans
|
||||
|
||||
# Remove project images (server/tool images typical to this project)
|
||||
execute_command "Remove acore images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^acore/' | xargs -r docker rmi"
|
||||
|
||||
85
compose.yml
85
compose.yml
@@ -366,6 +366,41 @@ services:
|
||||
retries: ${AUTH_HEALTHCHECK_RETRIES:-3}
|
||||
start_period: ${AUTH_HEALTHCHECK_START_PERIOD:-60s}
|
||||
|
||||
ac-authserver-modules:
|
||||
profiles: ["services-modules"]
|
||||
image: ${AC_AUTHSERVER_IMAGE_MODULES:-acore/ac-wotlk-authserver:modules-latest}
|
||||
container_name: ac-authserver
|
||||
user: "${CONTAINER_USER:-0:0}"
|
||||
depends_on:
|
||||
ac-mysql:
|
||||
condition: service_healthy
|
||||
ac-db-import:
|
||||
condition: service_completed_successfully
|
||||
ac-db-init:
|
||||
condition: service_completed_successfully
|
||||
environment:
|
||||
AC_LOGIN_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_AUTH_NAME:-acore_auth}"
|
||||
AC_UPDATES_ENABLE_DATABASES: "0"
|
||||
AC_BIND_IP: "0.0.0.0"
|
||||
AC_LOG_LEVEL: "1"
|
||||
AC_LOGGER_ROOT_CONFIG: "1,Console"
|
||||
AC_LOGGER_SERVER_CONFIG: "1,Console"
|
||||
AC_APPENDER_CONSOLE_CONFIG: "1,2,0"
|
||||
ports:
|
||||
- "${AUTH_EXTERNAL_PORT:-3784}:${AUTH_PORT:-3724}"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- azerothcore
|
||||
volumes:
|
||||
- ${STORAGE_PATH:-./storage}/config:/azerothcore/env/dist/etc
|
||||
cap_add: ["SYS_NICE"]
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "ps aux | grep '[a]uthserver' | grep -v grep || exit 1"]
|
||||
interval: ${AUTH_HEALTHCHECK_INTERVAL:-30s}
|
||||
timeout: ${AUTH_HEALTHCHECK_TIMEOUT:-10s}
|
||||
retries: ${AUTH_HEALTHCHECK_RETRIES:-3}
|
||||
start_period: ${AUTH_HEALTHCHECK_START_PERIOD:-60s}
|
||||
|
||||
ac-worldserver-playerbots:
|
||||
profiles: ["services-playerbots"]
|
||||
image: ${AC_WORLDSERVER_IMAGE_PLAYERBOTS:-uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot}
|
||||
@@ -416,6 +451,56 @@ services:
|
||||
retries: ${WORLD_HEALTHCHECK_RETRIES:-3}
|
||||
start_period: ${WORLD_HEALTHCHECK_START_PERIOD:-120s}
|
||||
|
||||
ac-worldserver-modules:
|
||||
profiles: ["services-modules"]
|
||||
image: ${AC_WORLDSERVER_IMAGE_MODULES:-acore/ac-wotlk-worldserver:modules-latest}
|
||||
container_name: ac-worldserver
|
||||
user: "${CONTAINER_USER:-0:0}"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
depends_on:
|
||||
- ac-authserver-modules
|
||||
- ac-client-data-standard
|
||||
environment:
|
||||
AC_LOGIN_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_AUTH_NAME:-acore_auth}"
|
||||
AC_WORLD_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_WORLD_NAME:-acore_world}"
|
||||
AC_CHARACTER_DATABASE_INFO: "${CONTAINER_MYSQL:-ac-mysql};${MYSQL_PORT:-3306};${MYSQL_USER:-root};${MYSQL_ROOT_PASSWORD:-azerothcore123};${DB_CHARACTERS_NAME:-acore_characters}"
|
||||
AC_UPDATES_ENABLE_DATABASES: "0"
|
||||
AC_BIND_IP: "0.0.0.0"
|
||||
AC_DATA_DIR: "/azerothcore/data"
|
||||
AC_SOAP_PORT: "7878"
|
||||
AC_PROCESS_PRIORITY: "0"
|
||||
AC_ELUNA_ENABLED: "${AC_ELUNA_ENABLED:-1}"
|
||||
AC_ELUNA_TRACE_BACK: "${AC_ELUNA_TRACE_BACK:-1}"
|
||||
AC_ELUNA_AUTO_RELOAD: "${AC_ELUNA_AUTO_RELOAD:-1}"
|
||||
AC_ELUNA_BYTECODE_CACHE: "${AC_ELUNA_BYTECODE_CACHE:-1}"
|
||||
AC_ELUNA_SCRIPT_PATH: "${AC_ELUNA_SCRIPT_PATH:-lua_scripts}"
|
||||
AC_ELUNA_REQUIRE_PATHS: "${AC_ELUNA_REQUIRE_PATHS:-}"
|
||||
AC_ELUNA_REQUIRE_CPATHS: "${AC_ELUNA_REQUIRE_CPATHS:-}"
|
||||
AC_ELUNA_AUTO_RELOAD_INTERVAL: "${AC_ELUNA_AUTO_RELOAD_INTERVAL:-1}"
|
||||
PLAYERBOT_ENABLED: "${PLAYERBOT_ENABLED:-0}"
|
||||
PLAYERBOT_MAX_BOTS: "${PLAYERBOT_MAX_BOTS:-40}"
|
||||
AC_LOG_LEVEL: "2"
|
||||
volumes:
|
||||
- ${STORAGE_PATH:-./storage}/data:/azerothcore/data
|
||||
- ${STORAGE_PATH:-./storage}/config:/azerothcore/env/dist/etc
|
||||
- ${STORAGE_PATH:-./storage}/logs:/azerothcore/logs
|
||||
- ${STORAGE_PATH:-./storage}/modules:/azerothcore/modules
|
||||
- ${STORAGE_PATH:-./storage}/lua_scripts:/azerothcore/lua_scripts
|
||||
networks:
|
||||
- azerothcore
|
||||
ports:
|
||||
- "${WORLD_EXTERNAL_PORT:-8215}:${WORLD_PORT:-8085}"
|
||||
- "${SOAP_EXTERNAL_PORT:-7778}:${SOAP_PORT:-7878}"
|
||||
restart: unless-stopped
|
||||
cap_add: ["SYS_NICE"]
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "ps aux | grep '[w]orldserver' | grep -v grep || exit 1"]
|
||||
interval: ${WORLD_HEALTHCHECK_INTERVAL:-30s}
|
||||
timeout: ${WORLD_HEALTHCHECK_TIMEOUT:-10s}
|
||||
retries: ${WORLD_HEALTHCHECK_RETRIES:-3}
|
||||
start_period: ${WORLD_HEALTHCHECK_START_PERIOD:-120s}
|
||||
|
||||
# =====================
|
||||
# Modules & Post-install (modules)
|
||||
# =====================
|
||||
|
||||
220
deploy.sh
Executable file
220
deploy.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# High-level orchestrator for module-aware deployments.
|
||||
# 1. Ensures AzerothCore source repo is present
|
||||
# 2. Runs ac-modules to sync/clean module checkout and configs
|
||||
# 3. Rebuilds source images when C++ modules demand it
|
||||
# 4. Stages target compose profile and optionally tails worldserver logs
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
COMPOSE_FILE="$ROOT_DIR/compose.yml"
|
||||
ENV_PATH="$ROOT_DIR/.env"
|
||||
TARGET_PROFILE=""
|
||||
WATCH_LOGS=1
|
||||
KEEP_RUNNING=0
|
||||
SKIP_REBUILD=0
|
||||
|
||||
BLUE='\033[0;34m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
info(){ echo -e "${BLUE}ℹ️ $*${NC}"; }
|
||||
ok(){ echo -e "${GREEN}✅ $*${NC}"; }
|
||||
warn(){ echo -e "${YELLOW}⚠️ $*${NC}"; }
|
||||
err(){ echo -e "${RED}❌ $*${NC}"; }
|
||||
|
||||
usage(){
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [options]
|
||||
|
||||
Options:
|
||||
--profile {standard|playerbots|modules} Force target profile (default: auto-detect)
|
||||
--no-watch Do not tail worldserver logs after staging
|
||||
--keep-running Do not pre-stop runtime stack before rebuild
|
||||
--skip-rebuild Skip source rebuild even if modules require it
|
||||
-h, --help Show this help
|
||||
|
||||
This command automates the module workflow (sync modules, rebuild source if needed,
|
||||
stage the correct compose profile, and optionally watch worldserver logs).
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile) TARGET_PROFILE="$2"; shift 2;;
|
||||
--no-watch) WATCH_LOGS=0; shift;;
|
||||
--keep-running) KEEP_RUNNING=1; shift;;
|
||||
--skip-rebuild) SKIP_REBUILD=1; shift;;
|
||||
-h|--help) usage; exit 0;;
|
||||
*) err "Unknown option: $1"; usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
require_cmd(){
|
||||
command -v "$1" >/dev/null 2>&1 || { err "Missing required command: $1"; exit 1; }
|
||||
}
|
||||
|
||||
require_cmd docker
|
||||
|
||||
read_env(){
|
||||
local key="$1" default="${2:-}"
|
||||
local value=""
|
||||
if [ -f "$ENV_PATH" ]; then
|
||||
value="$(grep -E "^${key}=" "$ENV_PATH" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
|
||||
fi
|
||||
if [ -z "$value" ]; then
|
||||
value="$default"
|
||||
fi
|
||||
echo "$value"
|
||||
}
|
||||
|
||||
resolve_project_name(){
|
||||
local raw_name="$(read_env COMPOSE_PROJECT_NAME "acore-compose")"
|
||||
local sanitized
|
||||
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
|
||||
sanitized="${sanitized// /-}"
|
||||
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||
if [[ -z "$sanitized" ]]; then
|
||||
sanitized="acore-compose"
|
||||
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||
sanitized="ac${sanitized}"
|
||||
fi
|
||||
echo "$sanitized"
|
||||
}
|
||||
|
||||
compose(){
|
||||
local project_name
|
||||
project_name="$(resolve_project_name)"
|
||||
docker compose --project-name "$project_name" -f "$COMPOSE_FILE" "$@"
|
||||
}
|
||||
|
||||
ensure_source_repo(){
|
||||
local src_path
|
||||
src_path="$(read_env MODULES_REBUILD_SOURCE_PATH "./source/azerothcore")"
|
||||
if [[ "$src_path" != /* ]]; then
|
||||
src_path="$ROOT_DIR/$src_path"
|
||||
fi
|
||||
if [ -d "$src_path/.git" ]; then
|
||||
echo "$src_path"
|
||||
return
|
||||
fi
|
||||
warn "AzerothCore source not found at $src_path; running setup-source.sh"
|
||||
(cd "$ROOT_DIR" && ./scripts/setup-source.sh)
|
||||
echo "$src_path"
|
||||
}
|
||||
|
||||
stop_runtime_stack(){
|
||||
info "Stopping runtime stack to avoid container name conflicts"
|
||||
compose \
|
||||
--profile services-standard \
|
||||
--profile services-playerbots \
|
||||
--profile services-modules \
|
||||
--profile db \
|
||||
--profile client-data \
|
||||
--profile client-data-bots \
|
||||
--profile modules \
|
||||
down 2>/dev/null || true
|
||||
}
|
||||
|
||||
sync_modules(){
|
||||
info "Synchronising modules (ac-modules)"
|
||||
compose --profile db --profile modules up ac-modules
|
||||
compose --profile db --profile modules down >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
modules_need_rebuild(){
|
||||
local storage_path
|
||||
storage_path="$(read_env STORAGE_PATH "./storage")"
|
||||
if [[ "$storage_path" != /* ]]; then
|
||||
storage_path="$ROOT_DIR/$storage_path"
|
||||
fi
|
||||
local sentinel="$storage_path/modules/.requires_rebuild"
|
||||
[[ -f "$sentinel" ]]
|
||||
}
|
||||
|
||||
rebuild_source(){
|
||||
local src_dir="$1"
|
||||
local compose_file="$src_dir/docker-compose.yml"
|
||||
if [ ! -f "$compose_file" ]; then
|
||||
err "Source docker-compose.yml missing at $compose_file"
|
||||
return 1
|
||||
fi
|
||||
info "Rebuilding AzerothCore source with modules (this may take a while)"
|
||||
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
|
||||
if (cd "$ROOT_DIR" && ./scripts/rebuild-with-modules.sh --yes); then
|
||||
ok "Source rebuild completed"
|
||||
else
|
||||
err "Source rebuild failed"
|
||||
return 1
|
||||
fi
|
||||
docker compose -f "$compose_file" down --remove-orphans >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
tag_module_images(){
|
||||
local source_world="acore/ac-wotlk-worldserver:master"
|
||||
local source_auth="acore/ac-wotlk-authserver:master"
|
||||
local target_world
|
||||
local target_auth
|
||||
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "acore/ac-wotlk-worldserver:modules-latest")"
|
||||
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "acore/ac-wotlk-authserver:modules-latest")"
|
||||
|
||||
if docker image inspect "$source_world" >/dev/null 2>&1; then
|
||||
docker tag "$source_world" "$target_world"
|
||||
ok "Tagged $target_world from $source_world"
|
||||
else
|
||||
warn "Source image $source_world not found; skipping tag"
|
||||
fi
|
||||
|
||||
if docker image inspect "$source_auth" >/dev/null 2>&1; then
|
||||
docker tag "$source_auth" "$target_auth"
|
||||
ok "Tagged $target_auth from $source_auth"
|
||||
else
|
||||
warn "Source image $source_auth not found; skipping tag"
|
||||
fi
|
||||
}
|
||||
|
||||
stage_runtime(){
|
||||
local args=(--yes)
|
||||
if [ -n "$TARGET_PROFILE" ]; then
|
||||
args+=("$TARGET_PROFILE")
|
||||
fi
|
||||
info "Staging runtime environment via stage-modules.sh ${args[*]}"
|
||||
(cd "$ROOT_DIR" && ./scripts/stage-modules.sh "${args[@]}")
|
||||
}
|
||||
|
||||
tail_world_logs(){
|
||||
info "Tailing worldserver logs (Ctrl+C to stop)"
|
||||
compose logs -f ac-worldserver
|
||||
}
|
||||
|
||||
main(){
|
||||
local src_dir
|
||||
src_dir="$(ensure_source_repo)"
|
||||
|
||||
if [ "$KEEP_RUNNING" -ne 1 ]; then
|
||||
stop_runtime_stack
|
||||
fi
|
||||
|
||||
sync_modules
|
||||
|
||||
if modules_need_rebuild; then
|
||||
if [ "$SKIP_REBUILD" -eq 1 ]; then
|
||||
warn "Modules require rebuild, but --skip-rebuild was provided."
|
||||
else
|
||||
rebuild_source "$src_dir"
|
||||
tag_module_images
|
||||
fi
|
||||
else
|
||||
info "No module rebuild required."
|
||||
tag_module_images
|
||||
fi
|
||||
|
||||
stage_runtime
|
||||
|
||||
if [ "$WATCH_LOGS" -eq 1 ]; then
|
||||
tail_world_logs
|
||||
else
|
||||
ok "Deployment completed. Logs not tailed (--no-watch)."
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
@@ -122,7 +122,6 @@ declare -A MODULE_REPO_MAP=(
|
||||
[MODULE_ACCOUNT_ACHIEVEMENTS]=mod-account-achievements
|
||||
[MODULE_AUTO_REVIVE]=mod-auto-revive
|
||||
[MODULE_GAIN_HONOR_GUARD]=mod-gain-honor-guard
|
||||
[MODULE_ELUNA]=mod-eluna
|
||||
[MODULE_TIME_IS_TIME]=mod-TimeIsTime
|
||||
[MODULE_POCKET_PORTAL]=mod-pocket-portal
|
||||
[MODULE_RANDOM_ENCHANTS]=mod-random-enchants
|
||||
@@ -184,8 +183,8 @@ fi
|
||||
echo "🚀 Building AzerothCore with modules..."
|
||||
docker compose build --no-cache
|
||||
|
||||
echo "🟢 Starting source services..."
|
||||
docker compose up -d
|
||||
echo "🧹 Cleaning up source build containers..."
|
||||
docker compose down --remove-orphans >/dev/null 2>&1 || true
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
|
||||
78
scripts/setup-source.sh
Executable file
78
scripts/setup-source.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
# ac-compose source repository setup
|
||||
set -e
|
||||
|
||||
echo '🔧 Setting up AzerothCore source repository...'
|
||||
|
||||
# Load environment variables if .env exists
|
||||
if [ -f .env ]; then
|
||||
source .env
|
||||
fi
|
||||
|
||||
# Default values
|
||||
SOURCE_PATH="${MODULES_REBUILD_SOURCE_PATH:-./source/azerothcore}"
|
||||
|
||||
# Convert to absolute path if relative
|
||||
if [[ "$SOURCE_PATH" != /* ]]; then
|
||||
SOURCE_PATH="$(pwd)/$SOURCE_PATH"
|
||||
fi
|
||||
MODULE_PLAYERBOTS="${MODULE_PLAYERBOTS:-0}"
|
||||
|
||||
# Repository and branch selection based on playerbots mode
|
||||
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
|
||||
REPO_URL="https://github.com/liyunfan1223/azerothcore-wotlk.git"
|
||||
BRANCH="Playerbot"
|
||||
echo "📌 Playerbots mode: Using liyunfan1223 fork, Playerbot branch"
|
||||
else
|
||||
REPO_URL="https://github.com/azerothcore/azerothcore-wotlk.git"
|
||||
BRANCH="master"
|
||||
echo "📌 Standard mode: Using official AzerothCore, master branch"
|
||||
fi
|
||||
|
||||
echo "📍 Repository: $REPO_URL"
|
||||
echo "🌿 Branch: $BRANCH"
|
||||
echo "📂 Source path: $SOURCE_PATH"
|
||||
|
||||
# Create source directory if it doesn't exist
|
||||
mkdir -p "$(dirname "$SOURCE_PATH")"
|
||||
|
||||
# Clone or update repository
|
||||
if [ -d "$SOURCE_PATH/.git" ]; then
|
||||
echo "📂 Existing repository found, updating..."
|
||||
cd "$SOURCE_PATH"
|
||||
|
||||
# Check if we're on the correct repository
|
||||
CURRENT_REMOTE=$(git remote get-url origin 2>/dev/null || echo "")
|
||||
if [ "$CURRENT_REMOTE" != "$REPO_URL" ]; then
|
||||
echo "🔄 Repository URL changed, re-cloning..."
|
||||
cd ..
|
||||
rm -rf "$(basename "$SOURCE_PATH")"
|
||||
git clone "$REPO_URL" "$(basename "$SOURCE_PATH")"
|
||||
cd "$(basename "$SOURCE_PATH")"
|
||||
fi
|
||||
|
||||
# Fetch latest changes
|
||||
git fetch origin
|
||||
|
||||
# Switch to target branch
|
||||
git checkout "$BRANCH"
|
||||
git pull origin "$BRANCH"
|
||||
|
||||
echo "✅ Repository updated to latest $BRANCH"
|
||||
else
|
||||
echo "📥 Cloning repository..."
|
||||
git clone -b "$BRANCH" "$REPO_URL" "$SOURCE_PATH"
|
||||
echo "✅ Repository cloned successfully"
|
||||
fi
|
||||
|
||||
cd "$SOURCE_PATH"
|
||||
|
||||
# Display current status
|
||||
CURRENT_COMMIT=$(git rev-parse --short HEAD)
|
||||
CURRENT_BRANCH=$(git branch --show-current)
|
||||
echo "📊 Current status:"
|
||||
echo " Branch: $CURRENT_BRANCH"
|
||||
echo " Commit: $CURRENT_COMMIT"
|
||||
echo " Last commit: $(git log -1 --pretty=format:'%s (%an, %ar)')"
|
||||
|
||||
echo '🎉 Source repository setup complete!'
|
||||
211
scripts/stage-modules.sh
Executable file
211
scripts/stage-modules.sh
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ac-compose helper to automatically stage modules and trigger source builds when needed.
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
ENV_FILE="$PROJECT_DIR/.env"
|
||||
|
||||
usage(){
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [options] [PROFILE]
|
||||
|
||||
Automatically detect and stage modules for AzerothCore.
|
||||
|
||||
Arguments:
|
||||
PROFILE Target profile (standard, playerbots, or auto-detect)
|
||||
|
||||
Options:
|
||||
--force-rebuild Force a source rebuild even if not needed
|
||||
--yes, -y Skip interactive confirmation prompts
|
||||
-h, --help Show this help
|
||||
|
||||
Examples:
|
||||
$(basename "$0") # Auto-detect profile based on enabled modules
|
||||
$(basename "$0") playerbots # Force playerbots profile
|
||||
$(basename "$0") --force-rebuild # Force rebuild and auto-detect
|
||||
EOF
|
||||
}
|
||||
|
||||
read_env(){
|
||||
local key="$1" default="$2" env_path="$ENV_FILE" value
|
||||
if [ -f "$env_path" ]; then
|
||||
value="$(grep -E "^${key}=" "$env_path" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
|
||||
fi
|
||||
if [ -z "$value" ]; then
|
||||
value="$default"
|
||||
fi
|
||||
echo "$value"
|
||||
}
|
||||
|
||||
confirm(){
|
||||
local prompt="$1" default="$2" reply
|
||||
if [ "$ASSUME_YES" = "1" ]; then
|
||||
return 0
|
||||
fi
|
||||
while true; do
|
||||
if [ "$default" = "y" ]; then
|
||||
read -r -p "$prompt [Y/n]: " reply
|
||||
reply="${reply:-y}"
|
||||
else
|
||||
read -r -p "$prompt [y/N]: " reply
|
||||
reply="${reply:-n}"
|
||||
fi
|
||||
case "$reply" in
|
||||
[Yy]*) return 0 ;;
|
||||
[Nn]*) return 1 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
ASSUME_YES=0
|
||||
FORCE_REBUILD=0
|
||||
TARGET_PROFILE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--yes|-y) ASSUME_YES=1; shift;;
|
||||
--force-rebuild) FORCE_REBUILD=1; shift;;
|
||||
-h|--help) usage; exit 0;;
|
||||
standard|playerbots) TARGET_PROFILE="$1"; shift;;
|
||||
*) echo "Unknown option: $1" >&2; usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "❌ Docker CLI not found in PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
STORAGE_PATH="$(read_env STORAGE_PATH "./storage")"
|
||||
if [[ "$STORAGE_PATH" != /* ]]; then
|
||||
STORAGE_PATH="$PROJECT_DIR/$STORAGE_PATH"
|
||||
fi
|
||||
MODULES_DIR="$STORAGE_PATH/modules"
|
||||
SENTINEL_FILE="$MODULES_DIR/.requires_rebuild"
|
||||
|
||||
# Define module mappings (from rebuild-with-modules.sh)
|
||||
declare -A MODULE_REPO_MAP=(
|
||||
[MODULE_AOE_LOOT]=mod-aoe-loot
|
||||
[MODULE_LEARN_SPELLS]=mod-learn-spells
|
||||
[MODULE_FIREWORKS]=mod-fireworks-on-level
|
||||
[MODULE_INDIVIDUAL_PROGRESSION]=mod-individual-progression
|
||||
[MODULE_AHBOT]=mod-ahbot
|
||||
[MODULE_AUTOBALANCE]=mod-autobalance
|
||||
[MODULE_TRANSMOG]=mod-transmog
|
||||
[MODULE_NPC_BUFFER]=mod-npc-buffer
|
||||
[MODULE_DYNAMIC_XP]=mod-dynamic-xp
|
||||
[MODULE_SOLO_LFG]=mod-solo-lfg
|
||||
[MODULE_1V1_ARENA]=mod-1v1-arena
|
||||
[MODULE_PHASED_DUELS]=mod-phased-duels
|
||||
[MODULE_BREAKING_NEWS]=mod-breaking-news-override
|
||||
[MODULE_BOSS_ANNOUNCER]=mod-boss-announcer
|
||||
[MODULE_ACCOUNT_ACHIEVEMENTS]=mod-account-achievements
|
||||
[MODULE_AUTO_REVIVE]=mod-auto-revive
|
||||
[MODULE_GAIN_HONOR_GUARD]=mod-gain-honor-guard
|
||||
[MODULE_TIME_IS_TIME]=mod-TimeIsTime
|
||||
[MODULE_POCKET_PORTAL]=mod-pocket-portal
|
||||
[MODULE_RANDOM_ENCHANTS]=mod-random-enchants
|
||||
[MODULE_SOLOCRAFT]=mod-solocraft
|
||||
[MODULE_PVP_TITLES]=mod-pvp-titles
|
||||
[MODULE_NPC_BEASTMASTER]=mod-npc-beastmaster
|
||||
[MODULE_NPC_ENCHANTER]=mod-npc-enchanter
|
||||
[MODULE_INSTANCE_RESET]=mod-instance-reset
|
||||
[MODULE_LEVEL_GRANT]=mod-quest-count-level
|
||||
)
|
||||
|
||||
# Check for enabled C++ modules that require compilation
|
||||
compile_modules=()
|
||||
for key in "${!MODULE_REPO_MAP[@]}"; do
|
||||
if [ "$(read_env "$key" "0")" = "1" ]; then
|
||||
compile_modules+=("${MODULE_REPO_MAP[$key]}")
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for playerbots mode
|
||||
PLAYERBOT_ENABLED="$(read_env PLAYERBOT_ENABLED "0")"
|
||||
MODULE_PLAYERBOTS="$(read_env MODULE_PLAYERBOTS "0")"
|
||||
|
||||
# Determine target profile if not specified
|
||||
if [ -z "$TARGET_PROFILE" ]; then
|
||||
if [ ${#compile_modules[@]} -gt 0 ]; then
|
||||
echo "🔧 Detected ${#compile_modules[@]} C++ modules requiring compilation:"
|
||||
for mod in "${compile_modules[@]}"; do
|
||||
echo " • $mod"
|
||||
done
|
||||
TARGET_PROFILE="modules"
|
||||
echo "🧩 Using modules profile for custom source build"
|
||||
elif [ "$MODULE_PLAYERBOTS" = "1" ] || [ "$PLAYERBOT_ENABLED" = "1" ]; then
|
||||
TARGET_PROFILE="playerbots"
|
||||
echo "🤖 Playerbot profile enabled"
|
||||
else
|
||||
TARGET_PROFILE="standard"
|
||||
echo "✅ No special modules detected - using standard profile"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🎯 Target profile: services-$TARGET_PROFILE"
|
||||
|
||||
# Check if source rebuild is needed for modules profile
|
||||
REBUILD_NEEDED=0
|
||||
if [ "$TARGET_PROFILE" = "modules" ]; then
|
||||
# Check if source image exists
|
||||
if ! docker image inspect "acore/ac-wotlk-worldserver:modules-latest" >/dev/null 2>&1; then
|
||||
echo "📦 Custom worldserver image not found - rebuild needed"
|
||||
REBUILD_NEEDED=1
|
||||
elif [ -f "$SENTINEL_FILE" ]; then
|
||||
echo "🔄 Modules changed since last build - rebuild needed"
|
||||
REBUILD_NEEDED=1
|
||||
elif [ "$FORCE_REBUILD" = "1" ]; then
|
||||
echo "🔧 Force rebuild requested"
|
||||
REBUILD_NEEDED=1
|
||||
fi
|
||||
|
||||
if [ "$REBUILD_NEEDED" = "1" ]; then
|
||||
echo "🚀 Triggering source rebuild with modules..."
|
||||
if confirm "Proceed with source rebuild? (15-45 minutes)" n; then
|
||||
"$SCRIPT_DIR/rebuild-with-modules.sh" ${ASSUME_YES:+--yes}
|
||||
else
|
||||
echo "❌ Rebuild cancelled"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ Custom worldserver image up to date"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stage the services
|
||||
echo "🎬 Staging services with profile: services-$TARGET_PROFILE"
|
||||
|
||||
# Stop any currently running services
|
||||
echo "🛑 Stopping current services..."
|
||||
docker compose \
|
||||
--profile services-standard \
|
||||
--profile services-playerbots \
|
||||
--profile services-modules \
|
||||
--profile client-data \
|
||||
--profile client-data-bots \
|
||||
down 2>/dev/null || true
|
||||
|
||||
# Build list of profiles to start
|
||||
PROFILE_ARGS=(--profile "services-$TARGET_PROFILE" --profile db --profile modules)
|
||||
case "$TARGET_PROFILE" in
|
||||
standard) PROFILE_ARGS+=(--profile client-data) ;;
|
||||
playerbots) PROFILE_ARGS+=(--profile client-data-bots) ;;
|
||||
modules) PROFILE_ARGS+=(--profile client-data) ;;
|
||||
esac
|
||||
|
||||
# Start the target profile
|
||||
echo "🟢 Starting services-$TARGET_PROFILE profile..."
|
||||
docker compose "${PROFILE_ARGS[@]}" up -d
|
||||
|
||||
echo ""
|
||||
echo "🎉 SUCCESS! AzerothCore staged with profile: services-$TARGET_PROFILE"
|
||||
|
||||
# Show status
|
||||
echo ""
|
||||
echo "📊 Service Status:"
|
||||
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}" | grep -E "(ac-worldserver|ac-authserver|NAME)" || true
|
||||
29
setup.sh
29
setup.sh
@@ -52,7 +52,7 @@ Description:
|
||||
|
||||
Notes:
|
||||
- The generated .env is read automatically by docker compose.
|
||||
- Run deploy with: deploy-and-check.sh or docker compose --profile ... up -d
|
||||
- Run deploy with: deploy.sh or docker compose --profile ... up -d
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
@@ -162,10 +162,15 @@ EOF
|
||||
local MODULE_PLAYERBOTS=0 MODULE_AOE_LOOT=0 MODULE_LEARN_SPELLS=0 MODULE_FIREWORKS=0 MODULE_INDIVIDUAL_PROGRESSION=0 \
|
||||
MODULE_AHBOT=0 MODULE_AUTOBALANCE=0 MODULE_TRANSMOG=0 MODULE_NPC_BUFFER=0 MODULE_DYNAMIC_XP=0 MODULE_SOLO_LFG=0 \
|
||||
MODULE_1V1_ARENA=0 MODULE_PHASED_DUELS=0 MODULE_BREAKING_NEWS=0 MODULE_BOSS_ANNOUNCER=0 MODULE_ACCOUNT_ACHIEVEMENTS=0 \
|
||||
MODULE_AUTO_REVIVE=0 MODULE_GAIN_HONOR_GUARD=0 MODULE_ELUNA=1 MODULE_TIME_IS_TIME=0 MODULE_POCKET_PORTAL=0 \
|
||||
MODULE_AUTO_REVIVE=0 MODULE_GAIN_HONOR_GUARD=0 MODULE_TIME_IS_TIME=0 MODULE_POCKET_PORTAL=0 \
|
||||
MODULE_RANDOM_ENCHANTS=0 MODULE_SOLOCRAFT=0 MODULE_PVP_TITLES=0 MODULE_NPC_BEASTMASTER=0 MODULE_NPC_ENCHANTER=0 \
|
||||
MODULE_INSTANCE_RESET=0 MODULE_LEVEL_GRANT=0 MODULE_ASSISTANT=0 MODULE_REAGENT_BANK=0 MODULE_BLACK_MARKET_AUCTION_HOUSE=0 MODULE_ARAC=0
|
||||
|
||||
declare -A DISABLED_MODULE_REASONS=(
|
||||
[MODULE_AHBOT]="Requires upstream Addmod_ahbotScripts symbol (fails link)"
|
||||
[MODULE_LEVEL_GRANT]="QuestCountLevel module relies on removed ConfigMgr APIs and fails to build"
|
||||
)
|
||||
|
||||
local PLAYERBOT_ENABLED=0 PLAYERBOT_MAX_BOTS=40
|
||||
|
||||
local AUTO_REBUILD_ON_DEPLOY=0
|
||||
@@ -174,11 +179,14 @@ EOF
|
||||
local NEEDS_CXX_REBUILD=0
|
||||
|
||||
if [ "$MODE" = "1" ]; then
|
||||
MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_AHBOT=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
|
||||
MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
|
||||
elif [ "$MODE" = "2" ]; then
|
||||
MODULE_PLAYERBOTS=1; MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_AHBOT=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
|
||||
MODULE_PLAYERBOTS=1; MODULE_SOLO_LFG=1; MODULE_SOLOCRAFT=1; MODULE_AUTOBALANCE=1; MODULE_TRANSMOG=1; MODULE_NPC_BUFFER=1; MODULE_LEARN_SPELLS=1; MODULE_FIREWORKS=1
|
||||
elif [ "$MODE" = "3" ]; then
|
||||
say INFO "Answer y/n for each module"
|
||||
for key in "${!DISABLED_MODULE_REASONS[@]}"; do
|
||||
say WARNING "${key#MODULE_}: ${DISABLED_MODULE_REASONS[$key]}"
|
||||
done
|
||||
# Core Gameplay
|
||||
MODULE_PLAYERBOTS=$(ask_yn "Playerbots - AI companions" n)
|
||||
MODULE_SOLO_LFG=$(ask_yn "Solo LFG - Solo dungeon finder" n)
|
||||
@@ -202,7 +210,6 @@ EOF
|
||||
# Progression
|
||||
MODULE_INDIVIDUAL_PROGRESSION=$(ask_yn "Individual Progression (Vanilla→TBC→WotLK)" n)
|
||||
MODULE_DYNAMIC_XP=$(ask_yn "Dynamic XP" n)
|
||||
MODULE_LEVEL_GRANT=$(ask_yn "Level Grant" n)
|
||||
MODULE_ACCOUNT_ACHIEVEMENTS=$(ask_yn "Account Achievements" n)
|
||||
# Server Features
|
||||
MODULE_BREAKING_NEWS=$(ask_yn "Breaking News" n)
|
||||
@@ -219,7 +226,7 @@ EOF
|
||||
MODULE_ARAC=$(ask_yn "All Races All Classes (requires client patch)" n)
|
||||
fi
|
||||
|
||||
for mod_var in MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE MODULE_TRANSMOG MODULE_NPC_BUFFER MODULE_DYNAMIC_XP MODULE_SOLO_LFG MODULE_1V1_ARENA MODULE_PHASED_DUELS MODULE_BREAKING_NEWS MODULE_BOSS_ANNOUNCER MODULE_ACCOUNT_ACHIEVEMENTS MODULE_AUTO_REVIVE MODULE_GAIN_HONOR_GUARD MODULE_ELUNA MODULE_TIME_IS_TIME MODULE_POCKET_PORTAL MODULE_RANDOM_ENCHANTS MODULE_SOLOCRAFT MODULE_PVP_TITLES MODULE_NPC_BEASTMASTER MODULE_NPC_ENCHANTER MODULE_INSTANCE_RESET MODULE_LEVEL_GRANT MODULE_ARAC MODULE_ASSISTANT MODULE_REAGENT_BANK MODULE_BLACK_MARKET_AUCTION_HOUSE; do
|
||||
for mod_var in MODULE_AOE_LOOT MODULE_LEARN_SPELLS MODULE_FIREWORKS MODULE_INDIVIDUAL_PROGRESSION MODULE_AHBOT MODULE_AUTOBALANCE MODULE_TRANSMOG MODULE_NPC_BUFFER MODULE_DYNAMIC_XP MODULE_SOLO_LFG MODULE_1V1_ARENA MODULE_PHASED_DUELS MODULE_BREAKING_NEWS MODULE_BOSS_ANNOUNCER MODULE_ACCOUNT_ACHIEVEMENTS MODULE_AUTO_REVIVE MODULE_GAIN_HONOR_GUARD MODULE_TIME_IS_TIME MODULE_POCKET_PORTAL MODULE_RANDOM_ENCHANTS MODULE_SOLOCRAFT MODULE_PVP_TITLES MODULE_NPC_BEASTMASTER MODULE_NPC_ENCHANTER MODULE_INSTANCE_RESET MODULE_LEVEL_GRANT MODULE_ARAC MODULE_ASSISTANT MODULE_REAGENT_BANK MODULE_BLACK_MARKET_AUCTION_HOUSE; do
|
||||
eval "value=\$$mod_var"
|
||||
if [ "$value" = "1" ]; then
|
||||
NEEDS_CXX_REBUILD=1
|
||||
@@ -234,9 +241,8 @@ EOF
|
||||
printf " %-18s %s\n" "Storage Path:" "$STORAGE_PATH"
|
||||
printf " %-18s %s\n" "Container User:" "$CONTAINER_USER"
|
||||
printf " %-18s Daily %s:00 UTC, keep %sd/%sh\n" "Backups:" "$BACKUP_DAILY_TIME" "$BACKUP_RETENTION_DAYS" "$BACKUP_RETENTION_HOURS"
|
||||
printf " %-18s preset %s (playerbots=%s solo_lfg=%s autobalance=%s transmog=%s ahbot=%s npc_buffer=%s learn_spells=%s fireworks=%s)\n" \
|
||||
"Modules:" "$MODE" "$MODULE_PLAYERBOTS" "$MODULE_SOLO_LFG" "$MODULE_AUTOBALANCE" "$MODULE_TRANSMOG" "$MODULE_AHBOT" "$MODULE_NPC_BUFFER" "$MODULE_LEARN_SPELLS" "$MODULE_FIREWORKS"
|
||||
printf " %-18s enabled by default (edit .env to disable)\n" "Eluna:"
|
||||
printf " %-18s preset %s (playerbots=%s solo_lfg=%s autobalance=%s transmog=%s npc_buffer=%s learn_spells=%s fireworks=%s)\n" \
|
||||
"Modules:" "$MODE" "$MODULE_PLAYERBOTS" "$MODULE_SOLO_LFG" "$MODULE_AUTOBALANCE" "$MODULE_TRANSMOG" "$MODULE_NPC_BUFFER" "$MODULE_LEARN_SPELLS" "$MODULE_FIREWORKS"
|
||||
if [ "$NEEDS_CXX_REBUILD" = "1" ]; then
|
||||
printf " %-18s detected (source rebuild required)\n" "C++ modules:"
|
||||
fi
|
||||
@@ -340,7 +346,6 @@ MODULE_BOSS_ANNOUNCER=$MODULE_BOSS_ANNOUNCER
|
||||
MODULE_ACCOUNT_ACHIEVEMENTS=$MODULE_ACCOUNT_ACHIEVEMENTS
|
||||
MODULE_AUTO_REVIVE=$MODULE_AUTO_REVIVE
|
||||
MODULE_GAIN_HONOR_GUARD=$MODULE_GAIN_HONOR_GUARD
|
||||
MODULE_ELUNA=$MODULE_ELUNA
|
||||
MODULE_ARAC=$MODULE_ARAC
|
||||
MODULE_TIME_IS_TIME=$MODULE_TIME_IS_TIME
|
||||
MODULE_POCKET_PORTAL=$MODULE_POCKET_PORTAL
|
||||
@@ -415,10 +420,10 @@ EOF
|
||||
say INFO "Run with profiles (examples):"
|
||||
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
|
||||
echo " docker compose -f compose.yml --profile db --profile services-playerbots --profile client-data-bots --profile modules --profile tools up -d"
|
||||
echo " ./deploy-and-check.sh --profiles db,services-playerbots,client-data-bots,modules,tools"
|
||||
echo " ./deploy.sh --profile modules --no-watch"
|
||||
else
|
||||
echo " docker compose -f compose.yml --profile db --profile services-standard --profile client-data --profile modules --profile tools up -d"
|
||||
echo " ./deploy-and-check.sh --profiles db,services-standard,client-data,modules,tools"
|
||||
echo " ./deploy.sh --profile modules --no-watch"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user