SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor

Як розгорнути Iva як Telegram AI-асистента

Розгорніть Iva на невеликому VPS без відкритих портів і домену: systemd user services, long polling Telegram та резервне копіювання Obsidian-сховища.

Що ви створюєте

Iva — це self-hosted Telegram AI assistant. Це один із небагатьох таких застосунків, який можна розгорнути без відкриття вхідного порту та без прив’язування домену. Сертифікат також не потрібен, оскільки на сервері немає служби, що приймає публічні підключення. Сервіс сам встановлює вихідне підключення до Telegram, підтримує його відкритим і читає ваші повідомлення з відповіді. Усе інше випливає з цього єдиного вихідного підключення.

Iva має ліцензію MIT і написана на Node. Її пам’ять — це папка зі звичайними markdown-файлами, які Obsidian відкриває безпосередньо. Тому нотатки, які застосунок зберігає про вас, залишаються доступними для читання без нього. У цьому посібнику зафіксовано release v0.3.13, опублікований 6 August 2026. Відтоді назву repository змінено з smixs/iva на smixs/iva-agent, і наведені нижче команди використовують нову назву.

Більшість self-hosted застосунків починається із запису DNS (domain name system) і сертифіката Let's Encrypt, виданого за допомогою Certbot. Iva повністю пропускає цей рівень. Тому для повного розгортання достатньо невеликого VPS за firewall, який дозволяє лише SSH.

Чому Iva не потребує відкритих портів

iva-telegram-poll.service — це міст long polling. Він звертається до getUpdates API Telegram і очікує на відповідь, тому кожне з’єднання починається з вашого сервера. Telegram ніколи не підключається назад. Тому не потрібно налаштовувати reverse proxy або поновлювати сертифікати.

Сам агент прослуховує лише порт 8723 на 127.0.0.1. Документація проєкту прямо вказує: не відкривайте порт 8723 назовні, а reverse proxy перед агентом має зберігати вимогу bearer token. Після встановлення перевірте адресу прив’язки.

sudo ss -tlnp | grep 8723

Адреса має бути 127.0.0.1:8723. Адреса з wildcard, наприклад 0.0.0.0:8723, робить HTTP-маршрути агента доступними з інтернету. Це потрібно виправити до того, як ви передасте боту будь-які приватні дані.

Тому firewall залишається закритим. Перед увімкненням дозвольте SSH, оскільки ufw enable без правила для SSH закриє поточний сеанс.

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Що насправді робить інсталятор в один рядок

На головній сторінці проєкту наведено одну команду, яка передає скрипт із GitHub у bash. Спочатку прочитайте цей скрипт, оскільки він робить значно більше, ніж установлює одну програму.

curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh -o iva-install.sh
less iva-install.sh
  • Він установлює системні пакети за допомогою виявленого менеджера пакетів: git, gh, python3, ffmpeg, pandoc і poppler-utils.
  • Він створює swapfile розміром 2 GB у /swapfile, якщо на сервері менше ніж 1.5 GB RAM і немає swap. Без нього процес збірки завершується через нестачу пам’яті.
  • Він установлює nvm, а потім Node 24 — мінімальну версію, на якій працює Iva.
  • Він установлює uv, менеджер пакетів Python, у ~/.local/bin.
  • Він клонує репозиторій у ~/iva і запускає npm ci.
  • Він установлює agent-browser як глобальний npm-пакет. Після цього пакет завантажує Chromium і розміщує Google Workspace CLI, gws, у ~/.local без sudo.
  • Він запускає майстер налаштування, збирає проєкт і створює сховище.
  • Він записує команду iva у ~/.local/bin і встановлює користувацькі unit-файли systemd.

Для однієї команди це багато програм. Це також пояснює інструкцію в README: установлюйте програму від імені звичайного користувача, а не root. Пізніше shell tool агента працює з привілеями, які мав інсталятор. Скрипт викликає sudo лише для встановлення пакетів і створення swapfile, а також, можливо, ще один раз для встановлення Chromium. Для цього використовується один допоміжний засіб, який виконує команди безпосередньо, якщо ви вже працюєте від імені root.

Створіть окремого користувача перед встановленням

Створіть для Iva окремий обліковий запис. Агент виконує команди shell на хості через Node's child_process, без контейнера та sandbox, тому обліковий запис, від імені якого він працює, є межею безпеки.

