Skip to content
PeterLombaersPublic

About

Chess club competition management app

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Petlom

Self-Hosting

Prerequisites

  • Docker (Docker Desktop on Windows/Mac, or Docker Engine + Docker Compose v2 on Linux)
  • Ports 80 (and 443 for HTTPS) open on your server

Deploy

1. Get the code

git clone https://github.com/PeterLombaers/petlom.git
cd petlom

2. Create your configuration file

cp .env.example .env

Open .env and fill in JWT_SECRET_KEY with a randomly generated secret:

python -c "import secrets; print(secrets.token_hex(32))"

Paste the output as the value. The other settings have safe defaults for Docker deployments.

3. Start the application

docker compose up -d --build

The first run downloads base images and builds the containers — this takes a few minutes.

4. Create your moderator account (do this once)

docker compose exec backend uv run python -m backend.create_account <username> <password>

Replace <username> and <password> with your chosen credentials.

To hand someone result entry and nothing else, add --role result_keeper. They can fill in the results of a round, but cannot change pairings, players or competitions. See scripts/README.md.

5. Open the app

Go to http://localhost (or http://<your-server-ip> if running on a remote server).


Enable External Ratings (optional)

Player search against the FIDE and KNSB rating lists, and the rating import that goes with it, are disabled unless a chess_player_db instance is reachable. Without one those features answer 503 and the rest of the app is unaffected.

The rating database is never contacted by the browser — petlom's backend proxies the requests — so it does not need to be exposed to the internet. Run it on the same host and let the two containers talk over its compose network:

1. Start chess_player_db first (its network has to exist before petlom starts):

cd /path/to/chess_player_db
docker compose up -d

2. In petlom's .env, uncomment:

COMPOSE_FILE=docker-compose.yml:docker-compose.chessdb.yml

3. Start petlom as usual:

docker compose up -d --build

Without the COMPOSE_FILE line, pass the overlay by hand instead:

docker compose -f docker-compose.yml -f docker-compose.chessdb.yml up -d --build

Verify the connection:

docker compose exec backend uv run -c "import httpx; print(httpx.get('http://chess-player-db:8000/federations/').json())"

External search is moderator-only, so log in before the search field appears in the create-player dialog.


Enable HTTPS

Caddy automatically obtains and renews a TLS certificate from Let's Encrypt. No further configuration is needed. You only need to set the environment variable CADDY_HOST so that it knows for which domain to obtain the certificate.

Update ALLOWED_ORIGINS in .env if you use the development workflow against your production server.


Update

On the server:

git pull
docker compose build
docker compose up -d

Or, from a machine that can reach the server over SSH, with scripts/.env configured (see scripts/README.md):

scripts/deploy.sh --backup

That backs the database up first, then pulls, rebuilds, restarts, and checks the containers came back.

Note: Database schema changes are applied automatically when new tables are added, but existing tables are not altered. If a release adds columns to an existing table, a migration step will be documented in the release notes.


Database Backup

Copy the SQLite file out of the Docker volume without stopping the application. SQLite's online backup API gives a consistent snapshot even while the app is writing:

mkdir -p backups
docker compose exec -T backend uv run python -c "
import sqlite3
src = sqlite3.connect('/data/petlom.db')
dst = sqlite3.connect('/data/_backup.db')
with dst:
    src.backup(dst)
dst.close(); src.close()
"
docker compose exec -T backend cat /data/_backup.db > "backups/petlom-$(date +%Y%m%d-%H%M%S).db"
docker compose exec -T backend rm -f /data/_backup.db

From a machine with SSH access to the server, scripts/backup.sh does all of that and downloads the result — see scripts/README.md.

To restore, stop the stack, copy a backup back into the petlom_db volume as petlom.db, and start it again.


View Logs

docker compose logs -f
docker compose logs -f backend
docker compose logs -f caddy

Development

  • Start the backend server: uv run fastapi dev backend/main.py
  • Start the frontend server: cd frontend && npm install && npm run dev
  • (Optional) Fill the database with fake data: uv run python fill_db.py

The frontend dev server proxies all /api/* requests to the backend at http://localhost:8000, so both servers can run simultaneously without CORS issues.

There is a VSCode tasks file at https://gist.github.com/PeterLombaers/0f896b05ecdaba6ff718f815b323ce71 that you can use to run these commands. Simply add it to your .vscode folder, use Ctrl+Shift+p and select Tasks: Run Task.

TypeScript API Client

The TypeScript API client is generated using openapi-typescript. It uses the OpenAPI definition that FastAPI outputs to generate TypeScript types for the backend API. These types are located at frontend/src/client/schema.d.ts. You never need to manually edit this file — instead run npm run generate-client from the frontend directory, or use the corresponding VSCode Task.

About

Chess club competition management app

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages