SSD Nodes Learn
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-07-19

Ollama sur un VPS : héberger son propre LLM

Hébergez un LLM avec Ollama sur un VPS : dimensionnement CPU, installation, systemd, pourquoi ne jamais exposer le port 11434, et Open WebUI derrière TLS.

Ce que vous construisez

Un seul modèle de langage à poids ouverts qui tourne sur un serveur qui vous appartient, accessible via une API HTTP et, si vous le souhaitez, une page de chat dans votre navigateur. Ollama est le composant qui télécharge le modèle, le charge en mémoire et répond aux requêtes sur http://127.0.0.1:11434. L'installation tient en une seule commande. Tout ce qui est difficile ici se trouve ailleurs : choisir un modèle que votre VPS peut réellement contenir en RAM, et ne pas publier par accident un serveur d'inférence sans authentification sur tout l'internet.

D'abord deux avertissements honnêtes. Un VPS sans GPU (CPU uniquement) fait tourner les petits modèles lentement, et l'API ne dispose d'aucune authentification intégrée. Les deux sont détaillés plus bas, car c'est là que les gens se font piéger.

Le point sur le dimensionnement, en chiffres clairs

L'empreinte mémoire d'un modèle correspond à peu près à la taille de son fichier, plus environ un gigaoctet de surcoût d'exécution, plus un peu plus pour la fenêtre de contexte. Les modèles par défaut d'Ollama sont quantifiés sur 4 bits (étiquetés Q4), ce qui coûte environ un demi-gigaoctet de RAM par milliard de paramètres. Le calcul est donc simple, et il décide de tout.

Un modèle 3B comme llama3.2:3b représente un téléchargement d'environ 2 Go et demande à peu près 4 Go de RAM libre pour tourner. Un modèle 7B ou 8B comme mistral:7b ou llama3.1:8b occupe environ 5 Go sur le disque et demande à peu près 8 Go de RAM, 16 Go pour être à l'aise. Un modèle 13B ou 14B demande environ 16 Go. Tout ce qui se situe entre 30B et 70B nécessite une machine à grande RAM ou, de façon réaliste, un GPU : sur un VPS CPU, soit il ne rentre pas, soit il répond si lentement qu'il devient inutile.

Maintenant la vitesse, car c'est la partie que les gens sous-estiment. L'inférence sur CPU est limitée par la bande passante mémoire, pas par la fréquence d'horloge, et un VPS à vCPU partagé dispose d'une bande passante modeste. Attendez-vous à un débit d'un seul chiffre à un petit nombre à deux chiffres de tokens par seconde : un modèle 7-8B en Q4 peut atteindre 4 à 10 tokens par seconde, un modèle 3B de 10 à 25. Un GPU est environ un ordre de grandeur plus rapide. Ces chiffres sont volontairement approximatifs : la démarche honnête consiste à mesurer votre propre machine, ce que l'étape d'exécution ci-dessous montre comment faire. Fiez-vous à votre eval rate, pas à un chiffre dans un article, celui-ci compris.

La conclusion pratique : les petits modèles quantifiés sur CPU sont réellement utiles pour rédiger des brouillons, résumer et classer si vous acceptez le rythme. Pour tout ce qui est plus gros ou plus rapide, prévoyez le budget d'une instance GPU.

Pour évaluer un modèle précis face à une machine précise, estimez son empreinte mémoire ici :

ToolCalculateur de VRAM et de taille de modèle LLM

Installer Ollama

Il existe deux méthodes propres. Le script officiel est le plus simple sur un VPS vierge :

curl -fsSL https://ollama.com/install.sh | sh

Cela crée un utilisateur système nommé ollama, installe le binaire dans /usr/local/bin/ollama et enregistre un service systemd appelé ollama.service qui démarre au boot et se lie à 127.0.0.1:11434. Vérifiez qu'il est actif :

systemctl status ollama
ollama --version

Si vous utilisez déjà Docker, utilisez plutôt le conteneur :

docker run -d --name ollama \
  -p 127.0.0.1:11434:11434 \
  -v ollama:/root/.ollama \
  --restart always \
  ollama/ollama

