# Install with Docker Compose

> Run InfraInbox on your own server with the official Docker Compose file.

Web page: https://infrainbox.app/docs/self-hosting/install/

InfraInbox ships as one Docker image plus PostgreSQL. There is no other infrastructure to run: no message broker, no cache, no separate identity server.

> **Note:** Public images are not published yet — they arrive with InfraInbox's first release. Until then, build the image yourself (`make image` in the repository) and point `INFRAINBOX_IMAGE` at what you built.

## What you need

- A Linux host (or a VM) with Docker Engine and the Compose plugin.
- A hostname the server will answer to. A private IP or a `.local`/`.home.arpa` name is fine for a LAN-only instance; a real DNS name is needed only if you want a browser-trusted certificate (see [TLS and reverse proxies](https://infrainbox.app/docs/self-hosting/reverse-proxy.md)).
- Nothing else. PostgreSQL runs in its own container and needs no separate setup.

## 1. Get the compose files

Clone the repository, or copy just the `deploy/compose/` directory from it:

```bash
git clone https://github.com/infrainbox/infrainbox
cd infrainbox/deploy/compose
```

## 2. Configure

```bash
cp .env.example .env
printf 'POSTGRES_PASSWORD=%s\n'      "$(openssl rand -hex 24)" >> .env
printf 'INFRAINBOX_DB_PASSWORD=%s\n' "$(openssl rand -hex 24)" >> .env
```

Then open `.env` and set `INFRAINBOX_PUBLIC_URL` to the address you and your phone will reach this server at, for example `https://infrainbox.example.com` or `https://192.168.1.20:8443`. Include the port unless it's 443.

> **Warning:** `INFRAINBOX_PUBLIC_URL` is the setting to get right. Sign-in, the pairing QR code and every generated ingest URL are built from it. A request that arrives under a different hostname gets an HTTP 421, which looks like "the server is up but broken" rather than a configuration hint.

None of the three values above has a default — Compose refuses to start until all three are set, so there's no InfraInbox install running on a blank or guessable password.

To let people sign in through your own identity provider or GitHub, see [Sign in with an identity provider](https://infrainbox.app/docs/self-hosting/configuration.md#sign-in-with-an-identity-provider), and check it with `infrainbox admin idp test <id>`. The first administrator is created with the setup link either way.

To let people reset a forgotten password themselves, give the server a mail relay: see [Email](https://infrainbox.app/docs/self-hosting/configuration.md#email). Without one, `infrainbox admin reset-password <user>` does it from a shell. (`infrainbox admin invites create` is for InfraInbox Cloud's invite-only sign-up and refuses to run on a self-hosted server.)

## 3. Start it

```bash
docker compose up -d
docker compose logs infrainbox | grep 'setup token'
```

The second command prints a one-time link, something like:

```
https://infrainbox.example.com/setup#token=...
```

Open it in a browser to create the first administrator account. The token works once, while the instance has no user yet; if the log has scrolled past, reissue one:

```bash
docker compose exec infrainbox /infrainbox admin setup-token
```

## 4. Check it works

- `docker compose ps` shows both `infrainbox` and `postgres` as healthy.
- The setup link loads a sign-in/setup page instead of a certificate error or a connection refusal.
- After creating the admin account, the dashboard loads at `INFRAINBOX_PUBLIC_URL`.

By default the app terminates TLS itself with a self-signed certificate, so your browser will warn about it once. See [TLS and reverse proxies](https://infrainbox.app/docs/self-hosting/reverse-proxy.md) for a browser-trusted certificate, and [Core concepts](https://infrainbox.app/docs/start/concepts.md) for what to do next.

## Where your data lives

Two named volumes:

| Volume | Holds |
|---|---|
| `postgres-data` | Everything in the database: events, incidents, sources, destinations, settings. |
| `infrainbox-data` | The master encryption key and, unless you mount your own, the generated TLS certificate. |

Back up both, and keep the backups apart from each other — see [Backups and upgrades](https://infrainbox.app/docs/self-hosting/backup-and-upgrade.md).

## Bring your own PostgreSQL

To use a PostgreSQL ≥ 16 you already run instead of the bundled one, drop the `postgres` service and point `INFRAINBOX_DATABASE_URL` at your server. Create the application's login yourself first — it needs `NOSUPERUSER`, `NOBYPASSRLS` and `CREATEROLE` (the last so InfraInbox's own migrations can create the internal roles they use):

```sql
CREATE ROLE infrainbox WITH LOGIN NOSUPERUSER NOBYPASSRLS NOCREATEDB CREATEROLE PASSWORD '<password>';
CREATE DATABASE infrainbox OWNER infrainbox;
\c infrainbox
ALTER SCHEMA public OWNER TO infrainbox;
```

Nothing more is needed: InfraInbox's own migrations create their remaining internal roles and grants. See [Configuration reference](https://infrainbox.app/docs/self-hosting/configuration.md) for `INFRAINBOX_DATABASE_URL`.
