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

# Manual install with Docker

> Install a self-hosted GAIA with Docker Compose alone, without the gaia CLI.

Run GAIA with plain `docker compose`, no `gaia` CLI needed.

> [!NOTE]
>
> The [walkthrough](https://docs.heygaia.io/self-hosting/walkthrough.md) does all of this with one command, and `gaia doctor`, `gaia update` and `gaia backup` only work with the CLI.

## What you need

* Docker with Compose v2, plus `curl` and `openssl`
* 8 GB RAM, 2+ CPU cores, 20 GB free disk ([why 8 GB](https://docs.heygaia.io/self-hosting/maintenance.md#memory-sizing))
* Port 3000 free (or ports 80 and 443 for a domain)

> **Installing Docker on Ubuntu or Debian**
>
> ```bash theme={null}
> sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin
> sudo usermod -aG docker $USER && newgrp docker
> ```
>
> On macOS or Windows, install [Docker Desktop](https://docs.docker.com/desktop/).

## Install

**1. Download the setup files**

Pick a version from the [releases page](https://github.com/theexperiencecompany/gaia/releases), then run:

```bash theme={null}
V=0.7.0 && mkdir -p ~/gaia && curl -fsSL https://github.com/theexperiencecompany/gaia/releases/download/cli-v$V/gaia-selfhost-$V.tar.gz | tar -xz -C ~/gaia
```

> **Check the download first**
>
> Each release also has a `.sha256` file. Download both, check, then unpack:
>
> ```bash theme={null}
> V=0.7.0
> BASE=https://github.com/theexperiencecompany/gaia/releases/download/cli-v$V
> curl -fsSLO "$BASE/gaia-selfhost-$V.tar.gz" -O "$BASE/gaia-selfhost-$V.tar.gz.sha256"
> sha256sum -c "gaia-selfhost-$V.tar.gz.sha256"
> mkdir -p ~/gaia && tar -xzf "gaia-selfhost-$V.tar.gz" -C ~/gaia
> ```
>
> On macOS, use `shasum -a 256 -c`. You should see `OK`.

**2. Write the API settings**

This file holds your passwords and database addresses. Run it once and keep the file.

```bash theme={null}
cd ~/gaia && mkdir -p apps/api && cat > apps/api/.env <<EOF
ENV=selfhost
AUTH_MODE=local
HOST=http://localhost:3000
FRONTEND_URL=http://localhost:3000
MONGO_DB=mongodb://mongo:27017/gaia
REDIS_URL=redis://redis:6379
POSTGRES_URL=postgresql://postgres:postgres@postgres:5432/langgraph
CHROMADB_HOST=chromadb
CHROMADB_PORT=8000
RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672/
AGENT_SECRET=$(openssl rand -hex 32)
BOT_SESSION_TOKEN_SECRET=$(openssl rand -hex 32)
EMAIL_UNSUBSCRIBE_SECRET=$(openssl rand -hex 32)
SHARE_GRANT_SECRET=$(openssl rand -hex 32)
SANDBOX_EXECUTE_TOKEN_SECRET=$(openssl rand -hex 32)
INSTANCE_SECRET=$(openssl rand -hex 32)
EOF
```

> [!WARNING]
>
> Never change these secrets once GAIA has data. It signs everyone out and locks your saved AI keys. See [the instance secret](https://docs.heygaia.io/self-hosting/maintenance.md#the-instance-secret).

**3. Write the Compose settings**

```bash theme={null}
printf 'COMPOSE_PROFILES=proxy\nGAIA_VERSION=v0.7.0\n' > ~/gaia/infra/docker/.env
```

`proxy` opens port 3000. `GAIA_VERSION` must match the version you downloaded.

**4. Start GAIA**

```bash theme={null}
cd ~/gaia/infra/docker && docker compose -f docker-compose.selfhost.yml up -d
```

The first start can take several minutes. Always pass `-f docker-compose.selfhost.yml`.

**5. Finish in the browser**

Open `http://localhost:3000`, create the admin account and pick an AI provider. See [AI models and tools](https://docs.heygaia.io/self-hosting/ai-models-and-tools.md).

Not loading? Check with `curl http://localhost:3000/health/ready`.

## Options

Set these in `infra/docker/.env`, then run `docker compose -f docker-compose.selfhost.yml up -d` again to apply them.

| Variable | What it does | Default |
| - | - | - |
| `GAIA_VERSION` | The image tag for the API, worker and web app | `latest` |
| `WEB_HOST_PORT` | The port GAIA is served on | `3000` |
| `HTTPS_HOST_PORT` | The HTTPS port | `3443` |
| `GAIA_DOMAIN` | A domain to serve over HTTPS with an automatic certificate | Unset: plain HTTP |
| `COMPOSE_PROFILES` | `proxy` starts the bundled proxy. Leave it out when you bring your own | Unset: no proxy |
| `GAIA_API_IMAGE`, `GAIA_WEB_IMAGE` | Use other images, such as your own builds | `ghcr.io/theexperiencecompany/gaia`, `ghcr.io/theexperiencecompany/gaia-web` |

For the local coding sandbox, add a second Compose file: `docker compose -f docker-compose.selfhost.yml -f docker-compose.sandbox.yml up -d`. Read [Running code](https://docs.heygaia.io/self-hosting/ai-models-and-tools.md#running-code) first: it gives the containers root access to your server. Chat bots need the CLI (`gaia bots add`); see [Chat bots](https://docs.heygaia.io/self-hosting/bots.md).

API settings such as provider keys and `BLOB_STORE` go in `apps/api/.env`; see [AI models and tools](https://docs.heygaia.io/self-hosting/ai-models-and-tools.md) and [Environment variables](https://docs.heygaia.io/configuration/environment-variables.md).

### Your own domain with HTTPS

Point your domain at the server and open ports 80 and 443. Set `HOST` and `FRONTEND_URL` in `apps/api/.env` to `https://gaia.example.com`, add these to `infra/docker/.env`, and run `up -d` again:

```bash theme={null}
GAIA_DOMAIN=gaia.example.com
WEB_HOST_PORT=80
HTTPS_HOST_PORT=443
```

The proxy gets and renews the certificate for you. For a name no public authority can certify (`gaia.test`, `*.internal`, `*.home.arpa`), see [A local domain with HTTPS](https://docs.heygaia.io/self-hosting/cli-reference.md#a-local-domain-with-https).

### Your own reverse proxy

Platforms with their own proxy (Coolify, Traefik and others) don't need the bundled one. Leave `COMPOSE_PROFILES` unset and route on the Compose network:

| Path | Send to |
| - | - |
| `/api/v1/*` and `/health/ready` | `gaia-backend:8000` |
| Everything else | `gaia-web:3000` |

Don't buffer streamed responses, allow WebSocket upgrades on `/api/v1`, and make your proxy replace, not append to, any `X-Forwarded-For` header a client sends: the API trusts it for rate limits. If you put another proxy in front of the bundled one instead (Cloudflare Tunnel, a load balancer), add its address to [`trusted_proxies`](https://caddyserver.com/docs/caddyfile/options#trusted-proxies) in `infra/docker/selfhost/Caddyfile`, or every visitor shares one rate limit.

## Day-to-day commands

Run these from `~/gaia/infra/docker`.

| To | Run |
| - | - |
| See container status | `docker compose -f docker-compose.selfhost.yml ps` |
| Follow the logs | `docker compose -f docker-compose.selfhost.yml logs -f gaia-backend` |
| Restart a service | `docker compose -f docker-compose.selfhost.yml restart gaia-backend` |
| Stop GAIA | `docker compose -f docker-compose.selfhost.yml down` |
| Open a database shell | `docker compose -f docker-compose.selfhost.yml exec mongo mongosh gaia` |

Containers have no fixed names, so always go through `docker compose` with the service name, not `docker logs`.

> [!WARNING]
>
> Never run `down -v` or `docker system prune --volumes`: they delete every volume, which is all of GAIA's data. See [Data persistence](https://docs.heygaia.io/self-hosting/maintenance.md#data-persistence).

Updates, backups and restores have manual steps too: see [Upgrades](https://docs.heygaia.io/self-hosting/maintenance.md#upgrades) and [Backups](https://docs.heygaia.io/self-hosting/maintenance.md#backups).

## What's running

> **The nine containers**
>
> | Service | What it does |
> | - | - |
> | `proxy` | Caddy, the only service with a host port. Sends `/api/v1/*` and `/health/ready` to the API and everything else to the web app |
> | `gaia-web` | The Next.js web app |
> | `gaia-backend` | The FastAPI API |
> | `arq_worker` | Background jobs: reminders, workflows, email. Same image as the API |
> | `mongo` | Accounts, chats, settings and saved provider keys |
> | `postgres` | Agent state |
> | `redis` | Cache, sessions and the job queue |
> | `chromadb` | Vectors for memory and search |
> | `rabbitmq` | Message broker |

The databases run without passwords (RabbitMQ uses the well-known `guest`/`guest`) and are reachable only on the internal Compose network.

> [!WARNING]
>
> Don't add `ports:` for the databases to the Compose file. Between them they hold every account, session, saved key and the instance secret, so an open port means anyone can take all of it.

## Troubleshooting

> **[http://localhost:3000](http://localhost:3000) doesn't load**
>
> Check that `infra/docker/.env` has `COMPOSE_PROFILES=proxy` and that `docker compose -f docker-compose.selfhost.yml ps` lists `proxy`. Without the profile no port is opened. If something else uses port 3000, set `WEB_HOST_PORT` to another port.

> **gaia-backend stays unhealthy**
>
> The first start sets up the databases and can take up to 10 minutes on a small machine. Watch it with `docker compose -f docker-compose.selfhost.yml logs -f gaia-backend`. An error that names a missing setting means a line is missing from `apps/api/.env`: compare it with step 2 above.

> **Containers restart once memory is in use**
>
> The machine is out of memory. GAIA needs 8 GB; see [Memory sizing](https://docs.heygaia.io/self-hosting/maintenance.md#memory-sizing).

> **docker compose says no configuration file was found**
>
> You left out `-f docker-compose.selfhost.yml`. Compose only finds `docker-compose.yml` on its own, and the setup files don't include one. Add `-f docker-compose.selfhost.yml` to every command.

> **Something else**
>
> See [Troubleshooting](https://docs.heygaia.io/self-hosting/maintenance.md#troubleshooting), including Ollama connection problems.

## Building from source

To run your own changes, build the images from a source checkout instead of pulling them. From `infra/docker/` in the checkout:

```bash theme={null}
docker compose -f docker-compose.selfhost.yml -f docker-compose.build.yml up -d --build
```

The build keeps the same image tags, so a later plain `up` uses your build until the next pull. For hot reload and the full developer setup, see [Development setup](https://docs.heygaia.io/developers/development-setup.md).


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