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

# Docker Deployment

> Deploy Helicone using Docker with either the all-in-one container or Docker Compose for development and production environments.

## Quick Start: All-in-One Container

The fastest way to get Helicone running is with the all-in-one Docker image that bundles all services into a single container.

### Local Development

For local development and testing:

```bash theme={null}
docker pull helicone/helicone-all-in-one:latest
docker run -d \
  --name helicone \
  -p 3000:3000 \
  -p 8585:8585 \
  -p 9080:9080 \
  helicone/helicone-all-in-one:latest
```

Access the dashboard at `http://localhost:3000`.

**Exposed Ports:**

* `3000` - Web dashboard
* `8585` - Jawn API + LLM proxy
* `9080` - MinIO S3 storage (for request/response bodies)

### Production Deployment

When deploying to a remote server (EC2, VPS, etc.), configure public URLs:

```bash theme={null}
# Replace YOUR_IP with your server's public IP or domain
export PUBLIC_URL="http://YOUR_IP:3000"
export JAWN_URL="http://YOUR_IP:8585"
export S3_URL="http://YOUR_IP:9080"

docker run -d \
  --name helicone \
  -p 3000:3000 \
  -p 8585:8585 \
  -p 9080:9080 \
  -e SITE_URL="$PUBLIC_URL" \
  -e BETTER_AUTH_URL="$PUBLIC_URL" \
  -e BETTER_AUTH_SECRET="$(openssl rand -base64 32)" \
  -e NEXT_PUBLIC_APP_URL="$PUBLIC_URL" \
  -e NEXT_PUBLIC_HELICONE_JAWN_SERVICE="$JAWN_URL" \
  -e NEXT_PUBLIC_IS_ON_PREM=true \
  -e S3_ENDPOINT="$S3_URL" \
  helicone/helicone-all-in-one:latest
```

### Data Persistence

<Warning>
  Container restarts will wipe all data unless you mount volumes for persistence.
</Warning>

For production deployments, mount Docker volumes to persist data:

```bash theme={null}
docker run -d \
  --name helicone \
  -p 3000:3000 \
  -p 8585:8585 \
  -p 9080:9080 \
  -v helicone-postgres:/var/lib/postgresql/data \
  -v helicone-clickhouse:/var/lib/clickhouse \
  -v helicone-minio:/data \
  # ... other environment variables ...
  helicone/helicone-all-in-one:latest
```

## Docker Compose Setup

For more control and development workflows, use Docker Compose to run services separately.

### Prerequisites

* Docker 20.10+
* Docker Compose 2.0+

### Initial Setup

1. Clone the Helicone repository:

```bash theme={null}
git clone https://github.com/Helicone/helicone.git
cd helicone/docker
```

2. Create environment file:

```bash theme={null}
cp .env.example .env
```

3. Update `.env` with your configuration (see Environment Variables section below)

### Start Services

**Option 1: Infrastructure + Core Services** (Recommended for production):

```bash theme={null}
docker compose --profile include-helicone up -d
```

This starts:

* Infrastructure: PostgreSQL, ClickHouse, MinIO, Redis
* Core services: Jawn API, Web Dashboard
* Database migrations run automatically

**Option 2: Infrastructure Only** (For development):

```bash theme={null}
docker compose up -d
```

Starts only infrastructure services. Run Jawn and Web locally for faster development cycles.

**Option 3: Development Mode** (Hot reload):

```bash theme={null}
docker compose --profile dev up -d
```

Mounts source code as volumes with hot reloading enabled.

### Available Profiles

Docker Compose uses profiles to control which services run:

| Profile | Services | Use Case |
| - | - | - |
| (default) | Infrastructure only | Local development with services running bare-metal |
| `include-helicone` | Infrastructure + Core | Production-like deployment |
| `dev` | Infrastructure + Dev services | Development with hot reload |
| `workers` | + Worker services | Separate worker processes |
| `kafka` | + Kafka + Zookeeper | Event streaming (experimental) |

### Verify Deployment

