SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor

Tự host Iva, trợ lý AI Telegram trên VPS nhỏ

Chạy Iva v0.3.13 trên VPS nhỏ mà không mở inbound port hay dùng domain. Thiết lập systemd user service, lưu bộ nhớ dạng Markdown và backup vault Obsidian.

Bạn đang xây dựng gì

Iva là một trợ lý AI Telegram tự host. Đây là một trong số ít trợ lý có thể triển khai mà không cần mở cổng inbound hoặc trỏ domain vào máy chủ. Bạn cũng không cần chứng chỉ vì không có dịch vụ nào trên máy lắng nghe lưu lượng public. Service chủ động kết nối đến Telegram, giữ kết nối mở và đọc tin nhắn của bạn từ phản hồi. Mọi thành phần còn lại đều dựa trên kết nối outbound này.

Iva được cấp phép theo MIT và được viết bằng Node. Bộ nhớ của Iva là một thư mục chứa các file markdown thuần mà Obsidian có thể mở trực tiếp. Vì vậy, các ghi chú Iva lưu về bạn vẫn dễ đọc ngay cả khi không dùng app. Hướng dẫn này cố định ở release v0.3.13, được phát hành vào ngày 6 August 2026. Repository sau đó đã được đổi tên từ smixs/iva thành smixs/iva-agent, và các command bên dưới sử dụng tên mới.

Phần lớn phần mềm tự host bắt đầu bằng một bản ghi DNS (domain name system) và chứng chỉ Let's Encrypt được cấp bằng Certbot. Iva bỏ qua hoàn toàn lớp này. Vì vậy, một VPS nhỏ phía sau firewall chỉ cho phép SSH là đủ để triển khai.

Vì sao Iva không cần mở cổng

iva-telegram-poll.service là một cầu nối long polling. Nó gọi API getUpdates của Telegram và chờ phản hồi, nên mọi kết nối đều bắt đầu từ máy chủ của bạn. Telegram không bao giờ kết nối ngược lại, vì vậy bạn không cần cấu hình reverse proxy và cũng không thể quên gia hạn chứng chỉ.

Bản thân agent vẫn listen, nhưng chỉ trên cổng 127.0.0.1 8723. Tài liệu dự án nêu rõ: không expose cổng 8723, và mọi reverse proxy đặt phía trước nó phải tiếp tục yêu cầu bearer token. Kiểm tra địa chỉ bind sau khi cài đặt.

sudo ss -tlnp | grep 8723

Địa chỉ phải là 127.0.0.1:8723. Địa chỉ wildcard như 0.0.0.0:8723 khiến các HTTP route của agent có thể truy cập từ Internet. Bạn nên sửa việc này trước khi gửi bất kỳ dữ liệu riêng tư nào cho bot.

Vì vậy firewall vẫn được giữ đóng. Cho phép SSH trước khi enable firewall, vì ufw enable khi không có rule SSH sẽ đóng session bạn đang dùng để nhập lệnh.

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Trình cài đặt một dòng thực sự làm gì

Trang chính của dự án cung cấp một lệnh truyền script từ GitHub vào bash. Hãy đọc script trước, vì nó làm nhiều việc hơn là chỉ cài đặt một chương trình.

curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh -o iva-install.sh
less iva-install.sh
  • Nó cài đặt các gói hệ thống bằng package manager được phát hiện: git, gh, python3, ffmpeg, pandoc và poppler-utils.
  • Nó tạo swapfile 2 GB tại /swapfile khi máy có dưới 1.5 GB RAM và không có swap, vì quá trình build sẽ bị kill nếu thiếu swap.
  • Nó cài đặt nvm, sau đó cài Node 24, là phiên bản tối thiểu mà Iva có thể chạy.
  • Nó cài đặt uv, package manager của Python, vào ~/.local/bin.
  • Nó clone repository vào ~/iva rồi chạy npm ci.
  • Nó cài đặt agent-browser dưới dạng npm package global. Package này sau đó tải Chromium và đặt Google Workspace CLI, gws, vào ~/.local mà không cần sudo.
  • Nó chạy setup wizard, build project và tạo vault.
  • Nó ghi một lệnh iva vào ~/.local/bin rồi cài các systemd user unit.

Đó là rất nhiều software cho một dòng lệnh. Điều này cũng giải thích hướng dẫn trong README: hãy cài đặt bằng user thông thường, không phải root. Shell tool của agent về sau sẽ chạy với các quyền mà installer đã có. Script chỉ gọi sudo để cài package và tạo swapfile, cùng lắm thêm một lần cho bước cài Chromium, thông qua một helper có thể chạy lệnh trực tiếp khi bạn đã là root.

