# Install

Installing Vaubaan Gateway means running one Docker image, built from the repository, behind a TLS proxy, with one volume for its database and a configuration that names its public URL, its master key and who administers it.

**No image is published yet.** Releases will be published at `ghcr.io/vaubaan/gateway` with a signed provenance attestation; until the first one, both ways below build the image from the sources. How to pull and verify a released image, once one exists: [deploy README](https://github.com/vaubaan/gateway/blob/main/deploy/README.md#released-images).

## Two ways

- [Docker Compose](/docs/install/docker-compose) on a host you run, with the bundled Caddy proxy that obtains the TLS certificate.
- [Railway](/docs/install/railway): one service built from the repository's Dockerfile, one volume, GitHub sign-in.

Running the image with your own reverse proxy is described in the [deploy README](https://github.com/vaubaan/gateway/blob/main/deploy/README.md#running-the-image-without-compose).

## Requirements

- **A host** with Docker and Compose v2, or a Railway project. One process and one SQLite file: no database server, no high availability.
- **A DNS name** pointing at the host; its `https://` origin is the instance's public URL. With Compose, ports 80 and 443 must be reachable so the bundled proxy can obtain the certificate.
- **Node.js on the machine where you generate the master key** (`npm run gen-master-key` prints 32 random bytes in base64).
- **A sign-in provider**: an OpenID Connect client at your identity provider, or a GitHub OAuth App. The test suites sign in through a simulated provider; no real identity provider has been tried yet ([known limitations](/docs/known-limitations)). You can add it from the interface after the first sign-in, or put it in the configuration.
- **An admin rule**: the email addresses (`VAUBAAN_ADMIN_EMAILS`) or the identity provider group (`VAUBAAN_ADMIN_GROUP`) of the administrators.

## Minimum configuration

| Key                             | Variable                                      | What                                                                 |
| ------------------------------- | --------------------------------------------- | -------------------------------------------------------------------- |
| `public_url`                    | `VAUBAAN_PUBLIC_URL`                          | `https://` and the instance's host                                   |
| `store.path`                    | `VAUBAAN_STORE_PATH`                          | the database file on the volume, such as `/data/gateway.db`          |
| `encryption.master_key`         | `VAUBAAN_MASTER_KEY`                          | the output of `npm run gen-master-key`; keep a copy outside the host |
| `admin.emails` or `admin.group` | `VAUBAAN_ADMIN_EMAILS`, `VAUBAAN_ADMIN_GROUP` | who administers the instance                                         |
| `bootstrap_token`               | `VAUBAAN_BOOTSTRAP_TOKEN`                     | 32 characters or more, until a sign-in provider is set               |

Anything missing stops the container with exit code 78 and a message naming every key:

```
Invalid instance configuration (1 problem):
  - encryption.master_key: missing required key (env: VAUBAAN_MASTER_KEY or VAUBAAN_MASTER_KEY_FILE)
```

Every key: [configuration keys](/docs/configuration/keys).

## First sign-in

1. Open `https://your-domain/login` and follow the bootstrap link; paste the bootstrap token.
2. On Settings → Administration → Sign-in, add a sign-in provider — your company's OpenID Connect directory (redirect URI `https://your-domain/auth/callback/your-provider-id`) or GitHub — then "Test".
3. Sign in through it as a person matching the admin rule. That first sign-in revokes the bootstrap token for good.

With a sign-in provider in the configuration (`idp.*` or `sign_in.<id>.*`), no bootstrap token is needed: sign in directly. A provider where anyone can open an account (GitHub, personal Google or Microsoft) needs allowed email domains or "invitation only".

Then: register your [company apps](/docs/configuration#company-apps), [connect accounts](/docs/providers), and [create a first mission](/docs/missions).

## Check what runs

`curl -s https://your-domain/healthz` answers `{"status":"ok",...}` with the version and the commit; the footer of every page shows them too.

## In this section

- [Install with Docker Compose](/docs/install/docker-compose)
- [Install on Railway](/docs/install/railway)
