Updating
Every change merged into Playmat is published as new images within about ten minutes. Your server keeps running the version it started with until you update it, and an update keeps your accounts, stats, backups and settings.
Is there a new version?
Admin → Updates (admins and the owner) shows the version the server runs and whether a newer
one is out, with the list of changes. The Overview says so too. The server asks GitHub only when staff open
the console, at most once an hour; XMAGE_UPDATE_CHECK=off in .env turns that off.
Servers follow master, the newest build. Releases (vX.Y.Z, followed with the
latest tag) will be published with images as they come.
The Update button
With the updater running beside the server, the owner updates from Admin → Updates: Update to … installs the newest version, and Go back to … returns to the one before the last update. Turn it on once, from the folder you cloned:
git pull
echo COMPOSE_PROFILES=updater >> ops/web/.env
docker compose -f ops/web/docker-compose.yml --env-file ops/web/.env up -d
It needs a Linux host with Docker Engine. On Docker Desktop for Windows the section says it can't work there; update by hand instead.
What an update does
- Downloads the version's images and pins them by digest in
.env, so a laterup -druns the same thing. - Backs up the databases, next to the nightly backups.
- Warns players. With games running it announces maintenance and gives them up to 15 minutes to end (
UPDATER_DRAIN_MINUTES). - Restarts the server and web client on the new version, with the compose file that version came with.
- Waits for both to be healthy. If they aren't within 10 minutes (
UPDATER_HEALTH_TIMEOUT), it goes back to the version that ran before, by itself. - Updates the updater to the same version, and posts how it went to the staff Discord channel if one is set.
The section follows each step while it runs. The server restarts in the middle, so the page loses its connection for a minute: sign in again and the section shows the result, with the updater's log under Updater log. If your browser still has the old version of the page, it offers to reload.
What the updater can do
The updater is the one container with access to Docker, which amounts to root on the host. Turn it on only if you're comfortable with that.
- It has no network connection and listens on nothing. Docker itself does the downloading.
- The server asks it through files in a volume they share, and a request can only name a version. The images come from the updater's own settings, never from the request.
- Only the owner can ask, and each update or rollback is kept in the audit log.
To turn it off again, remove updater from COMPOSE_PROFILES and run
docker compose -f ops/web/docker-compose.yml --env-file ops/web/.env rm -sf updater.
Updating by hand
Without the updater, run these from the folder you cloned. With games running, announce maintenance in Admin → Settings first: the restart ends every game in progress.
git pull
docker compose -f ops/web/docker-compose.yml --env-file ops/web/.env pull xmage web
docker compose -f ops/web/docker-compose.yml --env-file ops/web/.env up -d --no-build
If .env names the images with a digest (…@sha256:…, the updater writes them that way),
set them back to :master first, or the pull keeps the same version. A server that was built from
the source (empty image lines) switches to the published images by setting
XMAGE_SERVER_IMAGE=ghcr.io/arcanite24/playmat-server:master and
XMAGE_WEB_IMAGE=ghcr.io/arcanite24/playmat-web:master; the Update button does that by itself on its
first update.
The AI's format decks
The web client ships 12 decks per supported format, mixing metagame snapshots with original rogue and casual lists. Home's Format deck mode deals different decks to you and the AI; random picks favor metagame share, but every list can be drawn.
Self-hosters get the pool with the web image. Custom builds keep its index and fetched deck files in
Mage.Web.Client/public/meta-decks/, outside the JavaScript bundle. Each index entry has a
tier of meta, rogue or fun and records its source.
When changing lists, run npm test in Mage.Web.Client to check card counts,
implemented printings, set legality, bans, restricted cards and copy limits against this checkout at the
pool's snapshot date. Commander lists must have one legendary creature commander and stay within its
color identity, derived from Java card definitions' mana symbols, mana abilities and color indicators
(including both faces). Pool checks also enforce distinct commanders, multiple color combinations and
at most 25 shared nonland cards between Commander lists. These static checks do not execute Java or
validate every special deck-building rule. With a local server, the optional
metaDecks.live.test.ts suite also checks the server's deck validation; its refresh mode
preserves original rogue and fun lists.
When something goes wrong
- “The updater isn't running.”
COMPOSE_PROFILES=updateris missing from.env, or theup -dafter adding it hasn't run.docker compose … logs updatershows what it saw at start. - An update failed and went back. The server runs what it ran before. The updater log says which step failed; the backup from step 2 is in the backups volume.
- A job looks stuck after the host rebooted mid-update. Start the stack with
up -d, check that it's healthy, and ask again.