Remarquez le préfixe 127.0.0.1: dans le mappage de port. Il lie le port à localhost uniquement. Écrire -p 11434:11434 à la place le publie sur toutes les interfaces, ce qui est l'erreur contre laquelle la section sécurité vous met en garde. Choisissez une seule méthode d'installation ; ne lancez pas le script et le conteneur en même temps, sinon deux processus se disputent le port.

Télécharger et lancer votre premier modèle

ollama pull llama3.2:3b
ollama run llama3.2:3b

pull télécharge les couches du modèle sur le disque (environ 2 Go pour celui-ci). run les charge en mémoire et vous dépose devant une invite >>>. Tapez une question. Le premier token peut prendre plusieurs secondes pendant que les poids se chargent du disque vers la RAM, puis la réponse s'affiche au fil de l'eau. Tapez /bye pour quitter le chat ; Ollama continue de tourner en arrière-plan.

Voyez ce qui est chargé et comment cela tient en mémoire :

ollama ps

La colonne PROCESSOR dit la vérité. 100% CPU signifie qu'aucun GPU n'est impliqué, et c'est de là que vient la lenteur. Mesurez la vitesse réelle avec l'option verbose :

ollama run --verbose llama3.2:3b "Write two sentences about Linux."

La ligne eval rate affichée à la fin correspond à votre nombre de tokens par seconde sur ce matériel. C'est le chiffre autour duquel planifier.

Où vivent les modèles, et combien de disque acheter

Installés par le script et exécutés en tant que service, les modèles vivent dans le répertoire personnel de l'utilisateur ollama :

sudo du -sh /usr/share/ollama/.ollama/models

Exécutés de façon interactive avec votre propre utilisateur, ils se trouvent dans ~/.ollama/models. Dans le conteneur, ils vivent dans le volume nommé ollama. Cela compte car les poids quantifiés s'accumulent vite : un 3B fait environ 2 Go, un 7-8B environ 5 Go, un 14B environ 9 Go. Téléchargez quatre modèles pour les comparer et vous avez dépensé 20 Go sans vous en apercevoir. Dimensionnez le disque pour les modèles que vous comptez garder, et supprimez le reste avec ollama rm <model>.

Le faire tourner comme un service que vous contrôlez

Le script d'installation a déjà enregistré ollama.service, il redémarre donc au boot sans autre effort. Le réglage qui vaut la peine d'être changé est la durée pendant laquelle un modèle reste résident en mémoire et, sur certaines configurations, l'adresse de liaison : les deux se placent dans un drop-in systemd afin qu'une mise à jour d'Ollama ne les écrase pas :

sudo systemctl edit ollama.service

Ajoutez ceci sous l'en-tête [Service] que l'éditeur vous affiche :

