SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-09-04

Ollama draaien in rootless Podman op een VPS

Leer hoe u Ollama veilig als rootless Podman container op een VPS installeert. Wij behandelen lingering, Quadlet configuraties, SELinux labels en SSH-tunneling voor toegang.

Ollama uitvoeren in rootless Podman op een VPS

Om Ollama in rootless Podman op een server uit te voeren, moeten vijf voorwaarden zijn vervuld die in een desktop-handleiding vaak worden overgeslagen. Een specifieke gebruiker zonder privileges is eigenaar van de container. 'Lingering' is ingeschakeld voor deze gebruiker, zodat de container blijft draaien nadat u bent uitgelogd. Een Quadlet-bestand draagt de container over aan systemd, waardoor deze na een herstart automatisch wordt hervat. De model-directory draagt een SELinux-label op distributies die dit afdwingen. De API luistert alleen op loopback en u bereikt deze via een SSH-tunnel.

Ollama is een server voor large language models (LLM). Het slaat modelgewichten op schijf op, laadt deze in het geheugen en beantwoordt HTTP-verzoeken op poort 11434. Het bevat geen inlogprocedure, geen API-sleutel en geen gebruikersaccounts; het netwerk is dus uw enige vorm van toegangscontrole. Podman voert containers uit zonder daemon en zonder root-rechten, waardoor alles wat uit de container ontsnapt, begint als een gewone gebruiker zonder privileges. Als u eerst de vergelijking van de runtime wilt lezen, bekijk dan hoe Podman en Docker verschillen op een VPS. Als u liever helemaal geen containers gebruikt, is Ollama direct installeren op een VPS een kortere route.

SSD Nodes biedt Fedora aan als image, en Fedora levert standaard zowel Podman als SELinux (security-enhanced Linux). Elk onderstaand commando werkt op elke distributie met Podman 5 of nieuwer.

Waarom de laptopversie aanpassingen vereist op een server

Fedora Magazine publiceerde op 5 augustus 2026 een duidelijke handleiding voor deze stack: Running Ollama Locally with Podman on Fedora Linux, door Yazan Monshed. Het is een uitstekende introductie van een uur voor deze tools. De handleiding richt zich echter op een laptop, en vier van de gemaakte keuzes gedragen zich anders op een machine met een publiek IP-adres.

  • De container wordt gestart met een simpel podman run -d. Een handmatig gestarte container keert niet terug na een herstart, omdat er geen instructie is gegeven om deze automatisch te starten.
  • Er wordt gebruikgemaakt van de variabele tag ollama/ollama. Op een laptop merkt u het direct wanneer het gedrag verandert. Op een server is het eerste teken een script dat 's nachts is gestopt met werken.
  • De publicatie gebeurt met -p 11434:11434, wat alle interfaces bindt. Achter een thuisrouter is dit onbereikbaar vanaf het internet. Op een VPS is dit echter een publieke inference API zonder wachtwoordbeveiliging.
  • De container draait onder uw eigen inloggebruiker. Op een server moet het account dat de container bezit niets anders bezitten, zodat een eventuele uitbraak in een lege home-directory belandt.

Niets hiervan is onjuist voor het type machine waarvoor het artikel is geschreven. Elk punt is simpelweg een beslissing die u opnieuw moet evalueren wanneer de server vanaf elke locatie bereikbaar is en er niemand fysiek voor het scherm zit.

Maak de niet-bevoorrechte gebruiker aan en controleer subuid

Rootless Podman koppelt de interne user ID's (UID) van de container aan een blok ongebruikte ID's op de host. Dat blok wordt gedeclareerd in /etc/subuid en /etc/subgid. Zonder deze toewijzing kunnen rootless containers niet opstarten.

sudo dnf install -y podman        # or: sudo apt install -y podman
sudo useradd --create-home --shell /bin/bash --comment "Ollama container owner" ollama
sudo passwd --lock ollama
grep ollama /etc/subuid /etc/subgid

De grep zou twee regels moeten tonen, één uit elk bestand, waarbij elk een bereik van 65536 ID's aangeeft:

/etc/subuid:ollama:100000:65536
/etc/subgid:ollama:100000:65536

Uw startnummer zal afwijken, en dat is in orde. Als de grep niets weergeeft, heeft useradd geen bereik toegewezen en zal het eerste podman-commando als die gebruiker als volgt falen:

Error: cannot find UID/GID for user ollama: no subuid ranges found for user "ollama" in /etc/subuid