```bash theme={null}
# Check running services
docker compose ps

# View logs
docker compose logs -f web
docker compose logs -f jawn

# Check service health
docker compose ps | grep "(healthy)"
```

## Environment Variables

### Required for Production

| Variable | Default | Description |
| - | - | - |
| `BETTER_AUTH_SECRET` | `change-me-in-production` | **CRITICAL**: Generate with `openssl rand -base64 32` |
| `NEXT_PUBLIC_HELICONE_JAWN_SERVICE` | `http://localhost:8585` | Public URL browsers use to reach API |
| `S3_ENDPOINT` | `http://localhost:9080` | Public URL for S3 presigned URLs |
| `SITE_URL` | - | Public URL of web dashboard |
| `BETTER_AUTH_URL` | - | Same as SITE\_URL |
| `NEXT_PUBLIC_APP_URL` | - | Same as SITE\_URL |
| `NEXT_PUBLIC_IS_ON_PREM` | `false` | Set to `true` for non-localhost deployments |

### Database Configuration

| Variable | Default | Description |
| - | - | - |
| `SUPABASE_DATABASE_URL` | `postgres://postgres:testpassword@db:5432/helicone_test` | PostgreSQL connection string |
| `CLICKHOUSE_HOST` | `http://clickhouse:8123` | ClickHouse HTTP endpoint |
| `CLICKHOUSE_USER` | `default` | ClickHouse username |
| `CLICKHOUSE_PASSWORD` | (empty) | ClickHouse password |

### Storage Configuration

| Variable | Default | Description |
| - | - | - |
| `S3_ACCESS_KEY` | `minioadmin` | MinIO/S3 access key |
| `S3_SECRET_KEY` | `minioadmin` | MinIO/S3 secret key |
| `S3_BUCKET_NAME` | `request-response-storage` | Bucket for request/response bodies |
| `S3_PROMPT_BUCKET_NAME` | `prompt-body-storage` | Bucket for prompt templates |

### Service Ports

| Variable | Default | Description |
| - | - | - |
| `JAWN_PORT` | `8585` | Jawn API/Proxy port |
| `JAWN_PUBLIC_URL` | `http://localhost:8585` | Public Jawn URL |

## User Account Setup

### Create Account

Navigate to `http://YOUR_IP:3000/signup` and create your account.

### Email Verification

The container doesn't include production email services. Manually verify users:

```bash theme={null}
docker exec -u postgres helicone psql -d helicone_test -c \
  "UPDATE \"user\" SET \"emailVerified\" = true WHERE email = 'your@email.com';"
```

### Organization Setup

Users must belong to an organization:

```bash theme={null}
# 1. Get your user ID
docker exec -u postgres helicone psql -d helicone_test -c \
  "SELECT id, email FROM \"user\" WHERE email = 'your@email.com';"

# 2. Create organization (save the returned ID)
docker exec -u postgres helicone psql -d helicone_test -c \
  "INSERT INTO organization (name, is_personal) VALUES ('My Org', true) RETURNING id;"

# 3. Add user to organization (replace USER_ID and ORG_ID)
docker exec -u postgres helicone psql -d helicone_test -c \
  "INSERT INTO organization_member (\"user\", organization, org_role) \
   VALUES ('USER_ID', 'ORG_ID', 'admin');"
```

## Testing the Deployment

### Test Web Dashboard

Visit `http://YOUR_IP:3000` and sign in.

### Test LLM Proxy

Test with OpenAI:

```bash theme={null}
export OPENAI_API_KEY="sk-..."
export HELICONE_API_KEY="sk-..."  # Get from dashboard after signing in

curl --request POST \
  --url http://YOUR_IP:8585/v1/gateway/oai/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $OPENAI_API_KEY" \
  --header "Helicone-Auth: Bearer $HELICONE_API_KEY" \
  --data '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
```

## Supported LLM Providers

The self-hosted version supports:

* **OpenAI**: `http://YOUR_IP:8585/v1/gateway/oai/v1/chat/completions`
* **Anthropic**: `http://YOUR_IP:8585/v1/gateway/anthropic/v1/messages`

