Deploying with Docker
Run docsfy as a self-hosted documentation service so your team can generate and browse AI-powered docs from a shared server, with data that survives container restarts.
Prerequisites
- Docker Engine 20.10+ and Docker Compose v2
- An
ADMIN_KEYpassword (minimum 16 characters) — this is your admin login credential - At least one AI provider CLI credential available to the container (Cursor is pre-installed in the image)
Quick Example
git clone https://github.com/myk-org/docsfy.git
cd docsfy
cp .env.example .env
Edit .env and set your admin password:
ADMIN_KEY=change-this-to-a-16-plus-character-password
docker compose up -d
Open http://localhost:8000/login and sign in with username admin and your ADMIN_KEY value.
Step-by-Step
1. Create the environment file
cp .env.example .env
Edit .env with your production values:
ADMIN_KEY=change-this-to-a-16-plus-character-password
AI_PROVIDER=cursor
AI_MODEL=gpt-5.4-xhigh-fast
AI_CLI_TIMEOUT=60
LOG_LEVEL=INFO
DATA_DIR=/data
SECURE_COOKIES=true
Warning:
ADMIN_KEYis required and must be at least 16 characters. The server will refuse to start without it.Note: Set
SECURE_COOKIES=falseonly when running over plain HTTP (e.g.,http://localhostfor local testing). For any HTTPS deployment, keep ittrue.
See Configuration Reference for the full list of environment variables.
2. Review the Compose file
The project ships a ready-to-use docker-compose.yaml:
services:
docsfy:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- ./data:/data
env_file:
- .env
environment:
- ADMIN_KEY=${ADMIN_KEY}
restart: unless-stopped
Key points:
- Port 8000 — the web UI, API, and generated doc sites are all served here.
./data:/data— maps the hostdata/directory into the container at/data, where the database and generated documentation are stored.restart: unless-stopped— the container restarts automatically after crashes or host reboots (unless you explicitly stop it).
3. Build and start
docker compose up -d --build
The multi-stage build compiles the React frontend, the Pi SDK sidecar, and the Python backend into a single image. The first build takes a few minutes; subsequent builds use Docker layer caching.
4. Verify the deployment
curl http://localhost:8000/health
Expected response:
{"status": "ok"}
The built-in health check also verifies the AI sidecar is running. Check container health status with:
docker compose ps
The STATUS column should show healthy once both the server and sidecar pass their checks (this can take up to 30 seconds on first start).
5. Sign in and start generating
Open http://localhost:8000/login in your browser. Sign in with:
- Username:
admin - Password: your
ADMIN_KEYvalue
You're now ready to generate documentation. See Generating Documentation for next steps.
Persistent Storage
All docsfy state lives under a single directory (/data inside the container). The volume mount ./data:/data ensures this data persists across container restarts, rebuilds, and upgrades.
The data directory contains:
| Path | Contents |
|---|---|
/data/docsfy.db |
SQLite database — users, projects, access control, sessions |
/data/projects/ |
Generated documentation sites, page caches, and build artifacts |
Tip: Back up the
data/directory to preserve your entire docsfy state — database and all generated docs — in a single copy.
Using a named Docker volume
If you prefer a named volume instead of a bind mount, replace the volumes section:
services:
docsfy:
volumes:
- docsfy-data:/data
volumes:
docsfy-data:
Environment Variable Reference
| Variable | Default | Description |
|---|---|---|
ADMIN_KEY |
(required) | Admin password (minimum 16 characters) |
AI_PROVIDER |
cursor |
Default AI provider (claude, gemini, or cursor) |
AI_MODEL |
gpt-5.4-xhigh-fast |
Default AI model |
AI_CLI_TIMEOUT |
60 |
Timeout in seconds for each AI CLI call |
MAX_CONCURRENT_PAGES |
10 |
Maximum parallel AI calls during generation |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
DATA_DIR |
/data |
Path inside the container for database and docs |
SECURE_COOKIES |
true |
Set to false for HTTP-only deployments |
PORT |
8000 |
Server listen port |
SIDECAR_PORT |
9100 |
Internal AI sidecar port (rarely needs changing) |
See Configuration Reference for details on every setting, and Configuring AI Providers for provider-specific setup.
Advanced Usage
Changing the exposed port
To run docsfy on a different host port, change the port mapping in docker-compose.yaml:
ports:
- "3000:8000"
Then access the service at http://localhost:3000. The internal PORT variable should stay at 8000 unless you have a specific reason to change it.
Placing behind a reverse proxy
For production HTTPS deployments, put a reverse proxy (nginx, Caddy, Traefik) in front of docsfy. A minimal nginx configuration:
server {
listen 443 ssl;
server_name docs.example.com;
ssl_certificate /etc/ssl/certs/docs.example.com.pem;
ssl_certificate_key /etc/ssl/private/docs.example.com.key;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# WebSocket support for real-time generation updates
location /api/ws {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
Note: Keep
SECURE_COOKIES=true(the default) when serving over HTTPS. The WebSocket endpoint at/api/wsrequires theUpgradeandConnectionheaders to be forwarded.
Tuning generation performance
For servers with more CPU and memory, increase parallel AI calls:
MAX_CONCURRENT_PAGES=20
AI_CLI_TIMEOUT=120
For constrained environments, reduce concurrency:
MAX_CONCURRENT_PAGES=4
Development mode
For local development with hot reload, uncomment the dev options in docker-compose.yaml:
services:
docsfy:
ports:
- "8000:8000"
- "5173:5173"
volumes:
- ./data:/data
- ./frontend:/app/frontend
environment:
- ADMIN_KEY=${ADMIN_KEY}
- DEV_MODE=true
This starts the Vite dev server on port 5173 alongside the FastAPI backend with auto-reload. Edit frontend files on your host and see changes immediately.
Upgrading docsfy
git pull
docker compose up -d --build
Your data in ./data is preserved across rebuilds. The database schema automatically migrates on startup when needed.
Tip: Run
docker compose downbefore upgrading if you want a clean restart, but this is not required —up --buildreplaces the running container in place.
Troubleshooting
-
Container exits immediately — Check logs with
docker compose logs docsfy. The most common cause is a missing or too-shortADMIN_KEY. -
Health check fails — The health check probes both the server (
/healthon port 8000) and the AI sidecar (port 9100). Rundocker compose logs docsfy | grep sidecarto check if the sidecar started successfully. It can take up to 30 seconds on first boot. -
Browser login redirects back to
/login— If you're accessing over plain HTTP, setSECURE_COOKIES=falsein.envand restart the container. -
Permission denied on
./data— The container runs as a non-root user (UID 1000, GID 0). Ensure the hostdata/directory is writable:bash mkdir -p data && chmod 775 data -
Generation fails with provider errors — Verify your AI provider is configured correctly. See Configuring AI Providers for provider-specific requirements.
-
Out of disk space — Generated documentation and page caches accumulate in
./data/projects/. Delete old projects through the web dashboard or API to free space. See Managing Projects and Variants for cleanup options.