Self-hosted LobeHub setup with local Ollama models, intended for a personal home server on a trusted LAN.
This configuration intentionally:
- publishes LobeHub on port
3210; - publishes the RustFS S3 API and console on ports
9000and9001; - publishes the Ollama API on port
11434for direct LAN access; - allows anyone who can reach LobeHub to create an account.
The default setup is not intended for direct exposure to the public Internet. Docker port mappings without a host address normally listen on all host interfaces; they are not automatically limited to the LAN. Use host and router firewall rules appropriate for your network, and do not forward these ports directly from the Internet. An Internet-facing deployment needs additional controls such as HTTPS, a reverse proxy, and deliberate access restrictions.
- LobeHub
- Ollama + NVIDIA GPU
- PostgreSQL
- Redis
- RustFS S3-compatible storage
- RustFS CLI for bucket initialization
Server-side database and S3 storage are required for full file upload support in LobeHub.
- Docker Engine with Docker Compose v2
- A supported NVIDIA GPU and working NVIDIA driver
- NVIDIA Container Toolkit installed and configured for Docker
- The
nvidiacontainer runtime registered with Docker
The current Compose file uses runtime: nvidia. It does not use Compose GPU device reservations, so Docker must recognize a runtime named nvidia; otherwise the Ollama container will not start. Follow the NVIDIA Container Toolkit installation instructions for your operating system, run the toolkit's Docker runtime configuration step, and restart Docker if those instructions require it.
Docker's general Compose GPU documentation is available at https://docs.docker.com/compose/how-tos/gpu-support/.
First create the local environment file:
cp .env.example .envEdit .env before starting the stack. Replace every MY_... example value with a real value; the Compose required-variable checks reject missing or empty values, but they cannot detect a non-empty placeholder such as MY_AUTH_SECRET.
After completing the required settings, optionally pull the current images and start the stack:
docker compose pull
docker compose up -dCheck status:
docker compose psLogs:
docker compose logs --tail=100 lobe-chatSecrets and machine-specific settings are stored in .env.
Generate safe secrets and passwords with:
openssl rand -hex 24
openssl rand -base64 32Avoid special URI characters in POSTGRES_PASSWORD, or percent-encode them, because the password is part of DATABASE_URL.
The examples use 192.168.1.22 as the Docker host's LAN address. Replace that address in .env with the actual LAN address of your machine in all of these values:
APP_URLOLLAMA_ORIGINSRUSTFS_CORS_ALLOWED_ORIGINSS3_ENDPOINTS3_PUBLIC_DOMAIN
Keep OLLAMA_PROXY_URL=http://ollama:11434: ollama is the service name used inside the Compose network, not a host address for browsers.
The URL in APP_URL is also the LobeHub origin used by the Ollama and RustFS CORS settings. An origin consists of the scheme, host, and port, so http://192.168.1.22:3210 and http://localhost:3210 are different origins.
The current base configuration requires these non-empty values:
APP_URL: browser-visible LobeHub URLLOBE_DB_NAME: PostgreSQL database namePOSTGRES_PASSWORD: PostgreSQL passwordKEY_VAULTS_SECRET: LobeHub key-vault encryption secretAUTH_SECRET: LobeHub authentication/session secretOLLAMA_PROXY_URL: Ollama URL used by LobeHub inside ComposeOLLAMA_ORIGINS: browser origin allowed by OllamaRUSTFS_ACCESS_KEY: RustFS access keyRUSTFS_SECRET_KEY: RustFS secret keyRUSTFS_CORS_ALLOWED_ORIGINS: LobeHub origin allowed by the RustFS S3 listenerS3_ENDPOINT: RustFS endpoint reachable using the configured host addressS3_PUBLIC_DOMAIN: browser-visible RustFS address
OpenAI integration is optional. To use only local Ollama models, leave OPENAI_API_KEY and OPENAI_PROXY_URL empty or comment them out in .env. To enable OpenAI, replace the example API key and keep or adjust the proxy URL as required.
OLLAMA_KEEP_ALIVE is also optional. If omitted, the Compose file uses 5m; .env.example selects 2m for this setup.
Ports 3210, 9000, 9001, and 11434 are intentionally published by this Compose file. Without an explicit bind address, Docker normally publishes them on all host addresses, including addresses that may be reachable beyond the trusted LAN depending on firewall, routing, and IPv6 configuration.
LobeHub registration is intentionally open: anyone who can reach port 3210 can create an account. The Ollama API on port 11434 is also intentionally reachable directly from the LAN. These choices assume a trusted home network and are not suitable defaults for an untrusted or public network.
See Docker's port-publishing documentation for the exact host exposure behavior: https://docs.docker.com/engine/network/port-publishing/.
The LobeHub container currently uses:
SSRF_ALLOW_PRIVATE_IP_ADDRESS: "1"This allows LobeHub to connect to private-network services used by this stack, but it also relaxes LobeHub's protection against server-side requests to private IP addresses. Keep this setting only in the intended trusted-LAN deployment and do not expose the stack directly to untrusted networks.
Pull a model manually:
docker exec -it ollama ollama pull qwen3:8bList installed models:
docker exec -it ollama ollama listCheck currently loaded models:
docker exec -it ollama ollama psEnabling a model in LobeHub does not automatically mean it exists in the local Ollama instance. A 404 model not found error usually means the model still needs to be pulled.
See MODELS.md for a quick model selection guide.
Ollama keeps models loaded for a short period after the last request.
Configured through .env:
OLLAMA_KEEP_ALIVE=2mand passed to the Ollama container:
environment:
OLLAMA_KEEP_ALIVE: ${OLLAMA_KEEP_ALIVE:-5m}Examples:
1m unload after 1 minute
2m unload after 2 minutes
5m Ollama default
0 unload immediately
For a 12 GB GPU with several local models, 2m is a reasonable compromise between fast model reuse and freeing VRAM.
File uploads from LobeHub require CORS to be enabled manually for the lobe bucket. The rustfs-init service creates the bucket but does not configure its bucket CORS policy.
After the stack is running:
- Open the RustFS Console at
http://192.168.1.22:9001, replacing the example address with your Docker host's LAN IP. - Sign in with
RUSTFS_ACCESS_KEYandRUSTFS_SECRET_KEYfrom your local.env. - Select the
lobebucket. - Enable Bucket CORS.
- Add the exact LobeHub origin from
APP_URL, for examplehttp://192.168.1.22:3210. - Allow
GET,POST,PUT,DELETE, andHEAD.
The allowed origin must identify the LobeHub page making the browser request, not the RustFS address. Keep RUSTFS_CORS_ALLOWED_ORIGINS aligned with the same LobeHub origin. Do not use a path or trailing route in the origin value.
You can inspect the preflight response with:
curl -i -X OPTIONS \
-H "Origin: http://192.168.1.22:3210" \
-H "Access-Control-Request-Method: PUT" \
http://192.168.1.22:9000/lobe/testFor that configured origin, the response should include an appropriate Access-Control-Allow-Origin header and allow the requested method. This command is a diagnostic example; it does not configure CORS.
RustFS CORS documentation: https://docs.rustfs.com/en/administration/cors.
Example:
Database migrate failed
TypeError: Invalid URL
The PostgreSQL password contained characters that made the generated DATABASE_URL invalid.
Fix: use a URL-safe password, for example:
openssl rand -hex 24For a brand-new database volume, recreate the stack after changing the initial PostgreSQL password:
docker compose down -v
docker compose up -dDo not use down -v on an existing installation unless deleting the database/storage volumes is intentional.
Models must be downloaded into Ollama separately:
docker exec -it ollama ollama pull MODEL_NAMEExample:
docker exec -it ollama ollama pull qwen3:14b# Stack status
docker compose ps
# LobeHub logs
docker compose logs -f lobe-chat
# Ollama logs
docker compose logs -f ollama
# Installed models
docker exec -it ollama ollama list
# Loaded models / VRAM usage
docker exec -it ollama ollama ps
# Restart the stack
docker compose restart