sudo adduser --disabled-password --gecos "" iva
sudo usermod -aG sudo iva
sudo install -d -m 700 -o iva -g iva /home/iva/.ssh
sudo cp ~/.ssh/authorized_keys /home/iva/.ssh/authorized_keys
sudo chown iva:iva /home/iva/.ssh/authorized_keys
sudo chmod 600 /home/iva/.ssh/authorized_keys
sudo loginctl enable-linger iva

enable-linger має значення, оскільки Iva працює як user units systemd. Без linger systemd зупиняє служби цього користувача одразу після завершення останнього сеансу. Тому асистент завершить роботу, щойно ви закриєте SSH. Це саме правило стосується будь-яких служб і таймерів, які ви самостійно створюєте в systemd.

Обліковому запису потрібен sudo лише на час, коли інсталятор додає пакети. Після завершення встановлення заберіть цей доступ.

sudo deluser iva sudo

Увійдіть безпосередньо через SSH від імені цього користувача. Shell, який ви запускаєте за допомогою sudo -iu iva, не має встановлених DBUS_SESSION_BUS_ADDRESS і XDG_RUNTIME_DIR, тому кожна команда systemctl --user завершується помилкою Failed to connect to bus. Визначення цієї межі є таким самим завданням, як запуск служб від імені користувачів із мінімальними привілеями.

Встановлення фіксованого релізу замість передавання скрипта до bash

Інсталятор має корисну властивість. Перш ніж клонувати репозиторій, він перевіряє, чи містить каталог, у якому розташований скрипт, package.json із "eve". Якщо так, інсталятор збирає цей checkout і пропускає клонування. Тому версію можна вибрати самостійно.

git clone --branch v0.3.13 https://github.com/smixs/iva-agent.git ~/iva
cd ~/iva
git log -1 --oneline
bash install.sh

Тепер відомо, який код виконується. Якщо скрипт клонуватиме main у стані, у якому репозиторій перебуває саме в цей час, визначити це неможливо. У період із 4 до 6 August 2026 Iva випустила п’ять релізів, тому main цього ранку та main цього дня після обіду — це різні програми.

Після checkout тегу git переходить у стан detached HEAD. Це працює, але важливо розуміти обмеження: iva update переводить checkout вперед на гілку оновлень, тому зафіксована версія є відомою початковою точкою, а не постійним блокуванням. iva version виводить версію пакета та git commit, тож завжди можна перевірити поточний стан.

Щоб навмисно перейти до пізнішого релізу, виведіть список тегів, виконайте checkout вибраного тегу замість v0.3.13 нижче, а потім знову запустіть інсталятор із каталогу checkout. Сам інсталятор не має параметра для тегу релізу. У його документації зазначені змінні середовища REPO_URL, BRANCH і INSTALL_DIR, тому саме git checkout фіксує версію.

cd ~/iva
git fetch --tags
git tag --list 'v*' | sort -V | tail -5
git checkout v0.3.13
bash install.sh --skip-setup
iva restart

--skip-setup не дає майстру знову запускатися поверх .env, який уже працює. Після цього виконайте iva version, щоб підтвердити commit, на якому опинилися.

П’ять кроків майстра та ключі, які він запитує

  1. Провайдер моделі та модель. MODEL_PROVIDER приймає opencode, ollama, openrouter або codex. Майстер перевіряє ключ у реальному часі та показує моделі, доступні у вашому тарифному плані.
  2. Голосовий ввід і пошук. Ключ Deepgram перетворює голосові повідомлення на текст. Ключ вебпошуку (Tavily, Exa, Parallel або Brave) необов’язковий.
  3. Токен Telegram-бота від @BotFather. Майстер перевіряє його через кінцеву точку getMe.
  4. Контроль доступу. Надішліть повідомлення своєму боту, і майстер зчитає ваш числовий ID користувача з getUpdates.
  5. Системні параметри. Часовий пояс IANA, каталог vault і локальний порт; типовий порт — 8723.

Дві з цих залежностей приховані формулюванням «одна команда». Iva не постачається з моделлю, тому до першої відповіді їй потрібен платний тарифний план моделі або API key. Вона також не транскрибує аудіо самостійно, тому для голосових повідомлень потрібен окремий сервіс. Модель Deepgram nova-3 з параметром DEEPGRAM_LANGUAGE=multi визначає мову, а нові облікові записи Deepgram отримують стартові кредити, яких достатньо для кількох місяців особистого використання. Текст працює лише з ключем моделі. Від Deepgram залежить лише голосовий ввід.

Перевірте, що записав майстер.

