# Install Hindsight with Docker Compose on macOS
This guide runs the self-hosted [Hindsight](https://github.com/vectorize-io/hindsight) agent-memory service with Docker Compose. The project directory contains both `compose.yaml` and a private `.env` file that holds the API key. Hindsight’s API is exposed at <http://localhost:8888> and its UI at <http://localhost:9999>.[1]
> [!important] “On boot” on macOS
> Docker Desktop is a user application, so it normally starts after a user logs in—not while macOS is at its pre-login screen. The configuration below enables Docker Desktop at login; its Docker restart policy then brings Hindsight back whenever the Docker engine starts.[3]
## What the setup creates
- **Project directory:** `~/Services/hindsight` (choose another private location if preferred).
- **Compose file:** `compose.yaml`, defining the service, local-only port bindings, restart policy, and persistent storage.
- **Secret file:** `.env`, adjacent to `compose.yaml`, containing the LLM provider and API key. Compose loads `.env` for interpolation automatically, but this configuration also declares it using `env_file` so those values are explicitly passed into the container.[4]
- **Named Docker volume:** `hindsight-data`, mounted at `/home/hindsight/.pg0`; it survives container replacement.[1][5]
The Hindsight image, ports, data-mount target, and LLM environment-variable names follow the project’s Docker quick start.[1]
## Prerequisites
1. Docker Desktop for Mac. Install the build appropriate for Apple silicon or Intel from Docker’s official installation guide.[2]
2. An API key for the LLM provider being used. This guide uses OpenAI. Hindsight documents `openai`, `anthropic`, `gemini`, `groq`, `ollama`, `lmstudio`, `minimax`, and `atlas` as provider options.[1]
Open Docker Desktop once, wait until its engine is running, then verify the CLI can reach it:
```bash
docker version
docker info
docker compose version
```
Each command must complete without a daemon-connection error.
## 1. Create the project directory
```bash
mkdir -p ~/Services/hindsight
cd ~/Services/hindsight
```
The directory will contain these files:
```text
~/Services/hindsight/
├── compose.yaml
├── .env # secret: never commit or share
└── .gitignore
```
## 2. Create `.env` with the provider and API key
Create `~/Services/hindsight/.env` in a text editor with the following content, replacing the placeholder with the actual key. The model and base URL are explicit so the service does not rely on provider defaults.[6]
```dotenv
HINDSIGHT_API_LLM_PROVIDER=openai
HINDSIGHT_API_LLM_MODEL=gpt-4o-mini
HINDSIGHT_API_LLM_BASE_URL=https://api.openai.com/v1
HINDSIGHT_API_LLM_API_KEY=replace-with-the-real-openai-api-key
```
Restrict the file to the current macOS user:
```bash
chmod 600 .env
```
If this directory will ever be initialized as a Git repository, create `.gitignore` containing:
```gitignore
.env
```
> [!danger] Treat `.env` as a secret
> Do not paste the real key into `compose.yaml`, this note, a shell command, a screenshot, or version control. Do not run commands that print the `.env` contents. The file stays on the Mac in the Compose project directory and is read when Compose creates or recreates the container.
> [!note] Other LLM providers
> Change the provider, model, base URL, and API key together to values appropriate for the chosen provider. The base URL is particularly important for OpenAI-compatible local servers such as Ollama or LM Studio: it must be reachable from the **container**, not merely from the Mac. For example, a service on the Mac commonly needs a `host.docker.internal` URL rather than `localhost`; Hindsight’s base-URL setting is `HINDSIGHT_API_LLM_BASE_URL`.[6] Setting `HINDSIGHT_API_LLM_PROVIDER=anthropic` requires a compatible Anthropic API key, not an OpenAI key.[1]
## 3. Create `compose.yaml`
Create `~/Services/hindsight/compose.yaml` with exactly this content:
```yaml
services:
hindsight:
image: ghcr.io/vectorize-io/hindsight:latest
container_name: hindsight
restart: unless-stopped
env_file:
- .env
ports:
- "127.0.0.1:8888:8888" # Hindsight API
- "127.0.0.1:9999:9999" # Hindsight web UI
volumes:
- hindsight-data:/home/hindsight/.pg0
volumes:
hindsight-data:
name: hindsight-data
```
What the important settings do:
| Setting | Meaning |
|---|---|
| `env_file: .env` | Loads the provider, model, base-URL, and API-key variables from the adjacent private file into the container.[4] |
| `restart: unless-stopped` | Starts the service when Docker starts, unless it was deliberately stopped with Docker/Compose.[3] |
| `127.0.0.1:8888:8888` and `127.0.0.1:9999:9999` | Expose API and UI only to this Mac. They are not reachable from the local network. |
| `hindsight-data:/home/hindsight/.pg0` | Keeps Hindsight data in a named volume rather than the disposable container filesystem.[1][5] |
| `name: hindsight-data` | Uses the stable Docker-volume name `hindsight-data`, rather than a project-prefixed generated name. |
## 4. Start and verify Hindsight
From `~/Services/hindsight`:
```bash
docker compose pull
docker compose up -d
docker compose ps
```
The service should show as running. Check that Docker has the expected restart policy:
```bash
docker inspect -f 'restart={{.HostConfig.RestartPolicy.Name}} status={{.State.Status}}' hindsight
```
Expected result:
```text
restart=unless-stopped status=running
```
Open the UI:
```bash
open http://localhost:9999
```
The API is at <http://localhost:8888>.[1]
If the service does not become ready, inspect its logs instead of guessing:
```bash
docker compose logs --tail 200 hindsight
```
To follow logs live, run `docker compose logs -f hindsight`; `Ctrl-C` stops only the log viewer, not the service.
## 5. Make it start automatically after login
1. Open **Docker Desktop**.
2. Open **Settings** (gear icon) → **General**.
3. Enable **Start Docker Desktop when you log in**.
4. Apply or restart Docker Desktop if it prompts.
The Compose file’s `restart: unless-stopped` policy handles Hindsight after Docker Desktop’s engine is available.[3] It does not start a container that was explicitly stopped; start it again with:
```bash
cd ~/Services/hindsight
docker compose start
```
### Test the complete restart chain
First test the configured container directly:
```bash
cd ~/Services/hindsight
docker compose restart
docker compose ps
docker inspect -f 'restart={{.HostConfig.RestartPolicy.Name}} status={{.State.Status}}' hindsight
```
Then test the important integration event: quit Docker Desktop fully from its menu, reopen it, wait for the engine to say it is running, and run:
```bash
cd ~/Services/hindsight
docker compose ps
open http://localhost:9999
```
Finally, restart the Mac and log in. Docker Desktop should launch, then Hindsight should return automatically; verify the UI and `docker compose ps` after the Docker engine is ready.
## Day-to-day operations
Run these from `~/Services/hindsight`:
```bash
# Service status
docker compose ps
# Logs
docker compose logs -f hindsight
# Stop intentionally; it stays stopped over a Docker restart
docker compose stop
# Start it again
docker compose start
# Recreate from the current Compose configuration
docker compose up -d
# Update the image, preserving the named volume
docker compose pull
docker compose up -d
# Remove the container and Compose network, but keep hindsight-data
docker compose down
```
> [!danger] Preserve the data volume
> `docker compose down` does not delete named volumes by default. Do **not** run `docker compose down -v` and do not run `docker volume rm hindsight-data` unless permanently deleting all Hindsight data is intentional.[5]
## Troubleshooting
| Symptom | Check and remedy |
|---|---|
| `Cannot connect to the Docker daemon` | Start Docker Desktop, wait for its engine, and repeat `docker info`. |
| Hindsight is `exited` | Run `docker compose logs --tail 200 hindsight`; verify the provider and API key in `.env` without exposing the key. |
| It does not return after Docker restarts | Check `docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' hindsight`; it must print `unless-stopped`. If it was intentionally stopped, run `docker compose start`. |
| The UI is unavailable | Check `docker compose ps`, then logs. Check for port conflicts with `lsof -nP -iTCP:8888 -sTCP:LISTEN` and the equivalent command for port `9999`. |
| Another device cannot connect | This is deliberate: ports bind only to `127.0.0.1`. Keep this safer default unless network exposure and access controls are explicitly planned. |
## Sources
[1] https://github.com/vectorize-io/hindsight — Hindsight README — Docker quick start
[2] https://docs.docker.com/desktop/setup/install/mac-install — Docker Docs — Install Docker Desktop on Mac
[3] https://docs.docker.com/engine/containers/start-containers-automatically — Docker Docs — Start containers automatically
[4] https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables — Docker Docs — Set environment variables in Compose
[5] https://docs.docker.com/reference/compose-file/volumes — Docker Docs — Compose volumes reference
[6] https://github.com/vectorize-io/hindsight/blob/main/hindsight-api-slim/README.md — Hindsight API Slim README — LLM configuration