Skip to content

Docker

Ritual can be run inside a Docker container. This is particularly useful for self-hosting the static site generator and cache server. The provided Dockerfile uses Alpine Linux and uses the CLI as its entrypoint, so you can run any command directly by passing it to docker run or in your docker-compose.yml.

Use the provided script so the image build always injects GIT_VERSION from the current git ref:

Terminal window
sh scripts/build-docker.sh

By default it builds ghcr.io/sloshy/ritual:<git-ref>. You can override image/tag, and optionally push:

Terminal window
IMAGE=ghcr.io/<owner>/ritual TAG=v1.2.3 PUSH=true sh scripts/build-docker.sh

If git metadata is unavailable, the script falls back to a short commit SHA, then unknown.

This docker-compose.yml example shows an example of running the cache server command, which starts the cache server with some common options:

services:
ritual:
image: ritual
build: .
ports:
- '3000:3000'
volumes:
- ./dist:/app/dist
- ./decks:/app/decks
- ./collections:/app/collections
- ./cache:/app/cache
- ./.logins:/app/.logins
command: cache server --host 0.0.0.0 --port 4000 --verbose --cards-refresh weekly --prices-refresh weekly

Hosting the public site with a live backend

Section titled “Hosting the public site with a live backend”

To self-host the hosted public site — live list data plus cache-backed card search — run serve --api instead, mounting the list directories and a pre-populated cache:

services:
ritual:
image: ritual
build: .
ports:
- '3000:3000'
volumes:
- ./dist:/app/dist
- ./decks:/app/decks
- ./collections:/app/collections
- ./wanted:/app/wanted
- ./cache:/app/cache
command: serve --api --host 0.0.0.0 --port 3000 --refresh never

--refresh never stops the container from downloading Scryfall’s bulk data on startup — under the default ask, an empty or week-old cache is bulk-downloaded without prompting. So populate the cache first with ritual cache preload-all, or point the container at a shared cache server with --cache-server. An empty dist/ mount is fine: --api builds the site on startup when there is none — but that build needs card data, so with --refresh never and an empty cache it fails and the container exits 1. Add --build to rebuild the site on every start. --refresh never also opts out of the startup buylist refresh (which only runs when sell mode is enabled at all), so a long-lived container’s sell mode quotes the feed it started with until you refresh it from the admin site or a CLI run.

To ensure persistence and allow you to interact with the files Ritual uses, you should mount the following directories:

Host DirectoryContainer DirectoryPurpose
./dist/app/distThe generated static website files.
./decks/app/decksYour Magic: The Gathering deck files (.md).
./collections/app/collectionsYour card collection files.
./cache/app/cacheCached card data and images from Scryfall.
./.logins/app/.loginsAuthentication tokens for sites like Archidekt.