Як безпечно розгорнути Ollama на VPS
Модель 7B потребує 8 GB RAM і працює на CPU зі швидкістю 4–10 токенів/с. Дізнайтеся, як викликати API через 127.0.0.1:11434/v1, не відкриваючи порт 11434.
Що ви створюєте
Одна open-weight мовна модель працює на сервері, який ви контролюєте, приймає запити через HTTP API і, за бажання, доступна через сторінку чату у браузері. Ollama завантажує модель, розміщує її в пам’яті та обробляє запити на http://127.0.0.1:11434. Встановлення виконується однією командою. Усе складне відбувається в інших частинах: потрібно вибрати модель, яка справді поміститься в оперативній пам’яті вашого VPS, і не опублікувати випадково сервер інференсу без автентифікації для всього інтернету.
Спочатку два важливі попередження. VPS лише з CPU повільно запускає невеликі моделі, а API взагалі не має вбудованої автентифікації. Нижче докладно розглянуто обидві проблеми, оскільки саме через них найчастіше виникають серйозні наслідки.
Перевірка реальних вимог у цифрах
Обсяг пам’яті, який потребує модель, приблизно дорівнює розміру її файлу плюс близько 1 GB накладних витрат під час роботи та додатковий обсяг для контекстного вікна. Моделі Ollama за замовчуванням квантизовані до 4 біт (позначаються як Q4). Це потребує приблизно 0.5 GB RAM на кожен мільярд параметрів. Тому розрахунок простий і визначає все.
Модель 3B, наприклад llama3.2:3b, має розмір завантаження близько 2 GB і потребує приблизно 4 GB вільної RAM для роботи. Модель 7B або 8B, наприклад mistral:7b або llama3.1:8b, займає близько 5 GB на диску та потребує приблизно 8 GB RAM; для комфортної роботи потрібно 16 GB. Моделі 13B або 14B потребують приблизно 16 GB. Для моделей у діапазоні від 30B до 70B потрібен сервер із великим обсягом RAM або, реалістично, GPU. На CPU VPS така модель або не поміститься в пам’яті, або відповідатиме настільки повільно, що буде непридатною для використання.
Тепер про швидкість, оскільки саме її часто недооцінюють. Інференс на CPU обмежений пропускною здатністю пам’яті, а не тактовою частотою. Спільний vCPU на VPS має помірну пропускну здатність. Очікуйте від однозначної до невисокої двозначної кількості токенів за секунду: модель 7-8B Q4 може обробляти приблизно від 4 до 10 токенів за секунду, а модель 3B — від 10 до 25. GPU працює приблизно на порядок швидше. Це навмисно орієнтовні значення. Правильний підхід — виміряти швидкість на власному сервері; нижче показано, як це зробити під час запуску. Довіряйте своїм eval rate, а не числу з будь-якої статті, зокрема цієї.
Практичний висновок: невеликі квантизовані моделі на CPU справді придатні для підготовки чернеток, узагальнення та класифікації, якщо вас влаштовує така швидкість. Для більших або швидших моделей закладайте бюджет на GPU instance.
Щоб порівняти конкретну модель із конкретним сервером, оцініть її потребу в пам’яті тут:
Встановлення Ollama
Є два коректні способи. На чистому VPS найпростіше скористатися офіційним скриптом:
curl -fsSL https://ollama.com/install.sh | shСкрипт створює системного користувача з іменем ollama, встановлює бінарний файл у /usr/local/bin/ollama і реєструє службу systemd з назвою ollama.service, яка запускається під час завантаження системи та прослуховує 127.0.0.1:11434. Переконайтеся, що служба працює:
systemctl status ollama
ollama --versionЯкщо ви вже використовуєте Docker, скористайтеся контейнером:
docker run -d --name ollama \
-p 127.0.0.1:11434:11434 \
-v ollama:/root/.ollama \
--restart always \
ollama/ollamaЗверніть увагу на префікс 127.0.0.1: у зіставленні портів. Він прив’язує порт лише до localhost. Якщо вказати -p 11434:11434, порт буде опубліковано на всіх інтерфейсах. Саме цієї помилки застерігає уникати розділ про безпеку. Виберіть один спосіб встановлення. Не запускайте скрипт і контейнер одночасно, інакше два процеси конкуруватимуть за порт.
Завантажте та запустіть свою першу модель
ollama pull llama3.2:3b
ollama run llama3.2:3bpull завантажує шари моделі на диск (для цієї моделі — близько 2 GB). run завантажує їх у пам’ять і відкриває запрошення >>>. Введіть запитання. Перший токен може з’явитися через кілька секунд, поки ваги завантажуються з диска в RAM. Після цього відповідь виводиться потоком. Введіть /bye, щоб завершити чат. Ollama продовжує працювати у фоновому режимі.
Перевірте, що завантажено та як це використовується:
ollama psСтовпець PROCESSOR показує фактичну ситуацію. Значення 100% CPU означає, що GPU не використовується. Саме тому робота повільна. Виміряйте реальну швидкість за допомогою прапорця verbose:
ollama run --verbose llama3.2:3b "Write two sentences about Linux."Рядок eval rate, виведений наприкінці, показує кількість токенів за секунду на цьому обладнанні. Орієнтуйтеся на це значення під час планування.
Де зберігаються моделі та скільки дискового простору потрібно
Моделі, встановлені скриптом і запущені як сервіс, зберігаються в домашньому каталозі користувача ollama:
sudo du -sh /usr/share/ollama/.ollama/modelsЯкщо запускати їх інтерактивно від власного користувача, вони зберігаються в ~/.ollama/models. У контейнері вони розміщуються в іменованому томі ollama. Це важливо, оскільки квантовані ваги швидко займають багато місця: модель 3B потребує приблизно 2 GB, модель 7-8B — приблизно 5 GB, а модель 14B — приблизно 9 GB. Якщо завантажити чотири моделі для порівняння, непомітно можна витратити 20 GB. Розрахуйте обсяг диска для моделей, які плануєте залишити, а решту видаліть за допомогою ollama rm <model>. Якщо на тому самому VPS уже працює сервіс із великим власним споживанням дискового простору, наприклад PhotoPrism або Immich зі збереженою фототекою, спочатку відніміть його обсяг від вільного місця. Залишок вважайте реальним бюджетом дискового простору для моделей.
Запустіть його як керований сервіс
Скрипт інсталяції вже зареєстрував ollama.service, тому після завантаження системи він перезапускається без додаткових дій. Варто змінити тривалість зберігання моделі в пам’яті та, у деяких конфігураціях, адресу прив’язки. Обидва параметри задаються у drop-in systemd, щоб оновлення Ollama їх не перезаписало:
sudo systemctl edit ollama.serviceДодайте це під заголовком [Service], який показує редактор:
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"OLLAMA_KEEP_ALIVE визначає, як довго модель залишається в пам’яті після останнього запиту (типове значення — 5 minutes). Збільште це значення на сервері, до якого звертаються протягом усього дня, щоб не завантажувати ваги щоразу. На сервері з обмеженим обсягом пам’яті встановіть 0, щоб звільняти RAM одразу після завершення запиту. systemctl edit перезавантажує для вас unit-файли, тому для застосування зміни перезапустіть сервіс:
sudo systemctl restart ollamaНайважливіший аспект безпеки
За замовчуванням Ollama прослуховує 127.0.0.1:11434, тому доступ до нього мають лише процеси на самому VPS. Це правильне налаштування. Не змінюйте його.
API не має автентифікації. Взагалі. Немає API key, входу, обмеження частоти запитів або allow-list. Будь-хто, хто може отримати доступ до порту 11434, може запускати будь-яку завантажену модель, завантажувати нові моделі, видаляти їх і безстроково навантажувати CPU або GPU на 100%. Сканери на кшталт Shodan індексують тисячі відкритих екземплярів Ollama, а відкритий екземпляр знаходять і використовують зловмисники протягом кількох годин.
Отже, ось єдина помилка, якої не можна припускатися: не встановлюйте OLLAMA_HOST=0.0.0.0 і не відкривайте порт 11434 у firewall. Це відкриє неавтентифікований inference server для всього інтернету. Жодні налаштування не зроблять прямий доступ до 11434 через 0.0.0.0 безпечним, оскільки в Ollama немає чого налаштовувати: автентифікація там просто відсутня. Це правило стосується саме цього сервісу, а не є забороною на відкриття портів узагалі: self-hosted relay RustDesk для віддаленого робочого столу має приймати публічний трафік, щоб виконувати свою функцію, і це виправдано наявністю власної автентифікації на основі ключів та короткого задокументованого списку портів. В Ollama немає ні того, ні іншого.
Є три безпечні способи отримати доступ до моделі не з самого сервера:
- Залиште доступ локальним. Якщо єдиним клієнтом є інша програма на тому самому VPS, cron-скрипт, бот або MCP-сервер, який з’єднує ваші інструменти з моделлю, залиште прив’язку на
127.0.0.1і налаштуйте цю програму на звернення доhttp://127.0.0.1:11434. Нічого не відкрито, і більше нічого не потрібно. - Використовуйте доступ через приватний тунель. Підключіть VPS до WireGuard VPN, який ви адмініструєте самостійно, встановіть
OLLAMA_HOSTна адресу тунелю, наприклад10.8.0.1, а не0.0.0.0, і лише VPN-піри зможуть підключатися. Публічний інтернет і далі не бачитиме нічого на порту 11434. - Розмістіть reverse proxy з автентифікацією перед Ollama. Завершуйте TLS і вимагайте пароль або токен на nginx, Traefik чи Caddy, а потім проксируйте запити до
127.0.0.1:11434. Ollama зберігає прив’язку до localhost, а reverse proxy буде єдиним компонентом, який прослуховує публічний порт. Це така сама схема, як розміщення сертифіката Let’s Encrypt на nginx перед будь-яким локальним сервісом.
Саме такий варіант із reverse proxy реалізує chat UI у наступному розділі, додаючи повноцінний вхід до системи.
Додайте чат-інтерфейс за допомогою Open WebUI під захистом TLS
Open WebUI — це self-hosted інтерфейс чату. Запустіть його в Docker і підключіть до локального Ollama:
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Прапорець --network=host є важливою деталлю для Linux VPS. Він розміщує контейнер у мережевому просторі імен хоста, тому 127.0.0.1 усередині контейнера є власним loopback хоста, а контейнер підключається до Ollama через 127.0.0.1:11434, не змушуючи Ollama слухати на будь-якому іншому інтерфейсі. Рецепт із bridge network, який ви побачите в іншому місці, --add-host=host.docker.internal:host-gateway разом із OLLAMA_BASE_URL=http://host.docker.internal:11434, тут не працює: це ім’я перетворюється на адресу шлюзу Docker bridge, а сервіс, прив’язаний до 127.0.0.1 на хості, недоступний через bridge. Тому Open WebUI просто повідомляє, що не може підключитися до Ollama.
Недолік host networking полягає в тому, що Open WebUI тепер слухає порт 8080 хоста на всіх інтерфейсах. Будь-яке зіставлення -p ігнорується, і Docker виводить відповідне попередження. Тому закрийте 8080 у firewall хоста та firewall провайдера і залиште TLS reverse proxy єдиною публічною точкою доступу. Під час першого відвідування Open WebUI попросить створити обліковий запис адміністратора. Цей обліковий запис є вашим рівнем автентифікації, тому виберіть надійний пароль.
Щоб відкрити чат із ноутбука через HTTPS, розмістіть TLS reverse proxy перед 127.0.0.1:8080. Якщо на цьому сервері вже маршрутизується кілька Docker-застосунків, Traefik з автоматичним TLS для багатьох застосунків буде найзручнішим варіантом: один блок labels випускає сертифікат і маршрутизує chat.example.com до Open WebUI. Правило з розділу про безпеку залишається чинним: проксі керує публічним портом і входом, тоді як Ollama залишається на localhost, а власний 8080 Open WebUI залишається закритим у firewall.
Використовуйте OpenAI-сумісний endpoint у своєму коді
Ollama підтримує підмножину Chat API OpenAI за адресою /v1, тому більшість клієнтських бібліотек OpenAI працює після зміни двох параметрів: базової URL-адреси та тимчасового ключа.
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)api_key потрібен клієнтській бібліотеці, але Ollama його ігнорує, тому можна вказати будь-який рядок. model має містити назву моделі, яку вже завантажено; для невідомої назви повертається model "x" not found, try pulling it first. Звичайний виклик curl працює за тим самим принципом:
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"}]}'Так само модель підключають до інструментів для роботи з агентами та редакторами. Якщо ви вже розробляєте на цьому сервері, локальна модель може обслуговувати скрипти й плагіни разом із Claude Code, запущеним на VPS у tmux, щоб недорогі приватні чернетки не надсилалися до платного API, а складні міркування виконувала hosted-модель.
Режими відмови з точними рядками, які ви побачите
Процес було «Killed» під час генерації. Ви запускаєте велику модель, а термінал виводить Killed або журнал сервера містить llama runner process has terminated: signal: killed. Процес зупинив Linux OOM killer, оскільки моделі потрібно більше RAM, ніж має сервер. Підтвердьте причину за допомогою sudo dmesg | grep -i oom. Ви побачите рядок на кшталт Out of memory: Killed process ... (ollama). Рішення — використати меншу модель або модель із агресивнішим квантуванням: llama3.2:3b замість 13B. Також можна додати swap, щоб навантаження, якому лише трохи не вистачає фізичної RAM, повільно завершувалося, а не аварійно зупинялося. Swap перетворює миттєвий збій на повільну відповідь. Він не робить модель 70B практичною на сервері з 4 GB. Процес завершується без повідомлення, якщо ви саме в цей момент не стежите за терміналом. Якщо ви надсилаєте запити до сервера з іншого пристрою, підключіть unit OnFailure= до ollama.service. Він надсилатиме повідомлення на сервер ntfy, який ви розгорнули для push-сповіщень, і ви дізнаєтеся про завершення процесу одразу, а не під час наступного запиту.
«Error: model requires more system memory». Ollama відмовляється запускати модель і виводить Error: model requires more system memory (X GiB) than is available (Y GiB). Це коректний варіант попередньої помилки: Ollama обчислює потребу в пам’яті й зупиняється, не передаючи процес OOM killer. Також програма показує два значення. Виберіть модель, вимоги якої нижчі за обсяг вільної RAM; перевірте його за допомогою free -h. Також можна зменшити довжину контексту або перейти на більший VPS. Жоден прапорець не дасть змоги вмістити модель, якщо їй фактично бракує пам’яті.
Перший токен з’являється дуже довго, а потім усе працює нормально. Холодна модель не виводить нічого від п’яти до тридцяти секунд, після чого зазвичай передає відповідь потоково. Це означає, що під час першого запуску ваги завантажуються з диска в RAM. Повільне сховище збільшує цю затримку. Після завантаження модель залишається в пам’яті протягом усього часу OLLAMA_KEEP_ALIVE, тому на другий запит відповідає одразу. Якщо перше завантаження перевищує тайм-аут на будь-якому етапі обробки запиту, ви отримаєте помилку, а не повільну відповідь. У статті як визначити, який рівень повідомив про перевищення дедлайну контексту пояснюється, як з’ясувати, чи тайм-аут спрацював на стороні клієнта, проксі або самого завантаження. Збільште це значення, якщо такі паузи заважають. Використовуйте ollama ps, щоб перевірити, чи завантажена зараз модель.
Усе працює просто повільно. Швидкість становить десять токенів за секунду або менше, але помилок немає. Це інференс на CPU, який працює саме так. ollama ps показує 100% CPU, тобто GPU немає. Це не помилка, і жодне налаштування її не усуне, оскільки обмеження визначається пропускною здатністю пам’яті, а не неправильною конфігурацією. Використайте меншу модель, прийміть таку швидкість або перейдіть на інстанс із GPU. Перед висновком, що щось зламано, виміряйте фактичну швидкість за допомогою --verbose.
Підключення з іншої машини відхилено. На ноутбуці ви отримуєте curl: (7) Failed to connect to <ip> port 11434: Connection refused. Це очікувана поведінка: Ollama прослуховує лише localhost. Не «виправляйте» це прив’язуванням до 0.0.0.0, оскільки саме так виникає описана вище помилка з відкритим доступом. Підключайтеся до моделі через VPN або проксі з автентифікацією.
Ви відкрили порт 11434 для інтернету. Якщо ви налаштували OLLAMA_HOST=0.0.0.0, відкрили порт у firewall і тепер бачите завантаження моделей, яких не запускали, або завантаження CPU на 100% через невідомих клієнтів, сервер було виявлено та використано сторонніми особами. Це типова критична помилка, а не рідкісний випадок. Прив’яжіть сервіс до 127.0.0.1 або адреси VPN, закрийте порт 11434 у firewall і додайте автентифікацію перед сервісом. Вважайте, що до всього, що було доступне за цією адресою, поки порт залишався відкритим, зверталися сторонні користувачі.
Резервне копіювання та оновлення
Стану, який можна втратити, небагато. Моделі можна завантажити повторно, тому варто резервно копіювати лише том даних Open WebUI, облікові записи, історію чатів, налаштування та створений вами drop-in для systemd. Створіть резервну копію тому за допомогою тимчасового контейнера:
docker run --rm -v open-webui:/data -v "$PWD":/backup alpine \
tar czf /backup/open-webui.tgz -C /data .Оновіть Ollama, повторно запустивши інсталяційний скрипт. Щоб оновити Open WebUI, виконайте docker pull ghcr.io/open-webui/open-webui:main, а потім створіть контейнер повторно. Не фіксуйте версії надовго: якість моделей і середовище виконання швидко змінюються. Прочитайте примітки до випуску та повторно перевірте продуктивність на власному сервері, а не покладайтеся на показники за минулий квартал.
FAQ
Чи справді можна запустити LLM на VPS лише з CPU?
Так, але з обмеженнями. Невеликі квантизовані моделі в діапазоні від 3B до 8B працюють на CPU і справді корисні для підготовки чернеток, узагальнення та класифікації. Однак вони працюють повільно: на спільному vCPU швидкість становить від однозначної до низької двозначної кількості токенів за секунду. Моделі від 13B і більші працюють дуже повільно або взагалі не поміщаються в RAM. Для високої швидкості або більших моделей потрібен інстанс із GPU.
Скільки RAM потребує кожна модель?
Для стандартних квантизованих моделей із точністю 4 біти можна орієнтуватися на приблизно 0.5 GB RAM на кожен мільярд параметрів для ваг, а також ще приблизно 1 GB службових витрат і трохи більше пам’яті для контексту. Тому для моделі 3B потрібно близько 4 GB вільної пам’яті, для моделі 7-8B — близько 8 GB, а для моделі 14B — близько 16 GB. Перевірте доступний запас пам’яті за допомогою free -h і залиште місце для операційної системи та інших процесів на сервері.
Чи має API Ollama автентифікацію?
Ні. Ollama не має вбудованої автентифікації, API key або обмеження частоти запитів. Будь-хто, хто має доступ до порту 11434, отримує повний контроль над ним. Саме тому за замовчуванням Ollama прив’язується до 127.0.0.1 і порт 11434 не можна відкривати для інтернету на 0.0.0.0. Підключайтеся до нього локально, через приватний VPN або через reverse proxy, який додає автентифікацію.
Як додати вебінтерфейс для чату?
Запустіть Open WebUI у Docker з параметром --network=host, щоб він використовував loopback хоста та підключався до нативного Ollama через http://127.0.0.1:11434. Потім налаштуйте перед його портом 8080 reverse proxy з TLS для доступу з вашого ноутбука. Залиште 8080 закритим у firewall, щоб reverse proxy був єдиною публічно доступною точкою входу. Власний обліковий запис адміністратора Open WebUI забезпечує вхід у систему. Пароль для нього задається під час першого запуску.
Як звертатися до нього з власного застосунку?
Використовуйте сумісний з OpenAI endpoint за адресою http://127.0.0.1:11434/v1. Вкажіть цю базову URL-адресу в будь-якому OpenAI SDK, передайте будь-який рядок як API key, оскільки він ігнорується, і встановіть model у назву завантаженої моделі. Наявний код для OpenAI зазвичай працює без змін, крім базової URL-адреси та key.