docker compose, no gaia CLI needed.
The walkthrough 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
curlandopenssl - 8 GB RAM, 2+ CPU cores, 20 GB free disk (why 8 GB)
- Port 3000 free (or ports 80 and 443 for a domain)
Installing Docker on Ubuntu or Debian
Installing Docker on Ubuntu or Debian
Install
1
Download the setup files
Pick a version from the releases page, then run:
Check the download first
Check the download first
Each release also has a On macOS, use
.sha256 file. Download both, check, then unpack: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.
3
Write the Compose settings
proxy opens port 3000. GAIA_VERSION must match the version you downloaded.4
Start GAIA
-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.Not loading? Check with curl http://localhost:3000/health/ready.Options
Set these ininfra/docker/.env, then run docker compose -f docker-compose.selfhost.yml up -d again to apply them.
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 first: it gives the containers root access to your server. Chat bots need the CLI (gaia bots add); see Chat bots.
API settings such as provider keys and BLOB_STORE go in apps/api/.env; see AI models and tools and Environment variables.
Your own domain with HTTPS
Point your domain at the server and open ports 80 and 443. SetHOST and FRONTEND_URL in apps/api/.env to https://gaia.example.com, add these to infra/docker/.env, and run up -d again:
gaia.test, *.internal, *.home.arpa), see A local domain with HTTPS.
Your own reverse proxy
Platforms with their own proxy (Coolify, Traefik and others) don’t need the bundled one. LeaveCOMPOSE_PROFILES unset and route on the Compose network:
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 in infra/docker/selfhost/Caddyfile, or every visitor shares one rate limit.
Day-to-day commands
Run these from~/gaia/infra/docker.
Containers have no fixed names, so always go through
docker compose with the service name, not docker logs.
Updates, backups and restores have manual steps too: see Upgrades and Backups.
What’s running
The nine containers
The nine containers
guest/guest) and are reachable only on the internal Compose network.
Troubleshooting
http://localhost:3000 doesn't load
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
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
Containers restart once memory is in use
The machine is out of memory. GAIA needs 8 GB; see Memory sizing.
docker compose says no configuration file was found
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
Something else
See Troubleshooting, including Ollama connection problems.
Building from source
To run your own changes, build the images from a source checkout instead of pulling them. Frominfra/docker/ in the checkout:
up uses your build until the next pull. For hot reload and the full developer setup, see Development setup.