<Info>
  Other providers (Vertex AI, AWS Bedrock, Azure OpenAI) are not supported in the self-hosted version.
</Info>

## Security Best Practices

### Authentication

<Warning>
  Port 8585 does not require authentication for proxying requests. Anyone with network access can proxy LLM requests through your endpoint.
</Warning>

Mitigate this by:

1. **Firewall Rules**: Restrict access to port 8585 to trusted IPs
2. **VPN**: Deploy behind a VPN for internal-only access
3. **Reverse Proxy**: Add authentication at the reverse proxy layer

### HTTPS Setup

For production deployments, use a reverse proxy for HTTPS:

**Example with Caddy:**

```caddy theme={null}
helicone.yourdomain.com {
    reverse_proxy localhost:3000
}

api.helicone.yourdomain.com {
    reverse_proxy localhost:8585
}

s3.helicone.yourdomain.com {
    reverse_proxy localhost:9080
}
```

For production deployments, configure HTTPS using a reverse proxy like Caddy or nginx.

## Troubleshooting

### API calls fail with connection refused

The web app tries to connect to `localhost:8585` instead of your public IP.

**Solution**: Verify environment variables:

```bash theme={null}
curl http://YOUR_IP:3000/__ENV.js | grep JAWN
# Should show your public IP, not localhost
```

### Infinite redirect loop

**Cause**: Missing `NEXT_PUBLIC_IS_ON_PREM=true` environment variable.

**Solution**: Add the environment variable and restart the container.

### "Invalid origin" error on sign-in

**Cause**: Mismatched URL origins in environment variables.

**Solution**: Ensure all URL variables use the same origin (either all localhost or all public IP/domain):

```bash theme={null}
SITE_URL=http://YOUR_IP:3000
BETTER_AUTH_URL=http://YOUR_IP:3000
NEXT_PUBLIC_APP_URL=http://YOUR_IP:3000
NEXT_PUBLIC_HELICONE_JAWN_SERVICE=http://YOUR_IP:8585
S3_ENDPOINT=http://YOUR_IP:9080
```

### "No organization ID found" error

**Cause**: User not added to an organization.

**Solution**: See the Organization Setup section above.

### Database connection errors

**Cause**: Services starting before databases are ready.

**Solution**: Docker Compose has health checks. Wait for healthy status:

```bash theme={null}
docker compose ps
# Wait until db, clickhouse, and minio show "(healthy)"
```

### Migration errors

**Cause**: Database schema not initialized.

**Solution**: Check migration logs:

```bash theme={null}
docker compose logs migrations
```

Rebuild and restart if needed:

```bash theme={null}
docker compose down
docker compose --profile include-helicone up -d --build
```

## Maintenance

### Updating Helicone

Pull the latest images and restart:

```bash theme={null}
docker compose pull
docker compose --profile include-helicone up -d
```

### Viewing Logs

```bash theme={null}
# All services
docker compose logs -f

# Specific service
docker compose logs -f web
docker compose logs -f jawn
```

### Backup Data

```bash theme={null}
# Backup PostgreSQL
docker exec helicone-postgres-flyway-test pg_dump -U postgres helicone_test > backup.sql

# Backup ClickHouse (requires clickhouse-client)
docker exec helicone-clickhouse clickhouse-client --query "BACKUP DATABASE default TO Disk('backups', 'backup.zip')"

# Backup MinIO data
docker run --rm -v helicone-minio:/data -v $(pwd):/backup alpine tar czf /backup/minio-backup.tar.gz /data
```

### Restore Data

```bash theme={null}
# Restore PostgreSQL
docker exec -i helicone-postgres-flyway-test psql -U postgres helicone_test < backup.sql
```

## Next Steps

* Configure your application to use the Helicone proxy
* Explore the [AI Gateway](/gateway/quickstart) for easier integration
* Set up monitoring and alerts for production deployments
* For scalable production deployments, see [Kubernetes Setup](/self-hosting/kubernetes)
