> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecompiler.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker

> Run Compiler on your own server from the published image, with automatic SSL through Caddy.

Compiler is published as a Docker image at `ghcr.io/usecompiler/compiler`. This guide runs it with Docker Compose, next to Caddy for automatic SSL.

To run Compiler on Kubernetes, ECS or another platform, see [Other platforms](/deployment/other-platforms).

## Prerequisites

* A server with Docker and Docker Compose
* A domain name pointing at the server, with ports 80 and 443 open

## Dependencies

Compiler needs PostgreSQL 16 or later and Redis 7 or later. Choose one of two paths.

<Tabs>
  <Tab title="Bundled (default)">
    The compose file in [step 1](#1-create-the-files) runs Postgres and Redis as their own containers next to Compiler, with their data in Docker volumes. There is nothing else to set up, so follow the steps from **1. Create the files** as written.
  </Tab>

  <Tab title="Your own Postgres and Redis">
    To use managed services such as Amazon RDS and ElastiCache instead, use this `docker-compose.yml` in step 1, which leaves out the `db` and `redis` services:

    ```yaml docker-compose.yml theme={null}
    services:
      app:
        image: ghcr.io/usecompiler/compiler:main
        environment:
          - DATABASE_URL=${DATABASE_URL}
          - DATABASE_SSL=${DATABASE_SSL:-false}
          - TOKEN_ENCRYPTION_KEY=${TOKEN_ENCRYPTION_KEY}
          - REDIS_URL=${REDIS_URL}
          - PUBLIC_URL=https://${DOMAIN}
        volumes:
          - ./repos:/repos

      caddy:
        image: caddy:alpine
        ports:
          - "80:80"
          - "443:443"
        environment:
          - DOMAIN=${DOMAIN}
        volumes:
          - ./Caddyfile:/etc/caddy/Caddyfile
          - caddy_data:/data
          - caddy_config:/config
        depends_on:
          - app

    volumes:
      caddy_data:
      caddy_config:
    ```

    Use this `.env` in place of the one in step 1:

    ```bash .env theme={null}
    DOMAIN=compiler.example.com
    TOKEN_ENCRYPTION_KEY=
    DATABASE_URL=postgresql://user:password@host:5432/compiler
    DATABASE_SSL=true
    REDIS_URL=rediss://host:6379
    ```

    | Variable | Description |
    | - | - |
    | `DATABASE_URL` | Connection string for an empty database that Compiler owns |
    | `DATABASE_SSL` | `true` when the database requires SSL, as RDS does |
    | `REDIS_URL` | `redis://` for a plain connection, `rediss://` for TLS |

    The database user must be able to create tables and the `pg_trgm` extension, which the first migration adds. On RDS the master user can.
  </Tab>
</Tabs>

## 1. Create the files

Make a folder for Compiler and put these three files in it.

<CodeGroup>
  ```yaml docker-compose.yml theme={null}
  services:
    app:
      image: ghcr.io/usecompiler/compiler:main
      environment:
        - DATABASE_URL=postgresql://compiler:${POSTGRES_PASSWORD}@db:5432/compiler
        - TOKEN_ENCRYPTION_KEY=${TOKEN_ENCRYPTION_KEY}
        - REDIS_URL=redis://redis:6379
        - PUBLIC_URL=https://${DOMAIN}
      volumes:
        - ./repos:/repos
      depends_on:
        db:
          condition: service_healthy
        redis:
          condition: service_healthy

    caddy:
      image: caddy:alpine
      ports:
        - "80:80"
        - "443:443"
      environment:
        - DOMAIN=${DOMAIN}
      volumes:
        - ./Caddyfile:/etc/caddy/Caddyfile
        - caddy_data:/data
        - caddy_config:/config
      depends_on:
        - app

    db:
      image: postgres:16-alpine
      environment:
        - POSTGRES_USER=compiler
        - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
        - POSTGRES_DB=compiler
      volumes:
        - pgdata:/var/lib/postgresql/data
      healthcheck:
        test: ["CMD-SHELL", "pg_isready -U compiler"]
        interval: 5s
        timeout: 5s
        retries: 5

    redis:
      image: redis:7-alpine
      volumes:
        - redisdata:/data
      healthcheck:
        test: ["CMD", "redis-cli", "ping"]
        interval: 5s
        timeout: 5s
        retries: 5

  volumes:
    pgdata:
    caddy_data:
    caddy_config:
    redisdata:
  ```

  ```text Caddyfile theme={null}
  {$DOMAIN} {
  	reverse_proxy app:3000
  }
  ```

  ```bash .env theme={null}
  DOMAIN=compiler.example.com
  POSTGRES_PASSWORD=
  TOKEN_ENCRYPTION_KEY=
  ```
</CodeGroup>

| Variable | Description |
| - | - |
| `DOMAIN` | The domain Compiler is served on, without `https://` |
| `POSTGRES_PASSWORD` | A long random password for the bundled database |
| `TOKEN_ENCRYPTION_KEY` | 64 hex characters, used to encrypt stored credentials |

Generate the password and the key with:

```bash theme={null}
openssl rand -hex 32
```

<Warning>
  Keep `TOKEN_ENCRYPTION_KEY` safe. If it is lost, every stored credential (GitHub App key, AI provider keys, connectors) has to be entered again.
</Warning>

## 2. Start Compiler

```bash theme={null}
docker compose up -d
```

Database migrations run on startup. Open `https://your-domain` and sign up as the first user. Setup then asks for your GitHub App.

## 3. Create a GitHub App

Compiler reads your code through a private GitHub App that you own. The short version is below; [GitHub App setup](/configuration/github-app) explains each setting.

<Steps>
  <Step title="Start a new app">
    Go to `https://github.com/settings/apps/new`, or for an organization `https://github.com/organizations/YOUR_ORG/settings/apps/new`.
  </Step>

  <Step title="Name it">
    Set **GitHub App name** to anything unique (for example `Acme Compiler`) and **Homepage URL** to `https://your-domain`.
  </Step>

  <Step title="Set the callback">
    Set both the **Callback URL** and, under **Post installation**, the **Setup URL** to `https://your-domain/onboarding/github-callback`. Check **Redirect on update**.
  </Step>

  <Step title="Turn off what Compiler doesn't use">
    Uncheck **Expire user authorization tokens** and **Request user authorization (OAuth) during installation**. Under **Webhook**, uncheck **Active**.
  </Step>

  <Step title="Set permissions">
    Under **Repository permissions**, set **Contents** and **Metadata** to **Read-only**. Leave everything else as **No access**.
  </Step>

  <Step title="Create it">
    Under **Where can this GitHub App be installed?**, choose **Only on this account**, then click **Create GitHub App**.
  </Step>

  <Step title="Collect the credentials">
    Note the **App ID** at the top of the settings page and the slug from the app's public URL (`github.com/apps/<slug>`). Under **Private keys**, click **Generate a private key** to download a `.pem` file.
  </Step>
</Steps>

Back in Compiler, enter the App ID, the slug and the full contents of the `.pem` file, then click **Install GitHub App** and choose the repositories Compiler may read. GitHub sends you back to Compiler, where you choose your AI provider (Anthropic API or [AWS Bedrock](/configuration/aws-bedrock)) and create your first project.

To change any of this later, open **Settings** as an admin.

## Behind a firewall

Without a public domain, skip Caddy and reach the app directly. Create `docker-compose.override.yml` next to the other files:

```yaml docker-compose.override.yml theme={null}
services:
  app:
    ports:
      - "3000:3000"
    environment:
      - PUBLIC_URL=http://your-server:3000
  caddy:
    profiles:
      - disabled
```

Then open `http://your-server:3000`, and use that address in place of `https://your-domain` when creating the GitHub App.

## Updating

```bash theme={null}
docker compose pull
docker compose up -d
```

**Settings** shows the commit your instance is running.

## Data and backups

| Location | Contents |
| - | - |
| `pgdata` volume | The bundled database: conversations, settings and users |
| `./repos` folder | Clones of your repositories, re-created on sync |
| `caddy_data` volume | SSL certificates |

With the bundled database, back it up with:

```bash theme={null}
docker compose exec db pg_dump -U compiler compiler > backup.sql
```

Keep a copy of `.env` with it. With your own Postgres, use your provider's backups.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.