Wijs een bereik toe dat geen enkele andere gebruiker bezit en geef vervolgens aan Podman door dat de oude mapping verouderd is:

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 ollama
sudo -iu ollama podman system migrate

Het vergrendelen van het wachtwoord betekent dat niemand direct inlogt als ollama. U krijgt toegang tot het account vanaf uw admin-gebruiker met sudo -iu ollama.

Lingering inschakelen zodat de service na uitloggen actief blijft

Een systemd-instantie van een gebruiker start normaal gesproken bij het inloggen en stopt bij het uitloggen, waarbij /run/user/<uid> wordt verwijderd. Elke rootless container die eigendom is van die gebruiker wordt op datzelfde moment beëindigd. Lingering zorgt ervoor dat de gebruikersinstantie actief blijft zonder dat er een sessie gekoppeld is.

sudo loginctl enable-linger ollama
loginctl show-user ollama --property=Linger

Dit zou Linger=yes moeten weergeven. Schakel dit in voordat u de unit aanmaakt, omdat de map die de unit nodig heeft, /run/user/<uid>, pas bestaat zodra lingering is ingeschakeld.

Er is nog één stap waar niemand rekening mee houdt. sudo -iu ollama geeft u een shell, maar geen sessiebus, waardoor systemctl --user direct faalt:

Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

systemd zoekt naar de gebruikersbus op $XDG_RUNTIME_DIR/bus, en sudo -i stelt die variabele niet in. Stel deze handmatig in in elke beheershell waarin u deze service beheert:

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user status

Waar model-blobs worden opgeslagen en hoeveel schijfruimte u moet plannen

Ollama schrijft gewichten naar /root/.ollama/models binnen de container. Koppel een map uit de home-directory van de gebruiker aan dat pad en de bestanden komen op een locatie terecht die u kunt meten: /home/ollama/ollama-data/models. Blobs worden opgeslagen in models/blobs als content-addressed bestanden, en models/manifests bevat de kleine index die deze benoemt. Als u in plaats daarvan een named volume gebruikt, zoals in het Fedora Magazine-artikel wordt beschreven, bevindt dezelfde boomstructuur zich onder /home/ollama/.local/share/containers/storage/volumes/<volume>/_data. Hoe dan ook schrijven ollama pull en ollama run gewichten naar dezelfde boomstructuur, en wat de twee commando's onderscheidt is enkel of er een chatsessie wordt geopend zodra de download is voltooid.

Bepaal de schijfgrootte voordat u iets ophaalt. De gepubliceerde downloadgroottes geven u de ondergrens.

ChartPublished download size per Ollama model tag, ollama.com/library, checked 13 August 2026
The data behind this chart
[
  {
    "label": "gemma3:4b",
    "download_gb": 3.3
  },
  {
    "label": "mistral:7b",
    "download_gb": 4.4
  },
  {
    "label": "qwen3:8b",
    "download_gb": 5.2
  },
  {
    "label": "gemma3:12b",
    "download_gb": 8.1
  },
  {
    "label": "qwen3:14b",
    "download_gb": 9.3
  },
  {
    "label": "gemma3:27b",
    "download_gb": 17
  },
  {
    "label": "qwen3:30b",
    "download_gb": 19
  }
]

Alle 7 rijen zijn cijfers die zijn gepubliceerd op ollama.com/library, geen groottes gemeten op een schijf. De kleinste tag hier, gemma3:4b, downloadt 3.3 GB. De grootste, qwen3:30b, downloadt 19 GB. De container-image zelf staat daarbovenop in de eigen opslag van Podman, dus controleer beide getallen samen met podman system df en df -h /home. Een model heeft tijdens het laden ook ongeveer zijn eigen bestandsgrootte aan RAM nodig, plus ruimte voor het contextvenster, dus een model van 19 GB zal niet draaien op een VPS met 16 GB.

Pin de image-tag en gebruik de volledige registry-naam

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
mkdir -p ~/ollama-data ~/.config/containers/systemd
podman pull docker.io/ollama/ollama:0.32.9

Gebruik een uitgebrachte versie-tag, 0.32.9 per augustus 2026, en niet latest. Een vastgezette (pinned) tag zorgt ervoor dat een herstart om 04:00 uur hetzelfde binaire bestand oplevert als het bestand dat u heeft getest; elke verandering in gedrag is dus een verandering die u zelf heeft aangebracht. Docker Hub publiceert ook -rc en -rocm tags voor dezelfde versies; kies de standaardversie tenzij u een AMD GPU gebruikt.

