Skip to content

Run from source

Running from source is the usual path for development, for reading the code alongside a live server, and for any deployment that wants to build its own image.

Prerequisites: Bun v1.3 or newer, and a database you can reach: MongoDB or PostgreSQL, whichever you would rather run.

  1. Clone and install:

    Terminal window
    git clone https://github.com/RedFox-Soft/OAuth-server.ts.git
    cd OAuth-server.ts
    bun install
  2. Create a .env file with the required variables:

    ISSUER=http://localhost:3000
    MONGODB_URI=mongodb://localhost:27017
    DATABASE_NAME=OAuth

    For PostgreSQL instead, set POSTGRES_URL and leave the other two out. The database name is part of that URL, so DATABASE_NAME is unused:

    ISSUER=http://localhost:3000
    POSTGRES_URL=postgres://user:password@localhost:5432/oauth

    Set both connection strings and the server refuses to start instead of picking one; see PostgreSQL. Bun loads .env automatically; nothing else needs configuring. Each variable is described in the environment variables reference. ISSUER is the canonical public URL of this server: the iss of every token, the base of every endpoint in discovery, and the redirect target of the admin console client — so set it to its final value before the next step.

  3. Provision the database:

    Terminal window
    bun run db:setup # MongoDB
    bun run db:setup:pg # PostgreSQL
  4. Bundle the console and the sign-in screens into public/:

    Terminal window
    bun run build
  5. Start the server:

    Terminal window
    bun start

    It listens on port 3000. Open http://localhost:3000/admin for the console, or http://localhost:3000/.well-known/openid-configuration for the discovery document.

db:setup runs database/mongodb.ts against MONGODB_URI / DATABASE_NAME, and it is what turns an empty database into a working deployment:

  • Collections, one per storage area the server writes to.
  • Indexes: the TTL indexes that expire tokens, codes, sessions and interactions, and the unique e-mail index on each project’s end-user collection. It also drops stale expiry indexes left on collections that no longer write the field.
  • The initial RS256 signing key, stored with every issuer’s keys in the bucketKeys area, which is why keys are not an environment variable here. (If the server ever starts against an empty key store it generates and persists one itself.)
  • The admin panel seed: the reserved “Administrators” project with registration closed, the first-party admin-panel OAuth client whose redirect URI is $ISSUER/admin/callback, the reserved admin-mcp agent client, the System team that holds projects no administrator manages, and the default redfox end-user project.

It is idempotent: every write is an upsert or a create-if-absent, so running it again changes nothing that already exists. Re-run it after upgrading an existing install, since a release that adds a collection, an index or a seeded document applies it here and nowhere else. Then run bun run db:migrate, which applies whatever a release has to reshape, as opposed to merely add; the server refuses to start until it has. Some migrations cannot be undone, so take a backup when the release notes name one.

On PostgreSQL, bun run db:setup:pg does the same job with tables in place of collections. The only structural difference is expiry: PostgreSQL has no TTL index, so the running server sweeps expired rows itself. bun run db:migrate is the same command on either backend.

  • The admin console needs a database-backed deployment. Setting NODE_ENV=test swaps in the in-memory adapter, which does not persist the seed across restarts.
  • Server settings are read at boot from the config store, and a change saved in the console applies at once on the instance that saved it; other instances take it at their next restart. Every one of them is listed in the settings reference.