Tạo user riêng trước khi cài đặt

Tạo cho Iva một account riêng. Agent chạy shell command trên host thông qua child_process của Node, không dùng container và không có sandbox, nên account mà agent chạy dưới đó chính là ranh giới bảo mật.

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 quan trọng vì Iva chạy dưới dạng systemd user unit. Nếu không bật linger, systemd sẽ dừng service của user đó ngay khi session cuối cùng kết thúc, nên assistant sẽ dừng khi bạn đóng SSH. Quy tắc này cũng áp dụng cho mọi service và timer bạn tự tạo dưới systemd.

Account chỉ cần sudo trong lúc installer thêm package. Hãy thu hồi quyền này sau khi cài đặt xong.

sudo deluser iva sudo

Đăng nhập trực tiếp bằng account đó qua SSH. Shell bạn mở bằng sudo -iu iva không có DBUS_SESSION_BUS_ADDRESS và XDG_RUNTIME_DIR, nên mọi lệnh systemctl --user đều fail với Failed to connect to bus. Thiết lập ranh giới này cũng giống như chạy service dưới các user có quyền tối thiểu.

Cài bản release được ghim thay vì pipe trực tiếp vào bash

Installer có một đặc điểm hữu ích. Trước khi clone bất kỳ thứ gì, nó kiểm tra xem thư mục chứa script đã có package.json chứa "eve" hay chưa. Nếu có, nó build checkout đó và bỏ qua bước clone. Vì vậy, bạn có thể tự chọn phiên bản.

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

Bây giờ bạn biết code nào đang chạy. Khi script clone main ở trạng thái hiện tại của thời điểm đó, bạn không biết điều này. Iva đã phát hành 5 release trong khoảng từ ngày 4 đến ngày 6 tháng 8 năm 2026, nên main vào sáng nay và main vào chiều nay không phải cùng một chương trình.

Checkout một tag sẽ đưa git vào trạng thái detached HEAD. Cách này vẫn chạy bình thường, nhưng bạn cần hiểu giới hạn: iva update sẽ đưa checkout tiến lên update branch, nên việc pin chỉ xác định điểm bắt đầu đã biết chứ không đóng băng vĩnh viễn. iva version in ra package version và git commit, vì vậy bạn luôn có thể biết mình đang ở đâu.

Để chủ động chuyển sang release mới hơn, hãy liệt kê các tag, checkout tag bạn chọn thay cho v0.3.13 bên dưới, rồi chạy lại installer từ bên trong checkout. Bản thân installer không có setting cho release tag. Các biến môi trường được document là REPO_URL, BRANCH và INSTALL_DIR, nên git checkout là cách duy nhất để pin phiên bản.

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 ngăn wizard chạy lại trên .env đã hoạt động. Sau đó chạy iva version để xác nhận commit mà bạn đã checkout.

Năm bước của wizard và các key cần nhập

  1. Nhà cung cấp model và model. MODEL_PROVIDER chấp nhận opencode, ollama, openrouter hoặc codex. Wizard kiểm tra key ngay lập tức và liệt kê các model có trong gói của bạn.
  2. Voice và tìm kiếm. Key Deepgram dùng để chuyển voice note thành văn bản. Web search key (Tavily, Exa, Parallel hoặc Brave) là tùy chọn.
  3. Telegram bot token lấy từ @BotFather, được kiểm tra với endpoint getMe.
  4. Kiểm soát quyền truy cập. Bạn gửi một tin nhắn cho bot, rồi wizard đọc numeric user ID của bạn từ getUpdates.
  5. Cài đặt hệ thống. Bao gồm múi giờ IANA, thư mục vault và cổng local, mặc định là 8723.

Có 2 dependency bị che khuất bởi cách mô tả "một lệnh". Iva không tích hợp sẵn model, nên cần gói model trả phí hoặc API key trước khi có thể trả lời. Iva cũng không tự chuyển audio thành văn bản, nên voice note cần một service riêng. Model nova-3 của Deepgram cùng với DEEPGRAM_LANGUAGE=multi sẽ tự phát hiện ngôn ngữ, và tài khoản Deepgram mới được cấp starter credits đủ cho vài tháng sử dụng cá nhân. Text chỉ cần model key. Chỉ voice mới phụ thuộc vào Deepgram.

Kiểm tra các giá trị wizard đã ghi.

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

ls phải in ra -rw-------, mode 0600, vì file đó chứa tất cả key bạn vừa dán vào. TELEGRAM_ALLOWED_USER_IDS phải chứa numeric ID của bạn. Allowlist áp dụng chính sách fail closed, nên giá trị trống có nghĩa là Iva không trả lời ai.