Vermeld ook de registry-host. Op Fedora heeft een korte naam in een systemd-unit geen terminal om om invoer te vragen, waardoor de unit faalt met:

Error: short-name "ollama/ollama" did not resolve to an alias and no unqualified-search registries are defined

Het handmatig ophalen (pullen) van de image is optioneel, maar nuttig omdat het de download van meerdere gigabytes buiten de start-timeout van de unit verplaatst.

De Quadlet-unit die een herstart overleeft

Quadlet is de systemd-generator van Podman. U schrijft een .container-bestand, systemd zet dit bij het opstarten om naar een service en podman generate systemd is niet langer nodig. Sla dit op als /home/ollama/.config/containers/systemd/ollama.container, met de gebruiker ollama als eigenaar.

[Unit]
Description=Ollama API (rootless)
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/ollama/ollama:0.32.9
ContainerName=ollama
PublishPort=127.0.0.1:11434:11434
Volume=/home/ollama/ollama-data:/root/.ollama:Z
Environment=OLLAMA_KEEP_ALIVE=30m
Environment=OLLAMA_MAX_LOADED_MODELS=1

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=default.target

De bestandsnaam bepaalt de servicenaam, dus ollama.container wordt ollama.service.

systemctl --user daemon-reload
systemctl --user start ollama.service
systemctl --user status ollama.service

status hoort active (running) te tonen. Voer systemctl --user enable ollama.service niet uit. De unit bestaat niet als bestand op de schijf, dus systemd weigert dit:

Failed to enable unit: Unit file /run/user/1001/systemd/generator/ollama.service is transient or generated.

De sectie [Install] voert die taak al uit. Quadlet maakt de link voor automatisch opstarten zelf aan tijdens daemon-reload, en daarom is dat commando niet optioneel. TimeoutStartSec=900 dekt een eerste start waarbij de image nog moet worden binnengehaald, aangezien de standaard 90 seconden niet volstaan voor een download van twee gigabyte en systemd de start als mislukt zal afbreken. OLLAMA_KEEP_ALIVE=30m houdt een model in het geheugen tussen verzoeken in plaats van het na vijf minuten te ontladen; de afwegingen hiervan staan in een Ollama-model in het geheugen houden. Als de systemd-terminologie hier nieuw voor u is, behandelt hoe systemd-services en timers werken op een VPS de units zelf.

Waarom de model-directory 'permission denied' retourneert onder SELinux

Op Fedora, RHEL, Rocky en AlmaLinux staat SELinux standaard in de 'enforcing'-modus. Een containerproces draait in het container_t-domein en een directory in de home-map van een gebruiker is gelabeld als user_home_t. Het beleid staat niet toe dat deze elkaar beïnvloeden, waardoor Ollama de model-tree niet kan aanmaken en de container afsluit. getenforce geeft op deze systemen Enforcing weer en de weigering wordt vastgelegd:

sudo ausearch -m avc -ts recent

U ziet een regel die het domein en het doel-label benoemt:

avc:  denied  { write } for  pid=1842 comm="ollama" name="models" dev="vda1" ino=131077 scontext=system_u:system_r:container_t:s0:c214,c827 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir permlisted=0

De :Z aan het einde van de Volume=-regel is de oplossing. Hiermee wordt de host-directory opnieuw gelabeld naar container_file_t en voorzien van een private MCS-categorie (multi-category security) die alleen deze container bezit. De kleine letter :z gebruikt in plaats daarvan een gedeeld label; dit is de gewenste optie wanneer twee containers dezelfde directory lezen.

Een waarschuwing over :Z: dit is destructief en geeft geen meldingen. Het opnieuw labelen gebeurt recursief. Als u dit op /home/ollama richt, wordt elk bestand in die home-directory opnieuw gelabeld, waardoor de toegang via SSH-keys voor die gebruiker niet meer werkt. Geef :Z altijd een specifieke subdirectory die niets anders bevat. Named volumes hebben dit niet nodig, omdat Podman deze correct labelt bij het aanmaken. Voor een breder overzicht legt SELinux-basisprincipes voor een server contexten en booleans uit. Op Ubuntu en Debian wordt AppArmor gebruikt; :Z is daar een no-op en het laten staan in de unit is ongevaarlijk.

