World Cup Pool is a self-hosted World Cup 2026 prediction game for friends, families, teams, and communities. Players predict the full tournament, submit match tips, and compete in private leagues with live standings.
The app ships as one Docker image: a Go/PocketBase backend serving the API and an embedded SvelteKit frontend from the same port.
This project is based on floholz/wm-pickems and remains licensed under GPL-3.0. The public repo is maintained as World Cup Pool for easier self-hosting and community use.
Some internal binary, container, and module names still use wm-pickems for
backwards compatibility with existing deployments.
- Match tips for every World Cup 2026 match, editable until kickoff.
- Full-tournament predictions: groups, best thirds, knockout bracket, and winner.
- Private leagues with invite codes and shareable join links.
- Global league, leaderboard breakdowns, and tiebreaker details.
- Built-in search for matches, teams, groups, and leagues.
- English/Nynorsk language toggle plus light/dark theming.
- League progress and points trend views to follow score changes over time.
- League chat, friend tip visibility after kickoff, and forecast detail views.
- Admin result override and scoring recompute endpoints.
- Optional Google OAuth, email/password auth, password reset, avatars, and PWA install.
- Results can come from openfootball data, API-Football, or manual admin updates.
git clone https://github.com/oyvhov/world-cup-pool.git
cd world-cup-pool
cp .env.example .envEdit .env before running:
- Set
PB_ADMIN_EMAILandPB_ADMIN_PASSWORDto your own admin credentials. - Leave
API_FOOTBALL_KEYempty unless you have a usable API-Football key. - Leave Google OAuth fields empty unless you want Google sign-in.
- Keep
WMP_DEV=0for normal deployments.
Start the app:
docker compose up --build -dOpen:
- App:
http://localhost:8090 - PocketBase admin UI:
http://localhost:8090/_/
Create a superuser if you did not bootstrap one from .env:
docker compose exec app wm-pickems superuser create you@example.com 'a-strong-password' --dir=/pb_datamake install
make dev-backend
make dev-frontendThe frontend dev server proxies API calls to the local backend.
Run checks:
make test
cd frontend && npm run checkRun the isolated Docker test app:
.\scripts\start-test.ps1 -Port 8091This uses a separate test container and volume from production.
Use .env.example as the template for local configuration. Never commit a real
.env file, API key, OAuth secret, password, backup archive, or PocketBase data.
Important environment variables:
| Variable | Required | Notes |
|---|---|---|
HTTP_PORT |
no | Host port for Docker, defaults to 8090. |
WMP_DEV |
no | Set 1 only for local simulation tools. |
RESULTS_SOURCE |
no | auto, openfootball, or apifootball. |
API_FOOTBALL_KEY |
no | Optional external result API key. |
ODDS_API_KEY |
no | Optional The Odds API key for bookmaker odds on upcoming matches. |
PB_ADMIN_EMAIL |
no | Optional initial PocketBase admin email. |
PB_ADMIN_PASSWORD |
no | Optional initial PocketBase admin password. |
GOOGLE_CLIENT_ID |
no | Optional Google OAuth client ID. |
GOOGLE_CLIENT_SECRET |
no | Optional Google OAuth secret. |
Match tips can score up to 6 points:
| Rule | Points |
|---|---|
| Correct result or knockout advancer | 3 |
| Exact score | +1 |
| Correct total goals | +1 |
| Correct goal difference | +1 |
Tournament predictions score group placements, perfect groups, advancing teams,
knockout reach, finalists, and champion picks. The scoring weights live in the
PocketBase scoring_configs records and can be changed without a redeploy.
- Full deployment guide: DEPLOY.md
- Backup and restore notes: BACKUP.md
- Local production/test workflow notes: Prod_guide.md
- Public onboarding: GETTING_STARTED.md
- Contributing: CONTRIBUTING.md
- Fixtures and initial tournament structure are seeded from openfootball data.
- Live results can be synced from API-Football when configured.
- Upcoming match odds sync from The Odds API when
ODDS_API_KEYis configured; otherwise the app shows FIFA-ranking-based probabilities. - Results can always be entered or corrected manually by an admin.
Before publishing or deploying your own instance:
- Keep
.envprivate. - Use your own strong admin password.
- Rotate any credentials that were ever accidentally shared.
- Do not commit
pb_data, backup archives, SQLite databases, DPAPI blobs, logs, or production snapshots. - Run a secret scanner such as Gitleaks before pushing a public release.
GPL-3.0. See LICENSE.


