Skip to content

Run your own instance

Runway is open source and self-hosted. You need Docker with Compose, a box your players’ phones can reach, and a domain name with a TLS certificate.

  1. Terminal window
    git clone https://github.com/Jessevdz/RunwayTheGame.git
  2. Terminal window
    cp .env.example .env
    Variable What to put in it
    RUNWAY_DB_PASSWORD Any strong password. Only the containers ever use it
    S3_ACCESS_KEY MinIO root username / S3 access key ID
    S3_SECRET_KEY The MinIO root password / S3 secret access key
    RUNWAY_WORKER_TOKEN Shared secret authenticating the background verification worker when submitting AI photo grading verdicts to the server
    RUNWAY_ROADMAP_ADMIN_KEY Secret key for roadmap and admin management
    S3_PUBLIC_ENDPOINT The browser-facing app URL, e.g. http://localhost locally or https://race.example.com in production. Evidence uploads should pass through the frontend proxy’s 50 MB limit.
    RUNWAY_ALLOWED_ORIGINS Comma-separated browser origins for the API and WebSocket (e.g. https://race.example.com). Leave empty locally for loopback/LAN origins
    SCALEWAY_API_KEY Optional: Scaleway API key to enable AI photo grading (or GEMINI_API_KEY for Google Gemini)

    Generate the secrets:

    Terminal window
    openssl rand -hex 32

    Everything else in the file has a working default.

  3. Configure reverse proxy or domain (optional)

    Section titled “Configure reverse proxy or domain (optional)”

    By default, docker-compose.yml publishes the frontend on port 80 (or FRONTEND_PORT in .env).

    Copy docker-compose.override.example.yml to docker-compose.override.yml:

    Terminal window
    cp docker-compose.override.example.yml docker-compose.override.yml

    Edit the frontend service labels in docker-compose.override.yml with your hostname and certificate resolver:

    - "traefik.http.routers.runway.rule=Host(`race.example.com`)"
    - "traefik.http.routers.runway.tls.certresolver=your-resolver"

    Docker Compose automatically applies docker-compose.override.yml, which is gitignored so your personal setup is never committed or overwritten during updates.

  4. Terminal window
    docker compose up -d --build

    Watch for all services healthy:

    Terminal window
    docker compose ps

The launchers offer the honour system and host grading out of the box, and both run entirely on your instance.

The AI referee needs SCALEWAY_API_KEY (or GEMINI_API_KEY) in your .env. The server is told a key exists and the worker is given the key itself, so the card appears in the launcher only when a backend can answer it. Cheap EXIF and GPS-velocity heuristics run first and reject some captures at zero API cost; everything past them goes to the model. Leave the key empty and the AI card stays hidden.

Terminal window
git pull
docker compose up -d --build

Two named volumes hold everything worth keeping: runway_db_data has the event log every race is replayed from, and runway_minio_data has the photos. Back up both together, since a photo whose row is gone is unreachable and a row whose photo is gone renders as a hole in the race report.