KiwiFS ships with a multi-stage Dockerfile and a docker-compose.yml that includes an optional pgvector sidecar for vector search.
Quick start
Pre-built image
Build from source
Pull and run the pre-built image from Docker Hub.docker run -p 3333:3333 -v ./knowledge:/data ameliaanhlam/kiwifs
Build from the repo Dockerfile (includes the latest embedded UI).docker build -t kiwifs .
docker run -p 3333:3333 -v ./knowledge:/data kiwifs
Your knowledge base is now available at http://localhost:3333.
Dockerfile
The Dockerfile uses a three-stage build to produce a minimal runtime image.
| Stage | Base image | Purpose |
|---|
| 1. Node.js | node:22-alpine | Builds the React UI |
| 2. Go | golang:1.26-alpine | Compiles the Go binary with the UI embedded via go:embed |
| 3. Runtime | alpine:3.20 | Minimal image with git and ca-certificates |
The final image contains only the compiled binary, git (for versioning), and root CA certificates.
Docker Compose
The included docker-compose.yml runs KiwiFS alongside an optional pgvector database for vector search.
services:
kiwifs:
build: .
ports:
- "3333:3333"
# Uncomment to expose additional protocols:
# - "2049:2049" # NFS
# - "3334:3334" # S3
# - "3335:3335" # WebDAV
volumes:
- ./knowledge:/data
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- KIWI_PGVECTOR_DSN=postgres://kiwi:kiwi@db:5432/kiwi?sslmode=disable
depends_on:
db:
condition: service_healthy
db:
image: pgvector/pgvector:pg16
environment:
POSTGRES_USER: kiwi
POSTGRES_PASSWORD: kiwi
POSTGRES_DB: kiwi
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U kiwi"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pgdata:
Start everything with a single command.
Configuration
Environment variables
Pass environment variables to configure KiwiFS and enable integrations.
docker run \
-v ./knowledge:/data \
-p 3333:3333 \
-e OPENAI_API_KEY=sk-... \
-e KIWI_PGVECTOR_DSN=postgres://user:pass@host:5432/db \
kiwifs
In docker-compose.yml, add variables under the environment key or use an .env file.
services:
kiwifs:
env_file: .env
Enable authentication
Pass auth flags as command arguments.
docker run -v ./knowledge:/data -p 3333:3333 \
kiwifs serve --auth apikey --api-key my-secret-key
Enable NFS, S3, and WebDAV
Uncomment the relevant port mappings in docker-compose.yml and add the corresponding flags.
services:
kiwifs:
build: .
ports:
- "3333:3333"
- "2049:2049" # NFS
- "3334:3334" # S3
- "3335:3335" # WebDAV
volumes:
- ./knowledge:/data
command: ["serve", "--nfs", "--s3", "--webdav"]
The NFS server runs in userspace (NFSv3) and does not require the container to run in privileged mode.
Volumes and persistence
The knowledge directory must be mounted as a volume so data persists across container restarts.
volumes:
- ./knowledge:/data # Knowledge files
- pgdata:/var/lib/postgresql/data # Vector search database
If you omit the volume mount, all knowledge data is lost when the container stops.
Health checks
KiwiFS exposes health endpoints you can use in your Docker configuration.
services:
kiwifs:
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3333/healthz"]
interval: 10s
timeout: 3s
retries: 3
| Endpoint | Purpose |
|---|
/health | Basic health check |
/healthz | Liveness probe |
/readyz | Readiness probe |
Production tips
Pin the image tag in production. Build with a version tag (docker build -t kiwifs:1.2.0 .) and reference it explicitly in your compose file.
- Set
--async-commit=true (the default) for better write throughput under load.
- Use
--search sqlite for fast full-text search without external dependencies.
- Mount the pgvector volume to a persistent disk if you use vector search.
- Set resource limits in your compose file to prevent runaway memory usage.
services:
kiwifs:
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"