Model được đọc một lần khi process khởi động. Sửa MODEL_PROVIDER hoặc tên model trong .env không có tác dụng cho đến khi bạn chạy iva restart. Trên openrouter, tên model là vendor slug như anthropic/claude-sonnet-4.5, không phải tên rút gọn. Trên codex không có API key: iva login đăng nhập vào ChatGPT subscription hiện có.

Iva tốn bao nhiêu mỗi tháng để chạy

Biểu đồMonthly cost of a self-hosted Iva, published list prices, October 2026
Dữ liệu đằng sau biểu đồ này
[
  {
    "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
  }
]

Đây là giá niêm yết được công bố tính đến tháng 10 năm 2026, không phải số liệu đo thực tế. Một VPS nhỏ có giá 5 đô la Mỹ cộng với gói OpenCode Go giá 10 đô la là cấu hình đầy đủ rẻ nhất, tổng cộng khoảng 15 đô la mỗi tháng. Trang Go của OpenCode liệt kê mức giá hàng tháng này mà không giảm giá cho tháng đầu tiên, còn README của Iva ước tính cùng stack này có tổng chi phí khoảng 14 đến 15 đô la. Ollama Cloud là lựa chọn giá cố định khác, ở mức 20 đô la cho gói Pro; phần sử dụng vượt quá credit đi kèm gói sẽ được tính thêm. Chi phí voice là 0 trong thời gian credit khởi đầu của Deepgram còn hiệu lực.

OpenRouter không có trong bảng này vì dịch vụ tính phí theo mức sử dụng, nên hóa đơn phụ thuộc vào mức bạn dùng. Đây là lựa chọn cần theo dõi: một assistant đưa context window 131072 token vào mọi lượt có thể nhanh chóng tốn nhiều hơn gói giá cố định. Hãy đặt biến context window theo đúng kích thước thực của model, vì giá trị đặt cao hơn thực tế chỉ làm lãng phí token.

Hai service và hai timer

  • iva.service chạy chính agent.
  • iva-telegram-poll.service chạy long polling bridge để giao tiếp với Telegram.
  • iva-memory-doctor.timer kích hoạt lúc 05:00 và chạy lượt bảo trì hằng đêm trên vault.
  • iva-update-check.timer kích hoạt lúc 10:00 và kiểm tra xem có release mới hơn hay không.
  • iva-telegram-userbot.service chỉ tồn tại nếu bạn thiết lập Telethon proxy tùy chọn.
iva status
systemctl --user status iva.service iva-telegram-poll.service
systemctl --user list-timers
iva logs poll

iva status hiển thị trạng thái của cả hai service và cả hai watchdog timer. systemctl --user list-timers hiển thị thời điểm chạy tiếp theo của từng timer. Đây là cách xác nhận memory doctor thực sự sẽ chạy tối nay. Cả hai service phải ở trạng thái active (running). Nếu một service khởi động lại liên tục, journalctl --user -u iva.service -n 100 sẽ cho biết nguyên nhân.

Việc tách riêng này rất quan trọng khi debug. Bridge có thể vẫn hoạt động và polling trong khi agent đã dừng. Khi đó Telegram nhận được tin nhắn của bạn nhưng không có phản hồi. iva logs poll theo dõi bridge, còn iva logs theo dõi agent. Vì vậy, hai log cho biết phần nào đang bị lỗi.

Vị trí Obsidian vault và cách sao lưu

ASSISTANT_VAULT_DIR mặc định nằm trong vault bên trong thư mục cài đặt, nên memory được lưu tại ~/iva/vault. Đây là một git repository riêng, tách khỏi code. Nhờ đó, bạn có thể cập nhật Iva mà không ảnh hưởng đến các ghi chú.

  • vault/CORE.md lưu các thông tin cố định và preference thường dùng, tối đa 1200 ký tự, và được đưa vào mọi system prompt.
  • vault/daily/YYYY-MM-DD.md là transcript trong ngày và chỉ được ghi nối tiếp.
  • vault/cards/ lưu các card có kiểu cho contact, project, decision, idea và note.
  • vault/summaries/daily/, weekly/, monthly/ và yearly/ lưu các bản tổng hợp.
  • vault/attachments/ lưu file theo ngày, còn vault/.graph/ lưu link graph.
  • vault/schema.json định nghĩa các card type và quy tắc decay.

