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

# Quickstart: self-host InfraAudit with Docker Compose

> Run InfraAudit on your own infrastructure with Docker Compose. Covers Supabase setup, .env configuration, first login, and connecting your first provider.

This guide gets InfraAudit running on your own machine using Docker Compose. You'll end up with a working InfraAudit backend on `http://localhost:8080`, a frontend on `http://localhost:5173`, one connected AWS account, and one completed drift scan.

Budget 15 to 30 minutes — most of it is the Supabase setup.

## Before you start

### Supabase project (required)

InfraAudit's auth layer is backed by Supabase. The backend will not start without valid Supabase credentials. This is the most common place new self-hosters get stuck, so do this first.

<Steps>
  <Step title="Create a Supabase account">
    Go to [supabase.com](https://supabase.com) and create a free account.
  </Step>

  <Step title="Create a project">
    Create a new project. Any region works; the smallest tier is sufficient for development.
  </Step>

  <Step title="Copy your API credentials">
    Go to **Project Settings → API** and copy three values:

    * **Project URL** (e.g. `https://xxxxxxxxxxxxxx.supabase.co`) → `SUPABASE_URL`
    * **anon public key** → `SUPABASE_ANON_KEY`
    * **service\_role secret** → `SUPABASE_SERVICE_ROLE_KEY`
  </Step>

  <Step title="Copy your JWT secret">
    Go to **Project Settings → API → JWT Settings** and copy the **JWT Secret** → `SUPABASE_JWT_SECRET`.
  </Step>
</Steps>

Keep these four values handy. You'll paste them into `.env` shortly.

### System requirements

* Docker 24+ and Docker Compose v2
* 4 GB free RAM (8 GB if you enable the Prometheus/Grafana monitoring profile)
* 10 GB free disk

### Gemini API key (optional)

If you want AI-generated recommendations rather than the rule-based fallback, grab a Gemini API key from [ai.google.dev](https://ai.google.dev). The key is not required to start the stack.

## Install and configure

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/pratik-mahalle/infraudit-go.git
    cd infraudit-go
    ```
  </Step>

  <Step title="Create your .env file">
    ```bash theme={null}
    cp .env.example .env
    ```

    Open `.env` and fill in at minimum the following values:

    ```env theme={null}
    # Supabase (required)
    SUPABASE_URL=https://xxxxxxxxxxxxxx.supabase.co
    SUPABASE_JWT_SECRET=your-jwt-secret-here
    SUPABASE_ANON_KEY=eyJhbGciOi...
    SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...

    # Server
    SERVER_PORT=8080
    FRONTEND_URL=http://localhost:5173
    ENVIRONMENT=development

    # Database (Docker Compose provisions this automatically)
    DB_DRIVER=postgres
    DB_HOST=postgres
    DB_PORT=5432
    DB_NAME=infraudit
    DB_USER=infraudit
    DB_PASSWORD=infraudit123
    DB_SSLMODE=disable

    # Encryption key for cloud credentials at rest
    ENCRYPTION_KEY=change-me-32-byte-random-string-here

    # Optional: Gemini AI recommendations
    GEMINI_API_KEY=

    # Optional: Slack notifications
    SLACK_WEBHOOK_URL=
    SLACK_CHANNEL=#alerts
    ```

    <Warning>
      Change `ENCRYPTION_KEY` before storing any real cloud credentials. Generate a secure value with `openssl rand -hex 32`. Also change `DB_PASSWORD` — the default is publicly known and must never reach production.
    </Warning>
  </Step>

  <Step title="Start the stack">
    ```bash theme={null}
    docker compose up -d
    ```

    This starts four containers:

    | Service    | Port | Purpose               |
    | ---------- | ---- | --------------------- |
    | `api`      | 8080 | InfraAudit Go backend |
    | `postgres` | 5432 | Primary database      |
    | `redis`    | 6379 | Cache                 |
    | `frontend` | 5173 | React web UI          |

    Watch the logs until the API reports it's ready:

    ```bash theme={null}
    docker compose logs -f api
    ```

    If the API exits immediately with a Supabase error, double-check `SUPABASE_URL` and `SUPABASE_JWT_SECRET`. The process refuses to start without them.
  </Step>

  <Step title="Verify the health endpoints">
    ```bash theme={null}
    curl http://localhost:8080/healthz
    # {"status":"ok"}

    curl http://localhost:8080/readyz
    # {"status":"ready","database":"ok","redis":"ok"}
    ```

    If `database` reports `error`, the Postgres container is still warming up. Wait 10 seconds and try again.
  </Step>
</Steps>

## First login

<Steps>
  <Step title="Open the UI">
    Go to `http://localhost:5173` in your browser.
  </Step>

  <Step title="Create your account">
    Click **Sign up** and register with any email and password. Supabase stores the credentials; InfraAudit resolves the Supabase user on first login.
  </Step>

  <Step title="Land on the dashboard">
    You land on the dashboard. It's empty because no providers are connected yet.
  </Step>
</Steps>

## Connect your first cloud account

<Tabs>
  <Tab title="Web UI">
    1. Click **Cloud Providers** in the sidebar.
    2. Click **Connect AWS**.
    3. Paste your AWS access key ID, secret access key, and choose a region (e.g. `us-east-1`).
    4. Click **Connect**. InfraAudit encrypts the credentials using your `ENCRYPTION_KEY` and kicks off an initial resource sync.
  </Tab>

  <Tab title="CLI">
    Install the CLI first — see [Quickstart: CLI](/getting-started/quickstart-cli) — then:

    ```bash theme={null}
    infraudit config init
    # Enter server URL: http://localhost:8080

    infraudit auth login

    infraudit provider connect aws
    ```
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -X POST http://localhost:8080/api/v1/providers/aws/connect \
      -H "Authorization: Bearer $INFRAUDIT_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "AWS Production",
        "accessKeyId": "AKIA...",
        "secretAccessKey": "...",
        "region": "us-east-1"
      }'
    ```

    The Bearer token is the Supabase `access_token` from signing in.
  </Tab>
</Tabs>

## Run your first scan

Once the initial resource sync finishes (typically under a minute for a small account), trigger a drift scan:

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    infraudit drift detect
    infraudit drift list --severity critical
    infraudit drift summary
    ```
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    curl -X POST http://localhost:8080/api/v1/drifts/detect \
      -H "Authorization: Bearer $INFRAUDIT_TOKEN"
    ```
  </Tab>

  <Tab title="Web UI">
    Open **Drift Detection** in the sidebar and click **Run scan**.
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The API container exits with 'SUPABASE_JWT_SECRET is required'">
    You skipped the Supabase setup or used the wrong variable name. Check `.env` against `.env.example` and make sure `SUPABASE_JWT_SECRET` is set.
  </Accordion>

  <Accordion title="I can log in on the frontend but API calls return 401">
    The frontend proxies through `FRONTEND_URL` but the API validates tokens against `SUPABASE_URL`. Make sure both point to the same Supabase project.
  </Accordion>

  <Accordion title="docker compose up says port 8080 is already in use">
    Another service is bound to that port. Change `SERVER_PORT` in `.env` and update the port mapping in `docker-compose.yml` to match.
  </Accordion>

  <Accordion title="Drift detection runs but never finds anything">
    Drift compares against baselines, and a fresh install has none yet. The first sync captures baselines automatically. Make a manual change to a resource in your cloud account and scan again to see drift appear.
  </Accordion>
</AccordionGroup>

## What to do next

* **Enable vulnerability scans** — run `infraudit vuln scan` or enable the scheduled job
* **Set up Slack alerts** — add `SLACK_WEBHOOK_URL` to `.env`, restart the API, and configure notification preferences
* **Enable a compliance framework** — run `infraudit compliance enable cis-aws` and then `infraudit compliance assess`
* **Review cost data** — billing syncs daily by default; force an immediate sync with `infraudit cost sync`
