A language model is not a small guest. Tens of gigabytes settle onto disk the way ice settles onto a quiet moon — harmless until you try to park everything on the same thin drive that boots the machine. Root filesystems are for systems. Expansion disks are for archives and weight.
This walkthrough assumes Linux Directory is already running and at least one host is enrolled. If you are still at first light, start with How to install Linux Directory (Lindir). We will place Ollama on a CachyOS workstation (here, Trantor), keep models on an Expansion volume, and leave a user systemd unit ready — started only when you ask. Each job is claimed on the next lindir-client sync; with the sync timer enabled, that is usually within a minute.
What we are arranging
| Piece | Choice |
|---|---|
| Package | Distro ollama (Arch / CachyOS) |
| Models | /run/media/user/Expansion/Models/ollama via OLLAMA_MODELS |
| Listen | OLLAMA_HOST=0.0.0.0 so other machines on the Tailnet can reach the API |
| Package daemon | System ollama.service stays disabled (it would use /var/lib/ollama on the root disk) |
| Our daemon | Lindir-managed user unit lindir-ollama.service |
| Autostart | Off — fleet service add enables immediately; we disable afterward |
Lindir fleet services write ExecStart and optional WorkingDirectory. There is no dedicated Environment= field yet, so OLLAMA_MODELS and OLLAMA_HOST ride in the command with /usr/bin/env.
Credentials
Load the env file described in the install article:
set -a
source ~/.config/lindir/mcp.env
set +a
lindir-admin health
lindir-admin host list
Take the host’s UUID from the list. Expansion must be mounted before you start the daemon: the udisks path /run/media/user/Expansion appears only while the volume is attached. On exFAT, Models/ollama and Models/Ollama may be the same directory.
Create the models directory
A short fleet script creates the path on the host:
cat > /tmp/ollama-models-dir.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
MODELS=/run/media/user/Expansion/Models/ollama
test -d /run/media/user/Expansion
mkdir -p "$MODELS"
ls -ld "$MODELS"
du -sh "$MODELS" || true
EOF
lindir-admin fleet scripts create --name ollama-models-dir \
--file /tmp/ollama-models-dir.sh --timeout-sec 60 \
--description 'Ensure Ollama models directory on Expansion'
lindir-admin fleet scripts run --id SCRIPT_ID --host-id HOST_ID
lindir-admin fleet runs
Use the script id from create (or from lindir-admin fleet scripts) and the host id from host list. Wait until the run status is succeeded.
Install the package
lindir-admin fleet packages install --host-id HOST_ID --package ollama
lindir-admin fleet packages pending
When the job leaves pending, the package is on the host. Skip this if inventory already shows ollama.
CachyOS and Arch ship /usr/lib/systemd/system/ollama.service. That unit runs as the system user ollama, sets OLLAMA_MODELS=/var/lib/ollama, and is wanted by multi-user.target — a poor fit for a multi‑hundred‑gigabyte library when the root disk is nearly full.
lindir-admin fleet systemd disable --host-id HOST_ID --unit ollama.service
fleet systemd only operates existing system units; it does not write unit files. Confirm with lindir-admin fleet systemd-units --host-id HOST_ID that ollama.service is disabled.
Add a user service, then turn auto-start off
lindir-admin fleet service add --host-id HOST_ID \
--scope user --username user --unit ollama \
--command '/usr/bin/env OLLAMA_MODELS=/run/media/user/Expansion/Models/ollama OLLAMA_HOST=0.0.0.0 /usr/bin/ollama serve' \
--working-directory /run/media/user/Expansion/Models/ollama \
--timer-description 'Ollama — models on Expansion, listen all interfaces'
lindir-admin fleet service pending
After sync, Lindir writes ~user/.config/systemd/user/lindir-ollama.service, enables linger for that account by default, and runs enable --now. The daemon starts once.
Then remove automatic start:
lindir-admin fleet service disable --host-id HOST_ID \
--scope user --username user --unit ollama
lindir-admin fleet service pending
disable stops the unit and clears the WantedBy link. The unit file remains. When Expansion is mounted and you want inference:
lindir-admin fleet service start --host-id HOST_ID \
--scope user --username user --unit ollama
Stop with fleet service stop when you are finished.
lindir-admin fleet service list
lindir-admin fleet services --host-id HOST_ID
Successful add and disable jobs include a short systemctl transcript in stdout (the WantedBy symlink created or removed).
Verify
lindir-admin fleet runs
lindir-admin fleet service list
lindir-admin fleet services --host-id HOST_ID
A successful ollama-models-dir run prints ls and du on stdout. After disable, stdout should show the WantedBy symlink removed; after start, the job should exit 0.
With the service running, another Tailnet host can reach the API at http://trantor:11434 (or Trantor’s Tailscale IP), for example curl -fsS http://trantor:11434/api/tags.
Model pulls land under Expansion when OLLAMA_MODELS points there. The root filesystem keeps the OS, the GPU drivers, and the modest ollama package.
Why this shape
- Disk — Models live on Expansion, not on
/. - Package vs policy — Distro
ollama.servicesuits a server that should always listen under/var/lib/ollama. A workstation with a detachable library wants a different unit and path. - Demand — Inference is intentional. Disabling after
fleet service addkeeps Lindir as author of the unit without making Ollama part of every boot. - Directory — Identity and fleet share one control plane: Fleet, Admin CLI.
Caveats
- Mount first.
/run/media/.../Expansionis a udisks mount. Attach and mount the disk beforefleet service start. - exFAT — Ownership semantics are shallow; treat the volume as a library path for the session user, not as a multi-user ACL surface.
- No API authentication.
OLLAMA_HOST=0.0.0.0exposes the API on every interface, including the Tailscale address. Treat the Tailnet as the trust boundary; do not forward port 11434 to the open internet without an auth proxy. - Linger — User-scope Lindir services enable linger so start and stop work without a graphical login. That is still the account’s user manager, not the system
ollamauser. - Sync — Jobs stay
pendinguntillindir-sync.timerclaims them — usually within a minute on a healthy agent.
When the directory can see the host, large models can live where there is room — and wake only when you call them.
