---
title: "FitaLabs Gateway — Docker Setup"
description: "Documentation: FitaLabs Gateway — Docker Setup"
type: reference
tags: [infra, docker, postgresql, prisma, redis, compose]
timestamp: 2026-07-06
---

# FitaLabs Gateway — Docker Setup

Docker Compose + Dockerfile configuration for the gateway.

## Services (docker-compose.yml)

| Service | Image | Port | Function |
|---------|-------|------|----------|
| `caddy` | `caddy:2-alpine` | 80, 8443 | Reverse proxy + TLS |
| `gateway` | build `./litellm-gateway` | 4000 | LiteLLM Proxy Server |
| `postgres` | `postgres:16-alpine` | 5432 | Proxy database |
| `redis` | `redis:7-alpine` | 6379 | Prompt cache |
| `searxng` | `searxng/searxng:latest` | 8888 | Meta-search |
| `crawl4ai` | `unclecode/crawl4ai:latest` | 11235 | Web crawler |
| `uptime-kuma` | `louislam/uptime-kuma:latest` | 3001 | Monitoring |

## Dockerfile

```dockerfile
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim

WORKDIR /app

# System deps: ffmpeg (audio codec), libatomic1 (Prisma/Node binaries)
RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg curl libatomic1 && rm -rf /var/lib/apt/lists/*

# Python deps (layer cache)
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev 2>/dev/null || uv sync --no-dev

COPY src/ src/
COPY litellm_config.yaml ./

ENV PYTHONPATH=/app/src
EXPOSE 4000

CMD ["uv", "run", "uvicorn", "gateway:app", "--host", "0.0.0.0", "--port", "4000"]
```

## Volumes

| Volume | Path | Purpose |
|--------|------|---------|
| `redis-data` | `/data` | Redis cache |
| `postgres-data` | `/var/lib/postgresql/data` | PostgreSQL database |
| `prisma-cache` | `/root/.cache/prisma-python` | Prisma binaries |
| bind `src/` | `/app/src` (ro) | Hot reload dev |
| bind `data/` | `/app/data` | SQLite + files |
| bind `litellm_config.yaml` | `/app/litellm_config.yaml` (ro) | Proxy config |
| bind `webapp/` | `/var/www` (Caddy) | Static files |

## Env Vars (.env)

Project convention: each service has its own `.env`, not in `docker-compose.yml`.

```bash
# litellm-gateway/.env
LITELLM_MASTER_KEY=sk-gateway-local
CONFIG_FILE_PATH=/app/litellm_config.yaml
DATABASE_URL=postgresql://litellm:litellm@postgres:5432/litellm
UI_USERNAME=admin
UI_PASSWORD=admin
REDIS_HOST=redis
REDIS_PORT=6379
XIAOMI_API_KEY=tp-...
DEEPSEEK_API_KEY=sk-...
OPENAI_API_KEY=tp-...              # same as XIAOMI (proxy requires)
GATEWAY_API_KEY=sk-gateway-local
SEARXNG_INTERNAL_URL=http://searxng:8080/search
```

## Why `libatomic1`?

Prisma (Python) downloads Node.js binaries to run the query engine.
The `node` binary needs `libatomic.so.1`. Without it:

```
node: error while loading shared libraries: libatomic.so.1:
cannot open shared object file: No such file or directory
```

## Why PostgreSQL and not SQLite?

LiteLLM's Prisma schema (`litellm_proxy_extras/schema.prisma`) uses:
```prisma
datasource client {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
```

SQLite is not supported. Admin UI, key management, spend tracking,
and user management all depend on PostgreSQL.

## Healthchecks

```yaml
postgres:
  healthcheck:
    test: ["CMD", "pg_isready", "-U", "litellm"]
redis:
  healthcheck:
    test: ["CMD", "redis-cli", "ping"]
gateway:
  healthcheck:
    test: ["CMD", "curl", "-f", "-H", "Authorization: Bearer sk-gateway-local",
           "http://localhost:4000/health"]
  depends_on:
    postgres:
      condition: service_healthy
    redis:
      condition: service_healthy
```

## Dev Workflow

```bash
# Build + start
docker compose up -d --build gateway

# Restart (pick up code changes via bind mount)
docker restart litellm-gateway

# Logs
docker logs litellm-gateway

# Test endpoint
docker exec litellm-gateway curl -s http://localhost:4000/v1/models \
  -H 'Authorization: Bearer sk-gateway-local'
```

## References
- [[fitalabs-gateway-1p-jornada]] — overview
- [[litellm-proxy-migration]] — proxy migration
- [[fitalabs-infra]] — original stack
