# Install with Docker Compose

> Install self-hosted MergeHarbor on a single Linux VM with Docker Compose. The installer checks prerequisites, generates secrets locally and starts everything.

The Compose bundle runs MergeHarbor on one Linux VM, for small teams, on-premises servers and evaluations. It includes PostgreSQL with pgvector, an embeddings server and Caddy for TLS, so nothing else is needed. For larger installations, use [Helm](https://mergeharbor.com/docs/self-hosting-helm).

## Requirements

- Linux with Docker Engine 24 or later and the Docker Compose plugin 2.24 or later
- `openssl`
- At least 4 vCPU, 8 GB RAM and 50 GB free disk (see [Sizing](https://mergeharbor.com/docs/self-hosting#sizing))
- Ports 80 and 443 free, and a DNS name for the VM
- linux/amd64 or linux/arm64

`./install.sh --check` checks all of this without changing anything.

## Install

Get the bundle (the `deploy/self-hosted` directory of a release, or the `self-hosted/` directory of the [air-gap bundle](https://mergeharbor.com/docs/self-hosting-air-gapped)). Then:

```sh
./install.sh --domain mergeharbor.example.com --version 1.4.0 --admin-email you@example.com
$EDITOR .env                                  # review model, code host, email
./compose.sh up -d
./create-admin.sh --org-name "Example Corp"
cp /path/to/mergeharbor.lic license/mergeharbor.lic
```

What each step does:

1. **`install.sh`**
   - Checks prerequisites and creates `.env` from `.env.example`.
   - Generates every secret locally with `openssl` into `secrets.env` (mode 600). Secrets are never printed, and an existing value is never replaced.
   - Pulls the images, starts everything and waits until the API is healthy.
2. **Edit `.env`** to choose the review model and connect your code host. Run `./compose.sh up -d` to apply changes. Always use `./compose.sh` rather than `docker compose`: it loads both `.env` and `secrets.env`.
3. **`create-admin.sh`**
   - Creates the first organization and prints a one-time link for its owner, who becomes an instance administrator.
   - Uses the break-glass admin token from inside the API container, then turns the token off again.
   - Works without email.
4. **Copy the license file.** Until a valid license is in place, reviews are paused. It is re-read every minute, so no restart is needed.

## Configuration

| Setting in `.env`                                                   | Purpose                                                                                                                                      |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `MERGEHARBOR_DOMAIN`, `MERGEHARBOR_VERSION`, `MERGEHARBOR_REGISTRY` | Host name, release (`X.Y.Z`), and image registry (default `ghcr.io/mergeharbor`)                                                             |
| `TLS_MODE`                                                          | `auto` (Let's Encrypt; needs a public name), `internal` (Caddy's own certificate authority) or `files` (`certs/tls.crt` and `certs/tls.key`) |
| `LLM_BACKEND`, `ANTHROPIC_API_KEY`                                  | The Anthropic API                                                                                                                            |
| `LLM_BACKEND=bedrock`, `AWS_REGION`, AWS credentials                | Amazon Bedrock                                                                                                                               |
| `SELFHOSTED_LLM_BASE_URL`                                           | Your own OpenAI-compatible model server; register and price the model in `config/models.yaml`                                                |
| `MODEL_PROVIDERS`                                                   | The providers configured above, for example `anthropic` or `openai_compatible`. Routing never uses another.                                  |
| `GITHUB_APP_*` and other code host settings                         | See [GitHub](https://mergeharbor.com/docs/github), [GitLab](https://mergeharbor.com/docs/gitlab) and the other code host guides                                                            |
| `SMTP_*`                                                            | Email for invitations and notifications                                                                                                      |
| `RESOURCE_PROFILE`                                                  | `small`, `medium` or `large` (with matching memory limits)                                                                                   |
| `CA_BUNDLE`                                                         | Extra certificate authorities, for code hosts or model servers with a private CA                                                             |
| `AIR_GAPPED`                                                        | `true` limits every outbound call to private networks                                                                                        |

## Operations

| Task                                   | Command                                                           |
| -------------------------------------- | ----------------------------------------------------------------- |
| Status and logs                        | `./compose.sh ps`, `./compose.sh logs -f api worker`              |
| Back up the database and configuration | `./backup.sh`. Schedule it, and copy `backups/` off the VM.       |
| Restore                                | `./backup.sh restore backups/<file>.dump`                         |
| Upgrade                                | `./upgrade.sh 1.5.0`; see [Upgrades](https://mergeharbor.com/docs/self-hosting-upgrades) |

Proof runs (the optional sandbox that runs generated tests) are not part of the Compose bundle. They need their own isolated host; use the Helm chart for them.
