Portainer stack and deployment doc for Nox #1
2 changed files with 209 additions and 0 deletions
80
docker-compose.mythica.yml
Normal file
80
docker-compose.mythica.yml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Portainer stack for the Mythica armory.
|
||||
#
|
||||
# Differs from the upstream docker-compose.yml in three ways, all of them
|
||||
# because Portainer deploys from a git checkout it manages itself:
|
||||
#
|
||||
# 1. Configuration comes from environment variables set in the Portainer
|
||||
# stack UI, not from a .env file in the repo (upstream uses env_file,
|
||||
# which Portainer git stacks do not provide).
|
||||
# 2. Only the four large model-data directories are bind-mounted from the
|
||||
# host. The DBC .csv files stay in the image so they stay versioned with
|
||||
# the code, and Portainer re-cloning the repo cannot wipe the 2 GB of
|
||||
# model data.
|
||||
# 3. The unused ac-network block is dropped.
|
||||
#
|
||||
# See docs/mythica-deploy.md for the full procedure.
|
||||
|
||||
services:
|
||||
armory:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: mythica-armory
|
||||
restart: unless-stopped
|
||||
|
||||
environment:
|
||||
# --- site identity -------------------------------------------------
|
||||
ACORE_ARMORY_WEBSITE_NAME: ${ARMORY_WEBSITE_NAME:-Mythica}
|
||||
ACORE_ARMORY_WEBSITE_URL: ${ARMORY_WEBSITE_URL:-http://192.168.1.77:48733}
|
||||
ACORE_ARMORY_WEBSITE_ROOT: ${ARMORY_WEBSITE_ROOT:-}
|
||||
|
||||
# Item tooltips and item icons are loaded from this AoWoW instance.
|
||||
# The default is a public third-party site: point this at your own
|
||||
# AoWoW if you do not want that dependency.
|
||||
ACORE_ARMORY_AOWOW_URL: ${ARMORY_AOWOW_URL:-https://wowgaming.altervista.org/aowow}
|
||||
|
||||
# --- embedding -----------------------------------------------------
|
||||
# Set both when embedding the armory in a page on the main site.
|
||||
ACORE_ARMORY_IFRAME_MODE__ENABLED: ${ARMORY_IFRAME_ENABLED:-0}
|
||||
ACORE_ARMORY_IFRAME_MODE__URL: ${ARMORY_IFRAME_URL:-}
|
||||
|
||||
# --- behaviour -----------------------------------------------------
|
||||
ACORE_ARMORY_LOAD_DBCS: ${ARMORY_LOAD_DBCS:-1}
|
||||
ACORE_ARMORY_HIDE_GAME_MASTERS: ${ARMORY_HIDE_GMS:-1}
|
||||
ACORE_ARMORY_TRANSMOG_MODULE: ${ARMORY_TRANSMOG:-0}
|
||||
|
||||
# 0 = serve 3D model assets from the local data directory.
|
||||
# Leave it at 0: the upstream fetch tool can no longer rebuild this
|
||||
# data from the Zam CDN, so the local copy is the only source.
|
||||
ACORE_ARMORY_USE_ZAM_CDN: ${ARMORY_USE_ZAM_CDN:-0}
|
||||
|
||||
# --- realm ---------------------------------------------------------
|
||||
ACORE_ARMORY_REALMS__0__NAME: ${ARMORY_REALM_NAME:-Mythica}
|
||||
ACORE_ARMORY_REALMS__0__REALM_ID: ${ARMORY_REALM_ID:-1}
|
||||
ACORE_ARMORY_REALMS__0__AUTH_DATABASE: ${ARMORY_AUTH_DB:-acore_auth}
|
||||
ACORE_ARMORY_REALMS__0__CHARACTERS_DATABASE__HOST: ${ARMORY_DB_HOST:-192.168.1.60}
|
||||
ACORE_ARMORY_REALMS__0__CHARACTERS_DATABASE__PORT: ${ARMORY_DB_PORT:-3306}
|
||||
ACORE_ARMORY_REALMS__0__CHARACTERS_DATABASE__USER: ${ARMORY_DB_USER:?set ARMORY_DB_USER}
|
||||
ACORE_ARMORY_REALMS__0__CHARACTERS_DATABASE__PASSWORD: ${ARMORY_DB_PASS:?set ARMORY_DB_PASS}
|
||||
ACORE_ARMORY_REALMS__0__CHARACTERS_DATABASE__DATABASE: ${ARMORY_CHARACTERS_DB:-acore_characters}
|
||||
|
||||
# --- world database -------------------------------------------------
|
||||
ACORE_ARMORY_WORLD_DATABASE__HOST: ${ARMORY_DB_HOST:-192.168.1.60}
|
||||
ACORE_ARMORY_WORLD_DATABASE__PORT: ${ARMORY_DB_PORT:-3306}
|
||||
ACORE_ARMORY_WORLD_DATABASE__USER: ${ARMORY_DB_USER:?set ARMORY_DB_USER}
|
||||
ACORE_ARMORY_WORLD_DATABASE__PASSWORD: ${ARMORY_DB_PASS:?set ARMORY_DB_PASS}
|
||||
ACORE_ARMORY_WORLD_DATABASE__DATABASE: ${ARMORY_WORLD_DB:-acore_world}
|
||||
|
||||
ACORE_ARMORY_DB_QUERY_TIMEOUT: ${ARMORY_DB_TIMEOUT:-10000}
|
||||
|
||||
volumes:
|
||||
# The 3D model payload, extracted from the release archive. These
|
||||
# four directories are exactly the top level of data.tar.gz.
|
||||
- ${ARMORY_DATA_DIR:-/opt/mythica-armory/data}/meta:/data/meta
|
||||
- ${ARMORY_DATA_DIR:-/opt/mythica-armory/data}/bone:/data/bone
|
||||
- ${ARMORY_DATA_DIR:-/opt/mythica-armory/data}/mo3:/data/mo3
|
||||
- ${ARMORY_DATA_DIR:-/opt/mythica-armory/data}/textures:/data/textures
|
||||
- ${ARMORY_LOG_DIR:-/opt/mythica-armory/logs}:/logs
|
||||
|
||||
ports:
|
||||
- "${ARMORY_PORT:-48733}:48733"
|
||||
129
docs/mythica-deploy.md
Normal file
129
docs/mythica-deploy.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Deploying the armory on Nox
|
||||
|
||||
This fork of [r-o-b-o-t-o/azerothcore-armory](https://github.com/r-o-b-o-t-o/azerothcore-armory)
|
||||
(MIT) is set up to run as a Portainer stack on Nox, alongside the Mythica web
|
||||
page, reading the AzerothCore databases on the game server over the LAN.
|
||||
|
||||
**It must not run on the AzerothCore VM (192.168.1.60).** That box is tuned for
|
||||
the playerbot load; anything extra there means redoing that balancing. Nothing
|
||||
in this procedure touches the game server — the armory only reads its databases.
|
||||
|
||||
---
|
||||
|
||||
## Why the model data is a manual step
|
||||
|
||||
The armory needs about 2 GB of processed 3D model data — bone sets, mo3 meshes,
|
||||
textures, and the per-race character descriptors.
|
||||
|
||||
Upstream ships a `fetchdata` tool that downloads this from Zam's CDN. **It no
|
||||
longer works.** Zam reorganised that part of the CDN, and every character path
|
||||
now 404s (`meta/character/*`, `meta/charactercustomization2/*` — checked against
|
||||
the `live`, `wrath` and `classic` prefixes and several filename variants). The
|
||||
armor and item paths still resolve, so a run appears to succeed while silently
|
||||
producing no character data, and the app then fails at startup on
|
||||
`data/meta/charactercustomization2/1_0.json`.
|
||||
|
||||
The only remaining source is the snapshot in upstream's v1.0.0 release. That
|
||||
snapshot is mirrored into this fork's own release so the fork does not depend on
|
||||
GitHub staying up for the one piece that cannot be regenerated.
|
||||
|
||||
The mirrored copy is **split into five parts** because Nginx Proxy Manager in
|
||||
front of the forge rejects request bodies at that size (500 MB uploads fine,
|
||||
2 GB returns 413). Raising `client_max_body_size` on the forge's proxy host
|
||||
would let it be stored as a single file, if that is ever worth doing.
|
||||
|
||||
---
|
||||
|
||||
## 1. Put the model data on Nox
|
||||
|
||||
Once. Redeploying the stack does not disturb it.
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/mythica-armory/data /opt/mythica-armory/logs
|
||||
cd /opt/mythica-armory/data
|
||||
|
||||
BASE=https://gitlab.hallsworth.ca/yrtria/azerothcore-armory/releases/download/v1.0.0
|
||||
for i in 0 1 2 3 4; do curl -LO $BASE/data.tar.gz.part-$i; done
|
||||
curl -LO $BASE/SHA256SUMS.txt
|
||||
|
||||
cat data.tar.gz.part-* > data.tar.gz
|
||||
sha256sum -c --ignore-missing SHA256SUMS.txt # data.tar.gz must say OK
|
||||
|
||||
tar xzf data.tar.gz
|
||||
rm -f data.tar.gz data.tar.gz.part-*
|
||||
```
|
||||
|
||||
Afterwards `/opt/mythica-armory/data` holds four directories — `meta`, `bone`,
|
||||
`mo3`, `textures` — totalling roughly 2.5 GB unpacked.
|
||||
|
||||
The DBC `.csv` files are **not** part of this. They are committed to the repo and
|
||||
travel in the image, so they stay in step with the code.
|
||||
|
||||
> `data.tar.gz.UPSTREAM-GITHUB-LINK.txt` on the same release is not the archive.
|
||||
> It is the original external reference Forgejo recorded during migration — a
|
||||
> short-lived signed GitHub URL, kept only for provenance.
|
||||
|
||||
## 2. Create the Portainer stack
|
||||
|
||||
Repository stack, same pattern as `wow-web-page`:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Repository URL | `https://gitlab.hallsworth.ca/yrtria/azerothcore-armory.git` |
|
||||
| Reference | `refs/heads/master` |
|
||||
| Compose path | `docker-compose.mythica.yml` |
|
||||
|
||||
Environment variables — `ARMORY_DB_USER` and `ARMORY_DB_PASS` are required and
|
||||
the stack refuses to start without them:
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `ARMORY_DB_USER` | database user (see §4) |
|
||||
| `ARMORY_DB_PASS` | its password |
|
||||
| `ARMORY_DB_HOST` | `192.168.1.60` |
|
||||
| `ARMORY_WEBSITE_URL` | `https://armory.dionysismedia.ca` once proxied, otherwise `http://192.168.1.77:48733` |
|
||||
| `ARMORY_WEBSITE_NAME` | `Mythica` |
|
||||
| `ARMORY_REALM_ID` | `1` |
|
||||
| `ARMORY_DATA_DIR` | `/opt/mythica-armory/data` |
|
||||
| `ARMORY_LOG_DIR` | `/opt/mythica-armory/logs` |
|
||||
|
||||
The first build compiles TypeScript, so it takes a few minutes. It listens on
|
||||
48733.
|
||||
|
||||
## 3. Reverse proxy
|
||||
|
||||
Add a proxy host in NPM pointing at `192.168.1.77:48733`.
|
||||
|
||||
To embed it in the main site instead of giving it its own subdomain, set
|
||||
`ARMORY_IFRAME_ENABLED=1` and `ARMORY_IFRAME_URL` to the page that hosts the
|
||||
iframe, then use the snippet in the upstream README. That path keeps the site's
|
||||
own header and navigation around it.
|
||||
|
||||
## 4. Database access
|
||||
|
||||
`acore` is already granted from `192.168.1.%` and MySQL on the game server binds
|
||||
`0.0.0.0`, so this works with no changes. But the armory only ever reads, and it
|
||||
is public-facing, so a dedicated read-only user is worth the two minutes:
|
||||
|
||||
```sql
|
||||
CREATE USER 'armory'@'192.168.1.%' IDENTIFIED BY '<password>';
|
||||
GRANT SELECT ON acore_characters.* TO 'armory'@'192.168.1.%';
|
||||
GRANT SELECT ON acore_world.* TO 'armory'@'192.168.1.%';
|
||||
GRANT SELECT ON acore_auth.* TO 'armory'@'192.168.1.%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
## 5. Things to know
|
||||
|
||||
- **Item icons and tooltips come from a third-party AoWoW instance**
|
||||
(`wowgaming.altervista.org` by default) — they are hotlinked, so they break if
|
||||
that site moves or goes down. Point `ARMORY_AOWOW_URL` at your own AoWoW to
|
||||
remove that dependency. This is the one remaining external asset dependency;
|
||||
the model data is now self-hosted.
|
||||
- **The armory has its own talent view** with dual-spec support, which overlaps
|
||||
the talent page already in `WoW-Web-Page`. Decide which one owns the character
|
||||
page rather than shipping both.
|
||||
- **The Dockerfile builds from `node:16`**, which is end-of-life. It builds and
|
||||
runs fine; bumping it is a separate change from getting this deployed.
|
||||
- **`hideGameMasters` defaults to on** here, so GM characters are hidden from
|
||||
search and return 404.
|
||||
Loading…
Add table
Add a link
Reference in a new issue