grep -E '^(MODEL_PROVIDER|TELEGRAM_ALLOWED_USER_IDS|ASSISTANT_VAULT_DIR|IVA_PORT)=' ~/iva/.env
ls -l ~/iva/.env

ls має вивести -rw------- з правами доступу 0600, оскільки цей файл містить усі щойно вставлені ключі. TELEGRAM_ALLOWED_USER_IDS має містити ваш числовий ID. Список дозволених користувачів працює за принципом fail closed, тому порожнє значення означає, що Iva нікому не відповідає.

Модель зчитується один раз під час запуску процесу. Редагування MODEL_PROVIDER або назви моделі у .env нічого не змінить, доки ви не виконаєте iva restart. У openrouter назва моделі має бути vendor slug, наприклад anthropic/claude-sonnet-4.5, а не лише назвою. У codex API key взагалі немає: iva login виконує вхід до наявної підписки ChatGPT.

Скільки коштує утримання Iva щомісяця

ГрафікMonthly cost of a self-hosted Iva, published list prices, October 2026
Дані, на яких побудовано графік
[
  {
    "plan": "Small VPS, always on",
    "usd_per_month": 5
  },
  {
    "plan": "OpenCode Go model plan",
    "usd_per_month": 10
  },
  {
    "plan": "Ollama Cloud model plan",
    "usd_per_month": 20
  },
  {
    "plan": "Deepgram voice, starter credits",
    "usd_per_month": 0
  },
  {
    "plan": "Tavily web search, free tier",
    "usd_per_month": 0
  },
  {
    "plan": "Cheapest complete setup",
    "usd_per_month": 15
  }
]

Це опубліковані роздрібні ціни станом на October 2026, а не результати вимірювань. Невеликий VPS за 5 доларів США плюс план OpenCode Go за 10 доларів — найдешевша повна конфігурація, приблизно 15 доларів на місяць. На власній сторінці Go OpenCode вказує цю місячну ціну без знижки за перший місяць, а в README Iva така сама конфігурація оцінюється приблизно в 14–15 доларів загалом. Ollama Cloud — інший варіант із фіксованою ціною: 20 доларів за план Pro; використання понад включені в план кредити оплачується додатково. Voice коштує 0, доки доступні стартові кредити Deepgram.

OpenRouter не наведено в таблиці, оскільки оплата здійснюється за фактичним використанням. Саме цей варіант потребує контролю: асистент, який передає в кожен запит контекстне вікно на 131072 токенів, може швидко перевищити вартість плану з фіксованою ціною. Установіть для змінної контекстного вікна фактичний розмір моделі, оскільки завищене значення лише марнує токени.

Два сервіси та два таймери

  • iva.service запускає сам агент.
  • iva-telegram-poll.service запускає міст довгого опитування, який взаємодіє з Telegram.
  • iva-memory-doctor.timer спрацьовує о 05:00 і запускає нічне обслуговування vault.
  • iva-update-check.timer спрацьовує о 10:00 і перевіряє наявність новішого релізу.
  • iva-telegram-userbot.service існує лише в разі налаштування необов’язкового проксі Telethon.
iva status
systemctl --user status iva.service iva-telegram-poll.service
systemctl --user list-timers
iva logs poll

iva status показує стан обох сервісів і обох watchdog-таймерів. systemctl --user list-timers виводить час наступного запуску кожного таймера. Так можна перевірити, що memory doctor справді запуститься сьогодні вночі. Обидва сервіси мають перебувати у стані active (running). Якщо один із них постійно перезапускається, journalctl --user -u iva.service -n 100 показує причину.

Такий поділ важливий під час налагодження. Міст може працювати й виконувати опитування, поки агент недоступний. У такому разі Telegram приймає ваше повідомлення, але відповідь не надходить. iva logs poll відстежує міст, а iva logs — агента. Тому два журнали показують, яка саме частина не працює.

Де зберігається сховище Obsidian і як створювати його резервні копії

ASSISTANT_VAULT_DIR за замовчуванням має значення vault у каталозі встановлення, тому пам’ять зберігається в ~/iva/vault. Це окремий git-репозиторій, відокремлений від коду. Завдяки цьому можна оновлювати Iva, не змінюючи нотатки.

  • vault/CORE.md містить довготривалі факти та постійні налаштування. Його розмір обмежено 1200 символами, і він додається до кожного системного промпту.
  • vault/daily/YYYY-MM-DD.md містить транскрипт поточного дня. Дані до нього лише додаються.
  • vault/cards/ містить типізовані картки для контактів, проєктів, рішень, ідей і нотаток.
  • vault/summaries/daily/, weekly/, monthly/ і yearly/ містять зведені дані.
  • vault/attachments/ містить файли, упорядковані за датами, а vault/.graph/ — граф зв’язків.
  • vault/schema.json визначає типи карток і правила згасання.