Các bản tổng hợp chạy theo lịch bên trong process. Lần chạy hằng ngày lúc 04:00 chuyển transcript của ngày hôm trước thành các card và một bản tóm tắt, đồng thời ghi lại CORE.md. Sau đó, các lần chạy hằng tuần, hằng tháng và hằng năm tiếp tục nén các dữ liệu này. Lúc 05:00, memory doctor chạy một pass deterministic không dùng model: kiểm tra schema, dựng lại link graph, tạo lại index, rồi commit và push.

Lần push đó chính là bản sao lưu của bạn, và đây là bước nhiều người bỏ sót. Nếu vault không có git remote, doctor sẽ thử tạo một GitHub repository private thông qua gh. Việc này cần một GitHub CLI đã được authenticate.

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

Một commit có ngày là hôm nay cho biết pass đã chạy và vault đã được commit. Các cảnh báo gh not available trong log cho biết điều ngược lại: vault vẫn được duy trì nhưng chưa bao giờ rời khỏi server, nên một VPS bị hỏng sẽ làm mất memory của bạn.

Bạn cũng nên giữ một bản sao do chính bạn kiểm soát.

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

Dùng scp để copy file đó khỏi máy chủ, rồi xóa file khỏi server. Để đọc memory trong Obsidian, hãy trỏ Obsidian vào một clone của vault repository. Wikilink, backlink và graph view vẫn hoạt động bình thường. Bạn có thể chỉnh sửa card và CORE.md thủ công một cách an toàn. Không chỉnh sửa MOC.md và .graph/, vì pass hằng đêm sẽ tạo lại cả hai.

Coi vault như nhật ký cuộc sống của bạn

Thư mục đó là bản ghi theo ngày về những gì bạn đã nói, những người bạn đã gặp và những quyết định bạn đã đưa ra, trên một máy chủ bạn thuê. Từ đó có 2 điều cần lưu ý.

Tự host chuyển nơi lưu trữ, không chuyển nơi xử lý. Mỗi lượt trao đổi đều được gửi đến nhà cung cấp model, và mọi voice note đều được gửi đến Deepgram. Vault là của bạn. Các request không được giữ riêng tư khỏi những công ty xử lý chúng. Tự vận hành memory layer, như một memory server Mem0 trên VPS của riêng bạn, cũng có cùng mô hình: dữ liệu được lưu local nhưng lời gọi model vẫn rời khỏi máy chủ của bạn. Nếu một chủ đề quá nhạy cảm để gửi cho bên thứ ba, hãy không đưa chủ đề đó vào chat.

Phạm vi truy cập của account đó là toàn bộ vault. Các tool của Iva chạy native trên host thông qua Node's fs và child_process, không có Docker và không có sandbox, nên một lượt trao đổi bị chiếm quyền sẽ có mọi quyền truy cập mà service user đó có. Vì vậy account này không giữ sudo nào sau khi cài đặt, và allowlist cần được chú ý nhiều hơn vẻ bề ngoài: nó là cổng kiểm soát quyết định tin nhắn của ai được chuyển thành command trên server của bạn. Nếu muốn dùng assistant trên điện thoại mà không mở thêm gì, đây là cùng mô hình được dùng để truy cập một Hermes agent tự host từ điện thoại, trong đó chat client thực hiện vai trò mà một public endpoint thường đảm nhiệm.

Các lỗi thường gặp và thông báo bạn sẽ thấy

Build bị dừng, mã thoát 137. Trình diệt tiến trình khi hết bộ nhớ của kernel đã dừng build. Installer chỉ thêm swap khi RAM dưới 1.5 GB và chưa có swap, vì vậy hãy tự thêm swap rồi chạy lại installer.

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

Failed to connect to bus. Mọi lệnh systemctl --user đều in thông báo này khi shell không có user session bus, thứ mà sudo -iu iva cung cấp. Hãy mở một phiên SSH bình thường bằng user đó, hoặc export XDG_RUNTIME_DIR=/run/user/$(id -u iva) trước khi chạy lệnh.

Bot không phản hồi. TELEGRAM_ALLOWED_USER_IDS đang trống và allowlist mặc định từ chối. Hãy gửi tin nhắn cho bot: bot chỉ trả về numeric ID của bạn, không trả về nội dung nào khác. Đặt ID đó vào .env rồi chạy iva restart.

Bot im lặng ngay sau iva config. Wizard có thể di chuyển IVA_PORT mà không cập nhật ASSISTANT_HOST, khiến bridge kết nối đến một cổng không có tiến trình phản hồi. Hãy so sánh hai dòng này rồi restart.

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

