iRaceHub is a production-ready league management platform for iRacing communities.
It includes:
- league, series, and season management
- schedule and race session syncing from iRacing
- results import and editing
- standings and widgets for external sites
- virtual money, team bank, and registration fee support
- self-hosted deployment with Docker, Nginx, or Caddy
iRaceHub is open source and intended to be self-hostable by the iRacing community.
- Repository: https://github.com/DarrellRichards/iracehub
- License: MIT
- Contributions: see CONTRIBUTING.md
- Security reporting: see SECURITY.md
- Node.js 20+
- PostgreSQL
- iRacing API credentials
Copy the development template and update the values:
cp .env.example .env.localFirst, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun devOpen http://localhost:2300 with your browser to see the result.
In a separate shell, generate Prisma artifacts and run migrations as needed:
npx prisma generate
npx prisma migrate devRun the project checks locally before opening a pull request:
npm run lint
npm run typecheck
npm run test
npm run buildYou can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
The production app is designed for league owners who want to run iRaceHub on their own infrastructure.
Typical production flow:
- Host PostgreSQL locally or from a managed provider.
- Set production environment variables in
.env.production. - Build and run the app with Docker.
- Put Nginx or Caddy in front of the app.
- Point your domain to the server and run Prisma migrations.
Once deployed, users access:
- the main marketing site
- driver dashboard
- league landing pages
- admin tools
- widgets via public API routes
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Issues and pull requests are welcome.
- Start with CONTRIBUTING.md
- Be sure not to commit secrets from
.env.localor.env.production - Include schema migrations with Prisma model changes
- GitHub issue and pull request templates are included for contributors
You can consume league data for external widgets/apps via:
GET /api/widgets/leagues/:leagueId
Where :leagueId can be either the app league id or numeric iRacing league id.
This endpoint is public and includes CORS headers for browser-based integrations.
upcomingEventlatestRaceResultsstandingsUpdateschedule
standingsLimit(default10, max50)scheduleLimit(default12, max50)resultsLimit(default20, max100)view(all,upcoming,results,standings,schedule)theme(light,dark)accent(hex color, e.g.#ef4444)bg(hex color ortransparent)text(hex color)border(hex color)compact(trueorfalse) for compact standings/results tables
curl "http://localhost:2300/api/widgets/leagues/12345?standingsLimit=10&scheduleLimit=8&resultsLimit=15"Drop this on any site/app page:
<div id="irh-widget"></div>
<script
src="http://localhost:2300/api/widgets/leagues/12345/embed?standingsLimit=10&scheduleLimit=8&resultsLimit=10&view=all&theme=dark&accent=%23ef4444&bg=%230f172a&text=%23e5e7eb&border=%23334155"
data-target="#irh-widget"
></script>If data-target is omitted, the widget renders directly below the script tag.
You can also render one standalone widget section by changing view to upcoming, results, standings, or schedule.
- If a league has private schedule enabled,
upcomingEventandscheduleare hidden. - If a league has private results enabled,
latestRaceResultsandstandingsUpdateare hidden.
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
You can run iRaceHub on your own VPS, bare-metal server, or cloud VM with Docker.
app: the Next.js production containernginxorcaddy: reverse proxy in front of the app
The app listens internally on port 2300.
This repo supports production deployment via Docker with either Nginx or Caddy as a reverse proxy.
- Linux server or VPS
- Docker and Docker Compose
- reachable public DNS if using HTTPS with Caddy
- PostgreSQL database (compose-managed by default in this repo)
Recommended minimum:
- 2 CPU
- 2 GB RAM
- 20 GB disk
Copy the template and set real values:
cp .env.production.example .env.productionRequired variables:
DATABASE_URLPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDIRACING_CLIENT_SECRETNEXT_PUBLIC_APP_URL(must match your public HTTPS URL)
Optional:
IRACING_CLIENT_ID
Example:
DATABASE_URL=postgresql://iracehub:replace_me@postgres:5432/iracehub
POSTGRES_DB=iracehub
POSTGRES_USER=iracehub
POSTGRES_PASSWORD=replace_me
IRACING_CLIENT_ID=your-client-id
IRACING_CLIENT_SECRET=your-client-secret
NEXT_PUBLIC_APP_URL=https://iracehub.yourdomain.comDATABASE_URL host must be reachable from inside the app container. For the compose-managed DB, use postgres as the host.
If using external Postgres, replace DATABASE_URL with your external host details.
If you just want to confirm the production container works before adding a proxy:
docker build -t iracehub .
docker run --rm -p 2300:2300 --env-file .env.production iracehubThen open http://your-server-ip:2300.
Starts app + Nginx on port 80:
docker compose -f docker-compose.nginx.yml up -d --buildNginx config lives at deploy/nginx/default.conf.
Use Nginx when:
- you already terminate TLS elsewhere
- you want a simple HTTP reverse proxy in front of Docker
Set your domain and start app + Caddy:
DOMAIN=your-domain.com docker compose -f docker-compose.caddy.yml up -d --buildCaddy config lives at deploy/caddy/Caddyfile and will automatically manage TLS certificates.
Use Caddy when:
- you want automatic HTTPS
- you want the simplest self-managed public deployment
Run migrations against your production DB after deployment:
docker compose -f docker-compose.nginx.yml exec app prisma migrate deploy --schema prisma/schema.prismaIf using Caddy stack, run:
docker compose -f docker-compose.caddy.yml exec app prisma migrate deploy --schema prisma/schema.prismaView logs:
docker compose -f docker-compose.nginx.yml logs -fRebuild/restart:
docker compose -f docker-compose.nginx.yml up -d --buildStop stack:
docker compose -f docker-compose.nginx.yml downPull the latest code and rebuild:
git pull
docker compose -f docker-compose.nginx.yml up -d --build
docker compose -f docker-compose.nginx.yml exec app prisma migrate deploy --schema prisma/schema.prisma- set a real
NEXT_PUBLIC_APP_URL - run behind HTTPS
- use a managed PostgreSQL backup strategy
- keep
.env.productionout of version control - run
prisma migrate deployafter each schema change - monitor Docker logs after deploys
If you discover a vulnerability, please follow SECURITY.md instead of opening a public issue.
Released under the MIT License.