Poort 11434 sluiten en de API bereiken via SSH

PublishPort=127.0.0.1:11434:11434 bindt de hostzijde aan loopback. Controleer dit:

ss -ltnp | grep 11434
curl http://127.0.0.1:11434

De ss-output moet 127.0.0.1:11434 tonen. 0.0.0.0:11434 of *:11434 betekent dat de poort openstaat voor het internet, en de curl moet Ollama is running antwoorden.

Wees nauwkeurig over welke zijde u bindt. Het adres in PublishPort is het hostadres. Binnen de container moet Ollama op alle interfaces blijven luisteren, wat de standaardinstelling van de image is. Het instellen van Environment=OLLAMA_HOST=127.0.0.1 bindt Ollama aan de eigen loopback van de container, en Podman stuurt gepubliceerd verkeer door naar het netwerkadres van de container, waardoor elk verzoek zelfs vanaf de host wordt geweigerd.

Een open 11434 kost u op twee manieren. Ollama heeft geen authenticatie, dus iedereen die de poort bereikt, kan uw modellen opvragen via /api/tags, inferentie uitvoeren op uw CPU en uw bandbreedte verbruiken via /api/generate, nieuwe modellen naar uw schijf downloaden en de modellen die u heeft verwijderen. Ten tweede verstuurt platte HTTP naar een externe poort prompts en antwoorden in leesbare tekst, waardoor elke machine langs het pad deze kan lezen. Beide problemen verdwijnen als de poort de server nooit verlaat.

Forward de poort vanaf uw werkstation via SSH:

ssh -N -L 11434:127.0.0.1:11434 you@vps.example.com

Nu is http://127.0.0.1:11434 op uw laptop de Ollama van de server, binnen de versleuteling van de SSH-sessie. Als uw laptop zelf al Ollama draait, mislukt de lokale bind met bind [127.0.0.1]:11434: Address already in use; gebruik -L 11435:127.0.0.1:11434 en wijs uw client naar 11435.

Wanneer een browserclient dit nodig heeft, plaatst u in plaats daarvan een reverse proxy met een wachtwoord ervoor. Een Caddy-siteblok bestaat uit vier regels, en caddy hash-password genereert de bcrypt-hash die vereist is:

ollama.example.com {
  basic_auth {
    you $2a$14$replace_with_the_generated_hash
  }
  reverse_proxy 127.0.0.1:11434
}

Caddy regelt zelf een certificaat via TLS (transport layer security), waardoor het verkeer versleuteld is. Test uw client eerst: veel tools die met Ollama communiceren hebben geen veld voor een Authorization-header, en zij zullen falen bij basic auth met een kale 401 Unauthorized. De SSH-tunnel heeft dit probleem niet, en daarom is dit hier de standaardaanbeveling.

Een model ophalen en het volledige pad controleren

podman exec -it ollama ollama pull gemma3:4b
curl -s http://127.0.0.1:11434/api/tags
curl -s http://127.0.0.1:11434/api/generate -d '{"model":"gemma3:4b","prompt":"Reply with the single word: ready","stream":false}'
du -sh ~/ollama-data/models

/api/tags retourneert een JSON-lijst met gemma3:4b. /api/generate retourneert een JSON-object met een response-veld, na een korte pauze terwijl de gewichten vanaf de schijf worden geladen. du hoort een getal te rapporteren dat dicht bij de gepubliceerde downloadgrootte ligt. Bewijs vervolgens het onderdeel waar deze hele handleiding over gaat:

sudo reboot
# reconnect, then:
sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user is-active ollama.service

active betekent dat het proces actief blijft; de [Install]-sectie en daemon-reload hebben hun werk gedaan. inactive betekent dat een van de drie ontbreekt.

Foutmodi en bijbehorende meldingen

Container is verdwenen na een herstart. Controleer eerst loginctl show-user ollama --property=Linger, want zonder Linger=yes start de systemd-instantie van de gebruiker nooit bij het opstarten. Als lingering is ingeschakeld, ontbreekt mogelijk de sectie [Install] in het bestand .container, of u heeft het bestand bewerkt zonder systemctl --user daemon-reload uit te voeren.

Error: statfs /home/ollama/ollama-data: no such file or directory. De bron van de bind mount moet bestaan voordat de container start. Podman maakt zelf geen host-mappen aan. Voer mkdir -p ~/ollama-data uit als de ollama-gebruiker.

