Option A: Docker (Recommended)
No local Python or Node.js required — everything is built inside the container.fim-data, fim-uploads) and survives container restarts.
Note: Docker mode does not support hot reload. Code changes require rebuilding the image (docker compose up --build -d). For active development with live reload, use Option B below.
Option B: Local Development
Prerequisites: Python 3.11+, uv, Node.js 18+, pnpm.Configuration
FIM One works with any OpenAI-compatible LLM provider — OpenAI, DeepSeek, Anthropic, Qwen, Ollama, vLLM, and more.
Jina AI unlocks web search/fetch, embedding, and the full RAG pipeline (free tier available).
Minimal
.env:
Production Deployment
Docker (Recommended)
docker compose up -d brings up everything you need — no manual service configuration required:
Scaling with Workers
By default, the API runs with a single worker process. To handle more concurrent users, increase workers via.env:
- PostgreSQL — SQLite is single-writer and does not support concurrent writes. Set
DATABASE_URLto a PostgreSQL connection string. - Redis — already included in Docker Compose (auto-configured). Handles cross-worker interrupt/inject relay.
WORKERS=1 (default), no Redis or PostgreSQL is needed — SQLite works fine.
Nginx Reverse Proxy
For HTTPS and custom domain, put an Nginx reverse proxy in front:/api/* requests automatically. Only port 3000 needs to be exposed.
Code Execution Sandbox
If you use the code execution sandbox (CODE_EXEC_BACKEND=docker), mount the Docker socket:
Cloudflare Tunnel
For a zero-open-ports setup, use Cloudflare Tunnel instead of Nginx. All traffic flows through Cloudflare’s edge — no need to expose ports 80/443, manage SSL certificates, or configure firewall rules.1
Create a tunnel
Go to Cloudflare Zero Trust → Networks → Tunnels → Create a tunnel.
Choose Cloudflared as the connector type.
2
Configure the public hostname
In the tunnel config, add a public hostname:
Leave all other settings (HTTP Host Header, Chunked Encoding, Timeouts, Access) at their defaults.
The URL uses the Docker service name
fim-one, not localhost, because cloudflared runs as a separate container in the same Docker network.3
Copy the tunnel token
In the tunnel’s Configure page, find the install command — it contains a token starting with
eyJ.... Copy it.4
Add the token to .env
5
Deploy with the tunnel overlay
docker-compose.tunnel.yml overlay adds a cloudflared sidecar container. The base docker-compose.yml is unchanged — community users without Cloudflare can continue using docker compose up -d as before.6
Remove the old DNS record
If your domain previously had an A record pointing to your server’s IP, delete it in Cloudflare DNS. The tunnel automatically creates a CNAME record pointing to its edge endpoint.
7
Close server ports
Remove (or comment out) the
ports section from docker-compose.yml on your server. Traffic now flows exclusively through the tunnel — no inbound ports needed.Script Deployment (Bare Metal)
For bare-metal servers or custom process managers, use./start.sh directly: