Self-hosted · Free · EN/FR
A self-hosted app that runs the whole LAN weekend — invites, brackets, shared costs, photos — from a Raspberry Pi in the corner of the room. Your server, your data, your crew.
Every module can be switched off from the admin settings, so the app stays exactly as big as your LAN.
Per-event invite codes, shareable as a QR and revocable any time. RSVP dates feed everything else.
Single-elimination brackets and round-robins, team or solo, for any game — scores in, standings out.
Log what was spent; everyone pays pro-rata for the nights they actually stayed. Exportable.
Photos and clips in one shared gallery, with emoji reactions and video thumbnails.
A token-authorized projector page: live matches, standings, arrivals, photo wall, trophy ceremonies.
Propose time blocks, let the crew vote, lock the schedule. The kiosk counts down to the next one.
Embed the crew's channels and clips, with live status and viewer counts from the Helix API.
One-click sign-in and announcements pushed to your server — LPM works with Discord, not against it.
Who brings the switch, who brings the projector — pledges, open requests, and last edition's kit pre-checked.
A shared shopping list per event, so the fridge matches twelve people's plans.
Crew-defined awards, by vote or by decree, revealed one by one on the projector.
After the weekend: results, best-of photos, badges and numbers on one page, with a share link.
Twenty-nine features ship in total — packing checklists, a hype chat, mini-games, sponsors and prizes among them. The README lists them all.
Build a single-elimination bracket or a round-robin in a minute, team or solo. Report a score from any phone; the next round and the standings follow on their own.
Log the rent, the food runs, the pizza order. LPM splits the total by person-nights, straight from everyone's RSVP dates — no spreadsheet, no "we'll sort it out later".
One URL on the projector, authorized by a revocable token — no personal login on a shared screen. It rotates through live matches, standings, arrivals and the photo wall, and interrupts itself for what matters: a champion, a trophy, a fresh photo.
Copy the file below — it pulls both images from Docker Hub.
Skip it and LPM generates one on first start — or put your own random 32+ character string in a .env file next to it.
Run docker compose up -d. The first account created becomes admin; everyone else joins with an invite code.
services:
backend:
image: crosswax/lanpartymanager-backend:latest
# No ports: — the frontend's Nginx reaches it over the Docker network.
volumes:
- ./data:/app/data # SQLite database (persisted)
- ./uploads:/app/uploads # Avatars, media, video thumbnails (persisted)
environment:
SECRET_KEY: ${SECRET_KEY:-} # optional, from .env (step 2)
DATABASE_URL: sqlite:///./data/lanparty.db
UPLOAD_DIR: /app/uploads
restart: unless-stopped
frontend:
image: crosswax/lanpartymanager-frontend:latest
ports:
- "3001:80"
environment:
# Where your reverse proxy (Nginx Proxy Manager, Caddy…) connects from.
# The default covers a proxy running in Docker on the same host.
LPM_TRUSTED_PROXIES: "172.16.0.0/12"
volumes:
- ./uploads:/app/uploads # Nginx serves uploads directly
depends_on:
- backend
restart: unless-stopped
services:
backend:
# https://hub.docker.com/r/crosswax/lanpartymanager-backend
image: crosswax/lanpartymanager-backend:latest
# No ports: — the frontend's Nginx reaches it over the Docker network.
volumes:
- ./data:/app/data # SQLite database (persisted)
- ./uploads:/app/uploads # Avatars, media, video thumbnails (persisted)
environment:
# Empty: the backend generates a random key on first start and keeps
# it in ./data/secret_key. Never paste an example value here.
SECRET_KEY: ""
DATABASE_URL: sqlite:///./data/lanparty.db
UPLOAD_DIR: /app/uploads
restart: unless-stopped
frontend:
# https://hub.docker.com/r/crosswax/lanpartymanager-frontend
image: crosswax/lanpartymanager-frontend:latest
ports:
- "3001:80"
environment:
# Where your reverse proxy (Nginx Proxy Manager, Caddy…) connects from.
# The default covers a proxy running in Docker on the same host.
LPM_TRUSTED_PROXIES: "172.16.0.0/12"
volumes:
- ./uploads:/app/uploads # Nginx serves uploads directly
depends_on:
- backend
restart: unless-stopped
Then docker compose up -d — the app answers on port 3001.
Paste as a Portainer stack. Use literal values there: Portainer resolves ${VAR:-default} to an empty string.
An optional Windows client that wraps your instance: native notifications when a match is called or an announcement drops, and automatic League of Legends stats captured during the LAN. Same app, same server, zero extra setup for the crew.
LAN Party Manager (LPM) is a free, self-hosted web app for organizing LAN parties. It gathers everything a crew needs in one place — invites and RSVPs, tournament brackets, pro-rata cost splitting, Twitch streams, a shared photo vault and a big-screen kiosk — and runs on your own machine or a Raspberry Pi with Docker. It's available in English and French, with an optional Windows desktop app.
Yes. No subscription, no paid tier, no account to create with anyone. You run it on your own machine — the only bill is your electricity.
Any machine with Docker: a laptop, a spare PC or a Raspberry Pi 4/5. Images are published for amd64 and arm64, and SQLite means there is no database server to set up.
On your box: a SQLite file and an uploads folder. Nothing is sent anywhere — there is no telemetry. Download a full backup (database + uploads) from the Settings page whenever you like, and restore it in one click.
No — it's a web app, so any phone or laptop browser will do. Windows players can also grab the optional desktop app for native notifications and League of Legends stats.
The app itself runs on your own network. The optional integrations — Discord, Twitch, email, Steam — reach their services over the internet when you turn them on.
Only people you invite. The first account becomes admin; every sign-up after that needs a per-event invite code, which you can share as a QR code and revoke at any time.
Yes. Most modules — chat, planning, gear, prizes, sponsors, mini-games, kiosk, recap and more — are switched on or off from the admin settings, so the app stays as simple as your LAN.
A spreadsheet and a Discord server each cover one piece of a LAN; LPM connects them. RSVP dates feed the pro-rata split, tournament results feed the Hall of Fame and the recap, and the kiosk shows it all on the big screen — nothing is copied by hand. Discord stays useful: LPM can post your announcements there and lets players sign in with it.
Any game. Tournaments, planning and the game library don't depend on a particular title — run a bracket for CS, Rocket League, Smash Bros or anything else. League of Legends also gets automatic stats through the desktop app, and the built-in arcade ships with Neon Survivor.
Please ask the same question to the Home Assistant, Uptime Kuma or Jellyfin folks. LPM was designed around our crew of ten friends, not a 250-seat giant-whale LAN. At that scale SQLite is the serious choice: nothing to administer, and a backup is a file copy.
We've been throwing LAN parties since 2015, and LPM's origins go back to 2019, when I was learning Ruby on Rails and our weekends were turning into Spreadsheet Simulator. So yes — Claude Code sped things up immensely since I got my account in July, and brought that vision to life in no time for an MVP at our October LAN. Hint: this landing page is vibecoded too. I use VS Code every day for work and I don't give a damn about visiting its website. Sorry, but I couldn't afford 200 hours aligning divs and tuning paddings — I'd rather put them into LPM's ~90 commits, QA and features. 😉
AGPL-3.0. The full source is on GitHub since 1.3.3 — versions up to 1.3.2 stayed in private testing while I cleaned up the ancient backend spaghetti. Run it, fork it, improve it: if you serve a modified version to your crew, share the changes. That's the deal.
Not anymore. It did at first — easier for dev and testing. Since 1.3.3, the backend runs as an unprivileged lpm user: the container starts as root just long enough to hand data/ and uploads/ over, then drops privileges for good. Existing installs switch over on their own at first start, no command to run.
Mostly ffmpeg. The Python app itself is a few megabytes; the rest is the Python 3.11 base image, Pillow's imaging libraries and a full ffmpeg build — the thing that turns your crew's clips into gallery thumbnails on your own box, no external service involved. Your weekend's pizza photos will outweigh it by Saturday night anyway.
// Your server is already good enough
Two Docker images, one compose file, ten minutes. The first RSVP can land tonight.