ollama service and running it manually bound to all interfaces:
sudo systemctl stop ollama
OLLAMA_HOST=0.0.0.0 ollama serve
Simply exporting the environment variable in the terminal while the systemd service was still running did not help. Systemd launches the service with its own environment, so my shell export was ignored.
Why this happens
By default, Ollama listens on 127.0.0.1:11434 (localhost). That's perfect for single‑box use but invisible to other machines on your LAN. To expose it to your network you must change the bind address with OLLAMA_HOST. If Ollama is started by systemd, your shell's exported variables do not apply; systemd uses its own environment for the service. That's why stopping the service and launching OLLAMA_HOST=0.0.0.0 ollama serve worked immediately.
Target architecture (what "remote access" actually means)
- Server (Pi or any Linux host): Ollama daemon listening on
0.0.0.0:11434(or specific IP), reachable on your local network. - Client (your laptop/desktop): Send HTTP to
http://<SERVER_IP>:11434/...— for example/api/tagsor/api/generate.
Step‑by‑step: Make Ollama reachable on your LAN
Option A — One‑off (fast validation; this is what fixed it for me)
# On the server (Pi/Linux)
sudo systemctl stop ollama
OLLAMA_HOST=0.0.0.0 ollama serve
- This binds Ollama to all interfaces immediately.
- Keep this terminal open; Ctrl+C stops the server.
Option B — Persistent via systemd (recommended after confirming A)
Create a systemd override so the service always binds to the network interface:
sudo systemctl edit ollama
Paste:
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
# Optional CORS if a browser UI will call the API directly:
# Environment="OLLAMA_ORIGINS=*"
Then reload and start:
sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo systemctl status ollama --no-pager
/etc/ollama/serve.conf). A drop‑in override is the most universal.
Local smoke tests (run on the server)
1) Confirm it's listening on the right address/port
sudo ss -ltnp | grep 11434
Expect 0.0.0.0:11434 (IPv4) or :::11434 (IPv6). If you see 127.0.0.1:11434, the bind is still local only.
2) Call the API locally
curl -s http://127.0.0.1:11434/api/tags
You should get JSON (list of models). If empty, pull one with ollama pull llama3.2:3b.
3) Try a generation
curl -s http://127.0.0.1:11434/api/generate \
-H "Content-Type: application/json" \
-d '{"model":"llama3.2:3b","prompt":"ping","stream":false}'
Remote tests (run from another computer)
1) Find the server's IP
hostname -I # run on the Pi/Linux host
2) From the client machine:
curl -v http://<SERVER_IP>:11434/api/tags
If that works, try a generation:
Linux/macOS (bash/zsh):
curl -s -X POST http://<SERVER_IP>:11434/api/generate \
-H "Content-Type: application/json" \
-d '{"model":"llama3.2:3b","prompt":"Hello from another computer","stream":false}'
Windows PowerShell:
curl -Method POST http://<SERVER_IP>:11434/api/generate `
-Headers @{ "Content-Type" = "application/json" } `
-Body '{ "model": "llama3.2:3b", "prompt": "Hello from another computer", "stream": false }'
PowerShell quoting differs; use double‑quoted JSON and the -Headers hashtable.
Troubleshooting checklist
- Still bound to localhost?
ss -ltnp | grep 11434shows127.0.0.1:11434→ the environment didn't apply. If systemd starts Ollama, create the systemd override, thendaemon-reloadandrestart. - Firewall blocking?
On the server:
(Or use your distro's firewall tool.)sudo ufw status sudo ufw allow 11434/tcp - No model pulled yet?
ollama listshows none →ollama pull <model>first, then retry/api/generate. - Wrong quoting on Windows?
Use the PowerShell example above (double‑quoted JSON,-Headershashtable). - Port conflict?
If 11434 is busy, pick another port:# one-off OLLAMA_HOST=0.0.0.0:11500 ollama serve # systemd override Environment="OLLAMA_HOST=0.0.0.0:11500" - Logs via systemd:
journalctl -u ollama -n 200 --no-pager
Security basics (don't skip)
For access across the internet or between homes/offices, prefer a mesh VPN like Tailscale. With Tailscale Serve, you can forward a local port to your tailnet without opening your router to the world.
Bonus: Docker quickstart
docker run --pull=always -d --name ollama \
-p 11434:11434 \
-e OLLAMA_HOST=0.0.0.0 \
ollama/ollama
This keeps your configuration isolated and makes upgrades easy.
Final notes from experience
When debugging, assume nothing is set and test in this order:
sudo systemctl stop ollamaOLLAMA_HOST=0.0.0.0 ollama servecurl http://127.0.0.1:11434/api/tags(local)curl http://<SERVER_IP>:11434/api/tags(remote)- Only then make the systemd override for permanence.
Remember: a shell export OLLAMA_HOST=… affects only processes started from that shell — not a service that systemd already launched.
References & useful links
- Ollama on GitHub (README & docs): https://github.com/ollama/ollama
- Ollama REST API docs: https://github.com/ollama/ollama/blob/main/docs/api.md
- Docker image for Ollama: https://hub.docker.com/r/ollama/ollama
- systemd
systemctl edit(drop‑in overrides): systemctl manual - systemd service environment (
Environment=): systemd.exec manual - Ubuntu UFW basics: UFW Community Help
- Tailscale Serve: https://tailscale.com/kb/1242/tailscale-serve