Where you change things
Any of these saves to the same place, so use whichever is handy. Changes apply right away, with no restart.
AI keys are tested before saving. Tool keys are saved as typed. A key saved in Settings beats the same variable in
apps/api/.env.
AI models
Pick one to start. If you add several, GAIA uses the first available in this order and falls back to the next on failure: OpenRouter, Gemini, OpenAI, Ollama, custom.
Only OpenRouter, Gemini and OpenAI can read images.
From the terminal
gaia up reference.
Using Ollama
GAIA runs in a container, solocalhost is not your machine. Use http://host.docker.internal:11434, which the setup page fills in for you. Then pick a model from the list.
Tools
Web search
Search works on a fresh install through DuckDuckGo. Add a key for better results. GAIA tries providers in this order and moves on when one fails: Exa, Tavily, Brave, your SearXNG, then DuckDuckGo. Exa, Tavily and Brave stop at their free monthly allowance (20,000, 1,000 and 1,000 searches), so search never bills you. SearXNG needs your server’s address, no key.Running code
Coding tools need a sandbox, and neither is on until you choose:
With neither, coding tools say code execution is off. Everything else works. If both are set, E2B is used.
How the local sandbox works
How the local sandbox works
Each user’s code runs in its own
gaia-sandbox-* container. --code-sandbox adds the docker-compose.sandbox.yml override, and the CLI remembers it for gaia start and gaia update. Without the CLI, run docker compose -f docker-compose.selfhost.yml -f docker-compose.sandbox.yml up -d.Each sandbox sees only its user’s files, at /workspace. It needs Docker Engine 26 or newer; gaia start refuses an older one. Limits:The sandbox can still reach ports your server publishes to all interfaces, like any internet client.The first sandbox builds the
gaia-local-sandbox image on your server, which takes about a minute. It has curl, git and sqlite3, so GAIA can run Claude Code and OpenCode in it (set ENABLE_AGENT_LAB=true in apps/api/.env). Those runs report back to GAIA through the port the proxy publishes (WEB_HOST_PORT).File storage
Files stay on two Docker volumes on your server. No storage account is needed.
Only the file’s owner can open it (profile pictures are visible to every member). Set
BLOB_STORE in apps/api/.env to change where files live:
For Cloudinary, add the cloud name, API key and API secret in Settings → Providers & Tools. Cloudinary links are public to anyone who has them.
Using an S3 bucket
AWS S3, Cloudflare R2, Backblaze B2, MinIO and Railway buckets all work. Files stay private: the bucket is never made public, and GAIA serves each file to signed-in users the same way it serves files from the volume. Set these inapps/api/.env, or on both the API and the worker service:
S3_ADDRESSING_STYLE=path.
On Railway, add a bucket to the project, then reference its variables from the API and worker services:
Replace
Bucket with your bucket’s name in Railway. If the bucket’s Credentials tab says to use path-style URLs, also set S3_ADDRESSING_STYLE=path.
Moving from the volume to a bucket does not copy the files that are already stored.
Details
Details
With
local, the API and worker refuse to start if the files volume isn’t mounted and writable. With s3, they write and delete a test object at startup and refuse to start if the bucket is missing, the keys are wrong or the endpoint can’t be reached. Either way, the error names the fix. The R2_* and JUICEFS_META_URL_TEMPLATE settings belong to GAIA Cloud and are ignored here.Integrations
Apps like Gmail and Calendar connect through your own Composio project. See Connect integrations. MCP servers need no key.Not available on self-host
These show as Unavailable in Settings, whatever keys you save:- Voice needs a LiveKit server and GAIA’s voice worker.
- Browser automation needs GAIA’s browser hosts. Reading web pages still works.

