Installation via Docker
The central repository provides two complete Compose files:
- compose.yaml uses the API and web images from GitHub Container Registry.
- dev.compose.yaml builds their Dockerfiles from sibling API and web checkouts.
Both work without a .env file, use the same storage and initialise the API automatically. Use one at a time. These defaults require an API image containing the automatic setup changes; this local work has not published a new image. Use the development Compose file to try the current source immediately.
Start the application
Section titled “Start the application”For published images, from app-tcg-set-designer:
docker compose up -d --waitFor the current source, with both sibling repos available:
docker compose -f dev.compose.yaml up --build -d --waitThe development file builds production containers from local source; it does not mount source code or enable hot reload. Use the host development commands for editing with hot reload.
Startup runs registered database migrations, adds missing reference data and creates an administrator only when no users exist. Its username, email and random password are saved in .tcgsd/database/initial-admin.json. Read that file on the host and sign in at http://localhost:5000. The default username is admin; the password is unique to the installation. The API is at http://localhost:15100.
A private JWT signing key is generated in .tcgsd/database/jwt-secret. Both files persist across container replacement. Existing users, passwords and role grants are retained, and credentials are not printed in container logs. Protect the data directory with your host’s file permissions. The credentials file records the initial password only; removing it after securely storing the credentials does not reset the account.
The frontend waits for the API’s health check before starting. Inspect startup with docker compose logs backend, or add -f dev.compose.yaml when using the source build.
Optional settings
Section titled “Optional settings”No values are required in .env. Add only overrides you need, either there or in the shell:
| Variable | Default | Purpose |
|---|---|---|
API_IMAGE_TAG, WEB_IMAGE_TAG |
latest |
Independent registry image tags; use development for ongoing main-branch builds |
BIND_ADDRESS |
127.0.0.1 |
Host interface for published ports |
API_PORT |
15100 |
Host API port; the container still listens on 15100 |
WEB_PORT |
5000 |
Host web port |
PUBLIC_API_URL |
http://localhost:<API_PORT> |
API origin reached by the browser |
TCGSD_DATA_PATH |
./.tcgsd |
Host storage root |
AUTO_SETUP |
true |
Automatic migrations, missing reference data and first administrator |
INITIAL_ADMIN_USERNAME |
admin |
Username for a fresh installation only |
INITIAL_ADMIN_EMAIL |
admin@localhost.test |
Initial account’s placeholder email; override before first start if desired |
JWT_SECRET_KEY |
Empty: generate and persist | Optional private signing key of at least 32 characters; JWT_SECRET is an alias |
Changing initial admin settings after an account exists does not reset it. AUTO_SETUP=false enables the manual migration/account workflow described in the persistent installation guide. A supplied invalid signing key is rejected.
Private GHCR packages require registry authentication and repository/package access. latest follows stable GitHub Releases, while development follows successful main builds. API and web versions are independent. An example optional .env for development images is:
API_IMAGE_TAG=developmentWEB_IMAGE_TAG=developmentStorage, upgrades and recovery
Section titled “Storage, upgrades and recovery”Keep .tcgsd/database, .tcgsd/templates, .tcgsd/webhooks and .tcgsd/backups when replacing containers. The database directory also holds the generated signing key and initial credentials. Extract template ZIPs into their own directories beneath .tcgsd/templates.
Create a checked SQLite backup using a new output filename each time:
docker compose run --rm --no-deps backend npm run db:backup -- --output /backups/project-backup.sqliteFor local builds, add -f dev.compose.yaml to that command. Back up template/webhook files, database assets and the signing key separately. Stop the API when taking a coordinated backup of all those files.
Before upgrades, retain your current version and take backups. Stop the services, pull the new images (or rebuild local source), then start them. Automatic setup saves a checked database snapshot before applying pending migrations to an existing recognised database. Unknown schemas, incompatible migration history and old demo passwords still stop startup. Existing role grants are preserved and may need review after upgrades.
The persistent installation guide covers manual setup, restore into a new directory, password reset, signing-key rotation and stale-lock recovery. Never run older schema-synchronising API versions against an upgraded database.
Network access and HTTPS
Section titled “Network access and HTTPS”The defaults publish ports only on localhost. For shared access, configure a reverse proxy with TLS for both the frontend and API, and set PUBLIC_API_URL=https://api.your-domain.example. Recreate the frontend after changing it. This must be a browser-reachable origin, not the Docker service name.
Compose passes only this public value to the web image as API_URL; the web container writes it to runtime-config.json without modifying compiled JavaScript. The signing key belongs only to the backend. Remove the old APP_ENV_PREFIX and VITE_BACKEND_NETWORK_HOSTNAME/PORT settings. See web configuration.