[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"

OLLAMA_KEEP_ALIVE correspond à la durée pendant laquelle un modèle reste en mémoire après la dernière requête (5 minutes par défaut). Augmentez-la sur une machine que vous interrogez toute la journée pour éviter de recharger les poids à chaque fois ; réglez-la sur 0 sur une machine à la mémoire serrée pour libérer la RAM dès qu'une requête se termine. systemctl edit recharge les fichiers d'unité pour vous, redémarrez donc pour appliquer le changement :

sudo systemctl restart ollama

Le point de sécurité le plus important

Par défaut, Ollama se lie à 127.0.0.1:11434, si bien que seuls les processus du VPS lui-même peuvent l'atteindre. Ce réglage par défaut est correct. Gardez-le.

L'API n'a aucune authentification. Aucune. Il n'y a pas de clé d'API, pas de connexion, pas de limitation de débit, pas de liste d'autorisation. Quiconque peut atteindre le port 11434 peut exécuter n'importe quel modèle que vous avez téléchargé, en télécharger de nouveaux, les supprimer et saturer votre CPU ou votre GPU à pleine charge indéfiniment. Des scanners comme Shodan indexent des milliers d'instances Ollama ouvertes, et une instance exposée est trouvée et abusée en quelques heures.

Voici donc l'unique erreur à ne jamais commettre : ne définissez pas OLLAMA_HOST=0.0.0.0 et n'ouvrez pas le port 11434 dans votre pare-feu. Cela publie un serveur d'inférence sans authentification sur tout l'internet. Aucune quantité de configuration ne rend le port 11434 brut sur 0.0.0.0 sûr, car il n'y a rien à configurer dans Ollama : l'authentification n'existe tout simplement pas.

Il existe trois façons sûres d'atteindre le modèle depuis un autre endroit que la machine elle-même :

  • Gardez-le local. Si le seul appelant est un autre programme sur le même VPS, un script cron, un bot, un serveur MCP qui relie vos outils au modèle, laissez la liaison sur 127.0.0.1 et faites en sorte que ce programme appelle http://127.0.0.1:11434. Rien n'est exposé et rien d'autre n'est nécessaire.
  • Atteignez-le via un tunnel privé. Placez le VPS sur un VPN WireGuard que vous hébergez vous-même, définissez OLLAMA_HOST sur l'adresse du tunnel (par exemple 10.8.0.1, pas 0.0.0.0), et seuls les pairs du VPN peuvent se connecter. L'internet public ne voit toujours rien sur le port 11434.
  • Placez devant un proxy inverse avec authentification. Terminez le TLS et exigez un mot de passe ou un token sur nginx, Traefik ou Caddy, puis relayez vers 127.0.0.1:11434. Ollama conserve sa liaison sur localhost ; le proxy est la seule chose qui écoute sur le port public. C'est la même structure que placer un certificat Let's Encrypt sur nginx devant n'importe quel service local.

L'option du proxy inverse est exactement ce que l'interface de chat vous offre ensuite, avec une véritable authentification attachée.

Ajouter une interface de chat avec Open WebUI, derrière TLS

Open WebUI est une interface de chat auto-hébergée. Lancez-la dans Docker et pointez-la vers l'Ollama local :

docker run -d \
  --name open-webui \
  --network=host \
  -e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
  -v open-webui:/app/backend/data \
  --restart always \
  ghcr.io/open-webui/open-webui:main

L'option --network=host est le détail important sur un VPS Linux. Elle place le conteneur dans l'espace de noms réseau de l'hôte, de sorte que 127.0.0.1 à l'intérieur du conteneur est le loopback de l'hôte lui-même et que le conteneur atteint Ollama sur 127.0.0.1:11434 sans qu'Ollama écoute sur une autre interface. La recette avec réseau bridge que vous verrez ailleurs, --add-host=host.docker.internal:host-gateway avec OLLAMA_BASE_URL=http://host.docker.internal:11434, ne fonctionne pas ici : ce nom se résout vers la passerelle du bridge Docker, et un service lié à 127.0.0.1 sur l'hôte n'est pas joignable à travers le bridge, si bien qu'Open WebUI reste bloqué en signalant qu'il ne peut pas se connecter à Ollama.

Le compromis du réseau hôte est qu'Open WebUI écoute désormais sur le port 8080 de l'hôte sur toutes les interfaces ; tout mappage -p est ignoré, et Docker affiche un avertissement le signalant. Fermez donc le port 8080 à la fois sur le pare-feu de l'hôte et sur celui du fournisseur, et laissez le proxy inverse TLS être la seule porte publique. Lors de la toute première visite, Open WebUI vous demande de créer un compte administrateur : ce compte est votre couche d'authentification, choisissez donc un mot de passe fort.

Pour ouvrir le chat depuis votre ordinateur portable en HTTPS, placez un proxy inverse TLS devant 127.0.0.1:8080. Si vous routez déjà plusieurs applications Docker sur la machine, Traefik avec TLS automatique sur de nombreuses applications est la solution la plus propre : un seul bloc de labels émet le certificat et route chat.example.com vers Open WebUI. La règle de la section sécurité tient toujours : le proxy possède le port public et l'authentification, tandis qu'Ollama reste sur localhost et que le port 8080 d'Open WebUI reste protégé par le pare-feu.

Utiliser le point de terminaison compatible OpenAI depuis votre code

Ollama parle un sous-ensemble de l'API de chat OpenAI sur /v1, si bien que la plupart des bibliothèques clientes OpenAI fonctionnent après avoir changé deux choses : l'URL de base et une clé jetable.

from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:11434/v1", api_key="ollama")

resp = client.chat.completions.create(
    model="llama3.2:3b",
    messages=[{"role": "user", "content": "Name three Linux distributions."}],
)
print(resp.choices[0].message.content)

La api_key est requise par la bibliothèque cliente mais ignorée par Ollama, n'importe quelle chaîne fonctionne donc. model doit être un nom que vous avez déjà téléchargé ; un nom inconnu renvoie model \"x\" not found, try pulling it first. Un simple appel curl repose sur la même idée :

curl http://127.0.0.1:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3.2:3b","messages":[{"role":"user","content":"Hello"}]}'

C'est aussi ainsi que vous branchez le modèle sur des outils d'agent et d'éditeur. Si vous développez déjà sur la machine, un modèle local peut alimenter des scripts et des plugins aux côtés de Claude Code qui tourne sur le VPS dans tmux, en gardant le travail de rédaction bon marché et privé hors d'une API payante tandis que le raisonnement lourd reste confié à un modèle hébergé.

Modes de défaillance, avec les messages exacts que vous verrez

Le processus est « Killed » en pleine génération. Vous lancez un gros modèle et le terminal affiche Killed, ou le journal du serveur montre llama runner process has terminated: signal: killed. Le OOM killer de Linux (tueur en cas de manque de mémoire) l'a arrêté parce que le modèle avait besoin de plus de RAM que la machine n'en a. Confirmez la cause avec sudo dmesg | grep -i oom, où vous verrez une ligne du type Out of memory: Killed process ... (ollama). La solution est un modèle plus petit ou plus fortement quantifié, llama3.2:3b au lieu d'un 13B, ou l'ajout de swap pour qu'une charge qui ne fait que déborder de peu la RAM physique survive lentement au lieu de mourir. Le swap transforme un crash instantané en une réponse lente ; il ne rend pas un modèle 70B praticable sur 4 Go.

« Error: model requires more system memory ». Ollama refuse de démarrer le modèle et affiche Error: model requires more system memory (X GiB) than is available (Y GiB). C'est la version polie du crash ci-dessus : Ollama a fait le calcul et s'est arrêté plutôt que de laisser le OOM killer agir. Il vous donne même les deux chiffres. Choisissez un modèle dont le besoin est inférieur à votre RAM libre (vérifiez avec free -h), réduisez la longueur du contexte, ou passez à un VPS plus grand. Aucune option ne fait rentrer le modèle : la mémoire est bien réelle.

Le premier token prend une éternité, puis tout va bien. Un modèle froid n'affiche rien pendant cinq à trente secondes, puis répond normalement au fil de l'eau. Cette pause correspond aux poids qui se chargent du disque vers la RAM pour la première fois, et un stockage lent l'aggrave. Une fois chargé, le modèle reste résident pendant la durée de OLLAMA_KEEP_ALIVE, de sorte que la deuxième requête répond instantanément. Augmentez cette valeur si les pauses vous agacent, et utilisez ollama ps pour voir si un modèle est actuellement chargé.

Tout est simplement lent. Dix tokens par seconde ou moins, sans aucune erreur. C'est l'inférence CPU qui fait exactement ce que fait l'inférence CPU. ollama ps affiche 100% CPU, ce qui signifie qu'il n'y a pas de GPU. Ce n'est pas un bug et aucun réglage ne le corrige, car la limite est la bande passante mémoire, pas une mauvaise configuration. Utilisez un modèle plus petit, acceptez la vitesse, ou passez à une instance GPU, et mesurez votre débit réel avec --verbose avant de décider que quoi que ce soit est cassé.

Connexion refusée depuis une autre machine. Depuis votre ordinateur portable, vous obtenez curl: (7) Failed to connect to <ip> port 11434: Connection refused. C'est le comportement prévu : Ollama se lie à localhost uniquement. Ne « corrigez » pas cela en vous liant à 0.0.0.0, ce qui est précisément l'erreur d'exposition ci-dessus. Atteignez plutôt le modèle via le VPN ou à travers le proxy avec authentification.

Vous avez exposé le port 11434 sur l'internet. Si vous avez bien défini OLLAMA_HOST=0.0.0.0, ouvert le pare-feu, et que vous voyez maintenant des téléchargements de modèles que vous n'avez jamais lancés ou le CPU bloqué à 100% par des clients inconnus, vous avez été trouvé et exploité. C'est l'erreur majeure, pas un cas marginal. Reliez-vous de nouveau à 127.0.0.1 ou à l'adresse du VPN, fermez le port 11434 sur le pare-feu, et placez une authentification devant. Partez du principe que tout ce qui était joignable à cette adresse pendant qu'elle était ouverte a été interrogé par des inconnus.

Sauvegardes et mises à jour

Il y a peu d'état à perdre. Les modèles sont retéléchargeables, si bien que les seules choses qui valent la peine d'être sauvegardées sont le volume de données d'Open WebUI, à savoir les comptes, l'historique des chats et les réglages, ainsi que tout drop-in systemd que vous avez écrit. Sauvegardez le volume avec un conteneur jetable :

docker run --rm -v open-webui:/data -v "$PWD":/backup alpine \
  tar czf /backup/open-webui.tgz -C /data .

Mettez à jour Ollama en relançant le script d'installation ; mettez à jour Open WebUI avec docker pull ghcr.io/open-webui/open-webui:main suivi de la recréation du conteneur. Ne figez rien sur le long terme : la qualité des modèles comme le runtime évoluent vite, lisez donc les notes de version et refaites vos mesures sur votre propre machine plutôt que de vous fier aux chiffres du trimestre dernier.

FAQ

Puis-je vraiment faire tourner un LLM sur un VPS sans GPU ?

Oui, dans certaines limites. Les petits modèles quantifiés dans la plage 3B à 8B tournent sur CPU et sont réellement utiles pour rédiger des brouillons, résumer et classer, mais lentement, à un débit d'un seul chiffre à un petit nombre à deux chiffres de tokens par seconde sur un vCPU partagé. Tout ce qui va de 13B vers le haut est douloureusement lent ou ne tient tout simplement pas en RAM. Pour une vraie vitesse ou des modèles plus grands, il vous faut une instance GPU.

De combien de RAM chaque modèle a-t-il besoin ?

Une règle approximative pour les modèles par défaut quantifiés sur 4 bits : environ 0,5 Go de RAM par milliard de paramètres pour les poids, plus à peu près 1 Go de surcoût et un peu plus pour le contexte. Ainsi un modèle 3B demande environ 4 Go libres, un modèle 7-8B environ 8 Go, et un modèle 14B environ 16 Go. Vérifiez votre marge avec free -h et laissez de la place pour le système d'exploitation et tout ce qui tourne d'autre sur la machine.

L'API Ollama est-elle authentifiée ?

Non. Ollama n'a aucune authentification intégrée, aucune clé d'API ni limitation de débit ; quiconque peut atteindre le port 11434 en a le contrôle total. C'est exactement pourquoi il se lie à 127.0.0.1 par défaut et pourquoi vous ne devez jamais exposer le port 11434 sur 0.0.0.0 vers l'internet. Atteignez-le localement, via un VPN privé, ou à travers un proxy inverse qui ajoute une authentification.

Comment ajouter une interface de chat web ?

Lancez Open WebUI dans Docker avec --network=host pour qu'il partage le loopback de l'hôte et atteigne l'Ollama natif sur http://127.0.0.1:11434, puis placez un proxy inverse TLS devant son port 8080 pour l'accès depuis votre ordinateur portable. Gardez le port 8080 fermé sur le pare-feu afin que le proxy soit la seule porte publique. Le compte administrateur propre à Open WebUI fournit l'authentification, et vous définissez son mot de passe au premier lancement.

Comment l'appeler depuis ma propre application ?

Utilisez le point de terminaison compatible OpenAI à http://127.0.0.1:11434/v1. Pointez n'importe quel SDK OpenAI vers cette URL de base, passez n'importe quelle chaîne comme clé d'API puisqu'elle est ignorée, et réglez model sur un nom que vous avez téléchargé. Le code OpenAI existant tourne généralement sans changement à part l'URL de base et la clé.