Start mislukt na 90 seconden. journalctl --user -u ollama.service toont Start operation timed out. Terminating. omdat het ophalen van de image nog bezig was. Haal de image handmatig op of behoud TimeoutStartSec=900.

Container start en stopt direct. podman logs ollama en sudo ausearch -m avc -ts recent geven samen aan of het probleem bij het SELinux-label ligt. Een AVC-melding met container_t en user_home_t betekent dat de :Z ontbreekt.

Verzoeken vanaf de host worden geweigerd. curl: (7) Failed to connect to 127.0.0.1 port 11434: Connection refused met de service active betekent meestal dat OLLAMA_HOST is ingesteld op een loopback-adres binnen de container. Verwijder die regel.

Generatie is erg traag of de container wordt beëindigd. Zonder GPU draait inferentie op de CPU en is een groot model van nature traag. Een container die halverwege een verzoek sterft met signal: killed in de logs, is het slachtoffer van de out-of-memory killer van de kernel; kies in dat geval een kleinere tag uit de bovenstaande tabel.

Een vastgezette image bijwerken

Vastzetten (pinning) betekent dat updates een actie zijn die u uitvoert, in plaats van iets dat u overkomt. Bewerk Image= in ollama.container en voer daarna een reload en restart uit:

systemctl --user daemon-reload
systemctl --user restart ollama.service
podman exec ollama ollama --version

Modellen bevinden zich in de bind mount, waardoor ze de wijziging van de image ongewijzigd overleven. AutoUpdate=registry in de sectie [Container] is bedoeld voor gebruikers die een bewegende tag gebruiken. Het heeft geen nut naast een vaste versie-tag, aangezien de inhoud van die tag nooit verandert. Maak een back-up van /home/ollama/ollama-data/models/manifests en het bestand .container en sla de blobs over: deze zijn groot en ollama pull haalt ze opnieuw op bij een nieuwe installatie.

FAQ

Waarom stopt mijn rootless Podman container wanneer ik uitlog?

De systemd-instantie van een gebruiker en de bijbehorende /run/user/<uid>-directory worden verwijderd zodra de laatste sessie van die gebruiker eindigt; hiermee worden ook alle rootless containers beëindigd. Voer sudo loginctl enable-linger ollama uit en controleer of loginctl show-user ollama --property=Linger de waarde Linger=yes teruggeeft. Schakel lingering in voordat u de Quadlet-unit aanmaakt, aangezien de runtime-directory die de unit vereist alleen bestaat wanneer lingering actief is.

Heb ik SELinux-labels nodig op de Ollama model-directory?

Op Fedora, RHEL, Rocky en AlmaLinux is dit nodig als u een host-directory bind-mount. De container draait in het container_t-domein en een directory in een home-map is gelabeld als user_home_t, waardoor schrijftoegang wordt geweigerd en Ollama afsluit. Voeg :Z toe aan de Volume=-regel en gebruik een specifieke subdirectory, omdat het herlabelen recursief is en het aanwijzen van :Z naar een volledige home-directory de toegang via SSH-keys voor die gebruiker blokkeert. Named volumes worden door Podman correct gelabeld en vereisen geen extra configuratie.

Hoeveel schijfruimte heeft een Ollama model nodig?

Ga uit van de gepubliceerde downloadgrootte op ollama.com/library, die varieert van 3.3 GB voor gemma3:4b tot 19 GB voor qwen3:30b. Tel daar de Podman-image bij op en houd extra ruimte vrij, aangezien een tweede model het eerste model niet op schijf vervangt. Controleer df -h /home vóór het pullen en du -sh ~/ollama-data/models daarna. Plan het RAM-geheugen op dezelfde manier: een model heeft ongeveer de bestandsgrootte aan geheugen nodig wanneer het geladen is, plus de context window.

Is het veilig om poort 11434 open te stellen op een VPS?

Nee. Ollama wordt geleverd zonder enige vorm van authenticatie. Iedereen die de poort bereikt, kan uw modellen bekijken, verwijderen, nieuwe modellen op uw schijf plaatsen en inferentie uitvoeren met uw CPU en bandbreedte. Onversleuteld HTTP over het internet verstuurt bovendien elke prompt en elk antwoord in leesbare tekst. Bind de host-zijde aan 127.0.0.1 met PublishPort=127.0.0.1:11434:11434, controleer dit met ss -ltnp | grep 11434 en benader de service via een SSH-tunnel of een reverse proxy die om een wachtwoord vraagt.