Зведені дані формуються за розкладом усередині процесу. Щоденний запуск о 04:00 перетворює транскрипт за вчора на картки та зведення і перезаписує CORE.md. Потім щотижневий, щомісячний і щорічний запуски послідовно стискають ці дані. О 05:00 memory doctor виконує детермінований запуск без залучення моделі: перевіряє схему, перебудовує граф зв’язків, повторно генерує індекс, а потім виконує commit і push.

Цей push є резервною копією. Саме цей крок часто пропускають. Якщо у сховища немає git remote, doctor намагається створити приватний репозиторій GitHub через gh. Для цього потрібен автентифікований GitHub CLI.

gh auth login
systemctl --user start iva-memory-doctor.service
cd ~/iva/vault && git log --oneline -3

Commit із сьогоднішньою датою означає, що запуск відбувся і сховище зафіксовано. Попередження gh not available у журналі означають протилежне: сховище обслуговується, але ніколи не залишає сервер. Тому відмова VPS призведе до втрати пам’яті.

Також зберігайте копію, яку контролюєте самостійно.

tar czf ~/iva-vault-backup.tgz -C ~/iva vault

Скопіюйте цей файл із сервера за допомогою scp, а потім видаліть його із сервера. Щоб читати пам’ять в Obsidian, укажіть Obsidian на клон репозиторію сховища. Wikilinks і backlinks працюватимуть без змін, як і подання графа. Картки та CORE.md можна безпечно редагувати вручну. Не змінюйте MOC.md і .graph/, оскільки нічний запуск повторно генерує обидва файли.

Сприймайте vault як журнал свого життя

Цей каталог є датованим записом того, що ви сказали, з ким зустрілися та що вирішили, на сервері, який ви орендуєте. З цього випливають два висновки.

Self-hosting переносить сховище, але не оброблення даних. Кожен запит надходить до вашого провайдера моделі, а кожна голосова нотатка — до Deepgram. vault належить вам. Компанії, які обробляють ці запити, усе одно їх бачать. Самостійний запуск memory layer, як у випадку з memory-сервером Mem0 на власному VPS, має таку саму особливість: сховище локальне, але виклик моделі все одно виходить за межі сервера. Якщо тема надто чутлива для стороннього сервісу, не додавайте її в чат.

Цей обліковий запис має доступ до всього vault. Інструменти Iva запускаються безпосередньо на хості через Node's fs і child_process, без Docker і sandbox, тому перехоплений запит отримує всі права, які має користувач сервісу. Саме тому після інсталяції цей обліковий запис не має sudo, а allowlist заслуговує на більшу увагу, ніж може здаватися: саме він визначає, чиї повідомлення стають командами на вашому сервері. Якщо ви хочете користуватися асистентом зі смартфона, не відкриваючи додаткових доступів, використовуйте ту саму схему, що й для доступу до self-hosted агента Hermes зі смартфона, де клієнт чату виконує роль, яку інакше виконував би публічний endpoint.

Що може зламатися і яке повідомлення ви побачите

Збірку завершено примусово, код завершення 137. OOM killer ядра завершив процес збірки через нестачу пам’яті. Інсталятор додає swap лише тоді, коли обсяг RAM менший за 1.5 GB і swap відсутній. Додайте swap вручну та знову запустіть інсталятор.

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
free -h

Failed to connect to bus. Кожна команда systemctl --user виводить це повідомлення, якщо в оболонці немає шини користувацького сеансу. Її надає sudo -iu iva. Відкрийте звичайний SSH-сеанс від імені цього користувача або експортуйте XDG_RUNTIME_DIR=/run/user/$(id -u iva) перед виконанням команди.

Бот ігнорує вас. TELEGRAM_ALLOWED_USER_IDS порожня, а список дозволених користувачів працює за принципом заборони за замовчуванням. Надішліть боту повідомлення. Він відповість лише вашим числовим ідентифікатором. Додайте цей ідентифікатор до .env і виконайте iva restart.

Бот замовкає одразу після iva config. Майстер може перемістити IVA_PORT, не оновивши ASSISTANT_HOST, тому міст підключається до порту, на якому нічого не відповідає. Порівняйте два рядки та перезапустіть служби.