Gửi voice note nhưng không nhận được phản hồi. Telegram Bot API từ chối tải file lớn hơn 20 MB, nên bridge không bao giờ nhận được audio dài để gửi cho Deepgram. Hãy tách file trước khi gửi.

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

Một lượt xử lý bị treo và không bao giờ phản hồi. Trạng thái workflow bị kẹt vẫn tồn tại sau khi restart và tự được đưa vào hàng đợi lại, nên chỉ restart sẽ không xóa được trạng thái này. iva reset cách ly trạng thái đó và restart cả hai service. /new trong chat sẽ bắt đầu một cuộc hội thoại mới.

Chromium không chạy được trên Ubuntu 24.04. Ubuntu 24.04 chặn user namespace không đặc quyền thông qua AppArmor, nên sandbox của Chromium không thể khởi động và agent-browser bị lỗi. Installer khắc phục bằng cách ghi "--no-sandbox" vào ~/.agent-browser/config.json. Bạn cần biết cấu hình này tồn tại. Nó làm giảm mức độ cách ly của trình duyệt, vì vậy tài khoản này càng không nên sở hữu bất kỳ thứ gì ngoài Iva.

FAQ

Tôi có cần domain hoặc cổng mở để tự host Iva không?

Không. Iva giao tiếp với Telegram bằng long polling: iva-telegram-poll.service gọi getUpdates rồi chờ phản hồi, vì vậy mọi kết nối đều là kết nối outbound từ server của bạn. Không có gì cần truy cập vào máy chủ từ bên ngoài, nên bạn không cần bản ghi DNS hoặc certificate. Cổng HTTP riêng của agent là 8723 và bind vào 127.0.0.1. Tài liệu dự án cũng yêu cầu bạn không expose cổng này. Cấu hình đúng là firewall chỉ cho phép SSH và không cho phép gì khác.

Mỗi tháng chạy Iva tốn bao nhiêu?

Theo bảng giá công bố tháng 10 năm 2026, một VPS nhỏ có giá 5 dollar cộng với gói model flat rate rẻ nhất có giá 10 dollar, tổng cộng khoảng 15 US dollar mỗi tháng. Ollama Cloud có giá 20 dollar thay vào đó và tính thêm phần usage vượt quá credit đi kèm. Credit starter của Deepgram ban đầu đủ để xử lý voice, còn các tier web search có mức sử dụng miễn phí. OpenRouter tính phí theo usage, nên không có mức phí cố định hàng tháng.

Iva lưu dữ liệu của tôi ở đâu và tôi backup dữ liệu như thế nào?

Theo mặc định, dữ liệu nằm trong ~/iva/vault và được thiết lập bởi ASSISTANT_VAULT_DIR. Đây là một git repository riêng tư, chứa markdown dạng plain text: CORE.md, daily/YYYY-MM-DD.md, cards/ và summaries/. Memory doctor chạy lúc 05:00 sẽ commit và push repository này. Việc đó chỉ có tác dụng nếu repository đã có remote, nên hãy chạy gh auth login hoặc thêm remote của riêng bạn trong lúc setup. Đồng thời giữ một bản sao offline bằng tar czf ~/iva-vault-backup.tgz -C ~/iva vault và chuyển file đó ra khỏi server.

Nếu tự host Iva thì dữ liệu của tôi có riêng tư không?

Phần lưu trữ thuộc về bạn. Phần xử lý thì không. Vault vẫn nằm trên disk của bạn cho đến khi bạn push nó, còn .env có mode 0600 và thuộc sở hữu của service user. Các lần gọi model và việc transcribe voice sử dụng cloud API, nên các message đó đi qua model provider và Deepgram của bạn. Iva được cấp phép theo MIT license, nên bạn có thể đọc chính xác những gì nó gửi và thay đổi code. Telegram allowlist có cơ chế fail closed. Điều đó có nghĩa là TELEGRAM_ALLOWED_USER_IDS rỗng sẽ chặn tất cả mọi người, kể cả bạn.

Iva hỗ trợ những model provider nào?

Trong release v0.3.13 được ghim, MODEL_PROVIDER chấp nhận opencode (OpenCode Go), ollama (Ollama Cloud), openrouter và codex. OpenRouter sử dụng vendor slug như anthropic/claude-sonnet-4.5 và cung cấp lựa chọn model rộng nhất. codex đăng nhập vào ChatGPT subscription hiện có bằng iva login và không sử dụng API key. Các release sau bổ sung thêm route, gồm subscription của Claude và custom OpenAI compatible endpoint. Hãy đặt provider và đặt context window tương ứng với kích thước thực của model, sau đó chạy iva restart, vì model chỉ được đọc một lần khi process khởi động.