Container-based AzerothCore WoW server with module support. Uses Podman or Docker.
This project provides a single acm command that manages the full lifecycle of an AzerothCore server stack: setup, start/stop, backups, restores, module management, and Paragon Anniversary support.
- Features
- Requirements
- Quick Start
- Commands
- Configuration
- Backups & Retention
- Restore
- Creating an Account
- Modules
- Examples
- Shell Completion
- Development & Testing
- One-command setup, start, stop, backup, and restore
- Podman-based container stack with Podman Compose overrides
- Per-config project isolation via
NAME(containers, networks, volumes, and backups are separated) - Automated MySQL database and config backups with gzip compression
- Built-in backup retention / cleanup policy (keeps all backups from today, one per day for 7 days, one per week for 4 weeks, one per month for 12 months)
- Module support: clone/update modules from Git and remove stale modules automatically
- Optional game launch after the server is healthy
- Paragon Anniversary install/uninstall helpers
- Worldserver console attachment and account creation via
expect
- Podman and
podman-compose(or Docker with Compose v2, via theCONTAINER_CMDconfig setting) - Bash 4.2+
expect(foracm create-account)git,tar,gzipenvsubst(fromgettext; used byacm setupto generate the Compose override)rsync(used byacm setupandacm bundle paragon installto sync module/Lua files)patch(used byacm setupto remove the client-data-init dependency)
./acm setupClones the main AzerothCore repository, installs module dependencies, and rebuilds the full container stack.
./acm startStarts the server and waits for the authserver to be ready.
./acm restore ./backups/db_backup_playerbots_YYYYMMDD_HHMMSS.sql.gzStops the full stack, removes the database container and volume, restores from a compressed backup, then shuts down. Use ./acm start to start the full stack afterward.
All commands accept an optional config file path (defaults to ./conf/wowserver.conf).
| Command | Purpose |
|---|---|
acm setup |
Clone/update repos, rebuild all container images. Flags: --clean (remove old images), --no-cache (skip build cache), --reset (reset main repo to HEAD, discarding local changes), --skip-update (skip git pull), --skip-build (skip compose build), --prune (clean dangling and external images), --skip-stale (skip stale module removal). |
acm start |
Ensure old containers are stopped, start server, wait for authserver to be ready. |
acm run |
Start stack, optionally launch game, wait for game exit, wait for keypress, backup, cleanup old backups, shutdown. --skip-game to skip game launch. |
acm stop |
Stop the running stack. |
acm backup |
Backup databases and configs, stopping worldserver/authserver first. --skip-stop to leave them running. |
acm restore |
Restore a database backup, then shut down. |
acm bundle arac-updated install |
Install All races all classes dbc files. |
acm bundle arac-updated uninstall |
Remove All races all classes dbc files. |
acm bundle paragon install |
Install Paragon Anniversary SQL schema and sync lua scripts. --skip-git to skip clone, --database to set custom DB name. |
acm bundle paragon uninstall |
Drop Paragon databases and remove synced lua scripts. --database to set custom DB name. |
acm create-account |
Create a new WoW account with GM level 3 on the running worldserver (requires expect). |
acm console |
Attach to the running worldserver console (Ctrl+P then Ctrl+Q to detach). |
Run ./acm <command> --help for command-specific help.
Edit conf/wowserver.conf to set:
| Setting | Description |
|---|---|
NAME |
Container image tag and Compose project name (e.g. playerbots). |
CONTAINER_CMD |
The container command to use. Default: podman; set to docker for Docker with Compose v2. |
BACKUP_DIR |
Directory where backups are stored. Default: ./backups (relative to the project root). |
MAIN_REPO |
Base AzerothCore fork to clone. Append @branch for a specific branch. |
MODULE_REPO |
One module Git URL per line. Use @branch for branches and #path for subfolders. |
LAUNCH_GAME |
Command to run 5 seconds after the worldserver is healthy (backgrounded, output discarded). |
Multiple configs can be used to run separate server instances. For example, conf/wowserver-solo.conf uses NAME=solo so containers, volumes, and backups are kept separate from the main config.
Two files are created on every backup:
./backups/db_backup_<CONFIG_NAME>_YYYYMMDD_HHMMSS.sql.gz # MySQL dump of all databases
./backups/config_backup_<CONFIG_NAME>_YYYYMMDD_HHMMSS.tar.gz # env/dist/etc/ and lua_scripts/
- The database backup uses
mysqldump --all-databases --single-transaction --routines --events --triggersand compresses withgzip -9. - The config backup archives the server config files and any custom Lua scripts.
- Backups are scoped by
CONFIG_NAME. Multiple server configs sharing the same backup directory will not delete each other's files.
acm backup— Stops the worldserver and authserver, dumps and compresses all databases, archives configs, applies the retention policy, then restarts the services. Use--skip-stopto avoid the stop/restart cycle (useful for quick online backups).acm run— Starts the full stack, optionally launches the game, waits for a keypress, then performs the same backup and cleanup sequence before shutting everything down.
After every backup, old files are automatically pruned according to the following policy:
| Window | Kept backups |
|---|---|
| Today | All backups created today are kept. |
| Last 7 days | The latest backup from each day is kept. |
| Next 4 weeks | The latest backup from each week is kept. |
| Next 12 months | The latest backup from each month is kept. |
Anything not selected by the rules above is deleted. Both database and config backups are cleaned up independently using the same retention rules. Each deletion is logged, and a summary count is printed at the end of cleanup.
For example, if today is August 10th and you have multiple backups per day, the policy will keep:
- Every backup made on August 10th
- The newest backup from August 9th, 8th, 7th, 6th, 5th, 4th, and 3rd
- The newest backup from each of the four previous weeks (July 13th, July 6th, June 29th, June 22nd, etc.)
- The newest backup from each of the previous 12 months (July 2026, June 2026, May 2026, ...)
Important: only backups matching the naming pattern db_backup_<CONFIG_NAME>_*.sql.gz and config_backup_<CONFIG_NAME>_*.tar.gz in the configured backup directory are evaluated. Backups with non-matching names or in other directories are ignored and never deleted.
You can customize the retention policy or disable cleanup entirely by adding any of the following settings to your config file:
# Keep every backup forever (disables the retention policy)
KEEP_ALL_BACKUPS=true
# Number of days' worth of daily backups to retain, including today (default: 7)
BACKUP_RETAIN_DAILY=7
# Number of weekly backups to retain (default: 4)
BACKUP_RETAIN_WEEKLY=4
# Number of monthly backups to retain (default: 12)
BACKUP_RETAIN_MONTHLY=12Set KEEP_ALL_BACKUPS=true to keep every backup. When it is enabled, the BACKUP_RETAIN_* values are ignored.
The default backup directory is ./backups (relative to the project root). You can change it by setting BACKUP_DIR in your config file:
BACKUP_DIR=/mnt/backups/wowRelative paths are resolved relative to the project root.
Restore a compressed database backup into a fresh database volume:
./acm restore ./backups/db_backup_playerbots_YYYYMMDD_HHMMSS.sql.gzWhat happens during restore:
- The full stack is stopped and the database container is removed.
- The existing database volume is deleted so the restore is clean.
- Only the
ac-databasecontainer is started and waited for. - The backup is decompressed to a temporary file and restored via
mysql. - The database container is shut down.
After restore completes, start the full stack with:
./acm startTo restore a backup for a different config, pass the config file first:
./acm restore ./conf/wowserver-solo.conf ./backups/db_backup_solo_YYYYMMDD_HHMMSS.sql.gzMake sure the server is running, then:
./acm create-account testuser mypasswordTo open the worldserver console manually:
./acm consolePress Ctrl+P then Ctrl+Q to detach. Do not press Ctrl+C — that stops the server.
Modules are configured by adding one MODULE_REPO=<url> line per module in your config file. For example, in conf/wowserver.conf:
MODULE_REPO=https://github.com/azerothcore/mod-playerbots.git
MODULE_REPO=https://github.com/azerothcore/mod-autobalance.git@master
MODULE_REPO=https://github.com/dr1s/lua-paragon-anniversary.git@main#serverside/mod-paragon-loot| Format | Purpose |
|---|---|
https://github.com/user/repo.git |
Clone the default branch. |
https://github.com/user/repo.git@branch |
Clone a specific branch or tag. |
https://github.com/user/repo.git@branch#path/to/subfolder |
Clone a specific branch and use only a subfolder as the module. |
- Clone or update: Each
MODULE_REPOis cloned into./server/<CONFIG_NAME>/modules/<repo-name>/. If it already exists,git pullupdates it to the configured branch. - Stale module cleanup: Any directory in
./server/<CONFIG_NAME>/modules/that is a git repo but is not listed in the config is removed automatically. To protect a directory, create a.stale-keepfile inside it. - Skip stale cleanup: Use
--skip-staleto keep modules that are not in the config. - Module config initialization: After images are built,
acm setupcopies each module's*.conf.distfiles from./modules/<name>/conf/to./env/dist/etc/modules/with the.distsuffix removed.
# Add MODULE_REPO lines to conf/wowserver.conf, then:
./acm setup./acm start ./conf/wowserver-solo.conf./acm run./acm run --skip-game./acm backup --skip-stop./acm setup --clean --no-cache --pruneUse --reset to discard any local changes in the AzerothCore source tree before updating:
./acm setup --reset./acm setup --skip-build./acm restore ./backups/db_backup_playerbots_20260810_120000.sql.gz
./acm startA shell completion script is included at completions/acm. It dynamically completes commands, flags, bundles, subcommands, config files, and backup files.
source /path/to/repo/completions/acmFor a system-wide install, copy it to your distribution's completion directory:
sudo cp /path/to/repo/completions/acm /etc/bash_completion.d/
# or, on some distributions:
sudo cp /path/to/repo/completions/acm /usr/share/bash-completion/completions/acmA zsh completion wrapper is included at completions/_acm. Add the completions directory to your fpath and initialize the completion system:
fpath+=(/path/to/repo/completions)
autoload -Uz compinit && compinitAlternatively, you can load the bash completion directly with bashcompinit:
autoload -Uz bashcompinit && bashcompinit
source /path/to/repo/completions/acmA .env file is included for autoenv users, and .envrc is a symlink to .env for direnv users. zsh users should use autoenv or load the completion manually.
Run the shell syntax checker:
./tests/check.shRun the unit tests:
./tests/run-tests.sh