grep -E '^(IVA_PORT|ASSISTANT_HOST)=' ~/iva/.env
iva restart

Голосова нотатка не отримує відповіді. Bot API Telegram не дозволяє завантажувати файли розміром понад 20 MB, тому міст не отримує довгі аудіофайли й не може передати їх у Deepgram. Розділіть файл перед надсиланням.

ffmpeg -i long.ogg -f segment -segment_time 600 -c copy part-%02d.ogg

Хід виконання зависає і не відповідає. Стан workflow, який завис, зберігається після перезапуску й повторно ставиться в чергу, тому самого перезапуску недостатньо. iva reset ізолює цей стан і перезапускає обидві служби. /new у чаті починає нову розмову.

Chromium не запускається в Ubuntu 24.04. Ubuntu 24.04 блокує непривілейовані user namespaces через AppArmor, тому власний sandbox Chromium не може запуститися, а agent-browser завершується помилкою. Інсталятор обходить це обмеження, записуючи "--no-sandbox" до ~/.agent-browser/config.json. Врахуйте наявність цього параметра. Він знижує рівень ізоляції браузера. Це ще одна причина, чому обліковий запис не повинен володіти нічим, крім Iva.

FAQ

Чи потрібен домен або відкритий порт для self-hosting Iva?

Ні. Iva взаємодіє з Telegram за допомогою long polling: iva-telegram-poll.service викликає getUpdates і очікує на відповідь, тому кожне з’єднання є вихідним із вашого сервера. Зовнішнім системам не потрібно підключатися до сервера, тому DNS-запис і сертифікат не потрібні. Власний HTTP-порт агента, 8723, прослуховується на 127.0.0.1, і документація проєкту рекомендує не відкривати його назовні. Правильна конфігурація firewall — дозволити SSH і заблокувати все інше.

Скільки коштує запуск Iva щомісяця?

За опублікованими цінами станом на October 2026 невеликий VPS за 5 доларів і найдешевший тарифний план із фіксованою ставкою за 10 доларів разом коштують приблизно 15 US dollars на місяць. Ollama Cloud коштує 20 доларів замість цього та додатково тарифікує використання понад включені кредити. Стартових кредитів Deepgram спочатку достатньо для голосових функцій, а тарифи вебпошуку мають безкоштовні ліміти. OpenRouter працює за моделлю pay as you go, тому фіксованої щомісячної суми немає.

Де Iva зберігає мої дані і як створити їхню резервну копію?

За замовчуванням у ~/iva/vault, який задається через ASSISTANT_VAULT_DIR. Це окремий приватний git-репозиторій зі звичайними markdown-файлами: CORE.md, daily/YYYY-MM-DD.md, cards/ і summaries/. О 05:00 memory doctor виконує commit і push. Це працює лише тоді, коли репозиторій має remote, тому під час налаштування виконайте gh auth login або додайте власний remote. Також зберігайте офлайн-копію за допомогою tar czf ~/iva-vault-backup.tgz -C ~/iva vault і перенесіть цей файл із сервера.

Чи залишаються мої дані приватними, якщо я самостійно розгортаю Iva?

Сховище належить вам. Обробка даних — ні. Vault залишається на вашому диску, доки ви не виконаєте push, а .env має режим 0600 і належить користувачу сервісу. Запити до моделей і транскрибування голосу виконуються через cloud API, тому ці повідомлення проходять через вашого провайдера моделей і Deepgram. Iva має ліцензію MIT, тому ви можете точно перевірити, які дані він надсилає, і змінити це. Telegram allowlist працює за принципом fail closed: порожній TELEGRAM_ALLOWED_USER_IDS блокує всіх, зокрема вас.

Яких провайдерів моделей підтримує Iva?

У зафіксованому релізі v0.3.13 MODEL_PROVIDER приймає opencode (OpenCode Go), ollama (Ollama Cloud), openrouter і codex. OpenRouter використовує vendor slug, наприклад anthropic/claude-sonnet-4.5, і пропонує найбільший вибір моделей. codex виконує вхід до наявної підписки ChatGPT через iva login і не використовує API key. Пізніші релізи додають інші маршрути, зокрема підписку Claude і сумісний із OpenAI custom endpoint. Вкажіть провайдера, встановіть відповідне context window відповідно до фактичного розміру моделі, а потім виконайте iva restart, оскільки модель зчитується лише під час запуску процесу.

Чи була ця стаття корисною?