SSD Nodes Learn 🎉 VPS từ $4.99/tháng
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 các trợ lý có thể triển khai mà không cần mở inbound port hoặc trỏ domain nào đến máy chủ. Bạn cũng không cần certificate, vì không có service nào trên máy lắng nghe kết nối từ bên ngoài. 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 khác đều bắt nguồn từ kết nối outbound này.

Iva được cấp phép theo MIT và 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 có thể đọc được khi không chạy 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.

Hầu hết phần mềm tự host đều bắt đầu bằng một bản ghi DNS (domain name system) và certificate 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à một deployment hoàn chỉnh.

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 duy nhất để pipe script từ GitHub vào bash. Hãy đọc script trước, vì nó làm nhiều việc hơn chỉ cài đặt một chương trình.

curl -fsSL https://raw.githubusercontent.com/smixs/iva/main/install.sh -o iva-install.sh
less iva-install.sh
  • Cài đặt các gói hệ thống bằng package manager được phát hiện: git, gh, python3, ffmpeg, pandocpoppler-utils.
  • 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.
  • Cài đặt nvm, sau đó cài Node 24, là phiên bản tối thiểu mà Iva yêu cầu.
  • Cài đặt uv, package manager của Python, vào ~/.local/bin.
  • Clone repository vào ~/iva và chạy npm ci.
  • Cài đặt 2 npm package global, agent-browser (sau đó package này tải Chromium) và @googleworkspace/cli.
  • Chạy setup wizard, build project và tạo vault.
  • Ghi một lệnh iva vào ~/.local/bin và cài đặt các systemd user unit.

Một dòng lệnh nhưng cài đặt rất nhiều software. Đ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 dùng root. Agent's shell tool sau đó sẽ chạy với các quyền mà installer đã có. Script chỉ gọi sudo để cài đặt package và tạo swapfile, thông qua một helper 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_ADDRESSXDG_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 pin thay vì pipe trực tiếp vào bash

Installer có một đặc tính 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 version.

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

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

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

Để chủ động chuyển sang release mới hơn, hãy liệt kê các tag, đặt IVA_TAG thành tag bạn chọn, rồi chạy lại installer từ bên trong checkout.

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

--skip-setup ngăn wizard chạy lại trên một .env đã hoạt động bình thường.

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ó.

Chi phí chạy Iva mỗi tháng là bao nhiêu

ChartMonthly cost of a self-hosted Iva, published list prices, August 2026
The data behind this chart
[
  {
    "plan": "Small VPS, always on",
    "usd_per_month": 5
  },
  {
    "plan": "OpenCode Go model plan",
    "usd_per_month": 5
  },
  {
    "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": 10
  }
]

Đây là giá niêm yết được công bố tại thời điểm tháng 8 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á 5 đô la, là cấu hình đầy đủ rẻ nhất, khoảng 10 đô la mỗi tháng. Ollama Cloud là lựa chọn tính phí cố định còn lại, với giá 20 đô la; các model frontier được tính thêm theo mức sử dụng ngoài phí gói. Voice có giá 0 trong thời gian còn credits của gói Deepgram starter.

OpenRouter không có dòng riêng ở đây vì dịch vụ này tính phí theo mức sử dụng, nên hóa đơn phụ thuộc vào lượng bạn dùng. Đây là lựa chọn cần theo dõi: một assistant mang context window 131072 token vào mọi lượt có thể nhanh chóng tốn nhiều hơn một gói tính phí 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 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/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.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 fschild_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ờ, nên mọi kết nối đều là kết nối outbound từ server của bạn. Không có kết nối nào cần đi vào server từ bên ngoài, vì vậy 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 của project 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.

Chi phí chạy Iva mỗi tháng là bao nhiêu?

Theo bảng giá niêm yết tháng 08 năm 2026, một VPS nhỏ giá 5 dollar cộng với model plan flat rate rẻ nhất giá 5 dollar sẽ tốn khoảng 10 US dollar mỗi tháng. Ollama Cloud có giá 20 dollar thay thế, chưa bao gồm chi phí các frontier model. Gói tín dụng starter của Deepgram ban đầu đủ dùng cho voice, còn các tier web search có hạn mức miễn phí. OpenRouter tính phí theo mức sử dụng, 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 sao lưu dữ liệu đó thế nào?

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ư, độc lập, chứa markdown dạng plain text: CORE.md, daily/YYYY-MM-DD.md, cards/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, vì vậy hãy chạy gh auth login hoặc tự thêm remote trong quá trình 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.

Dữ liệu của tôi có riêng tư nếu tôi tự host Iva không?

Bạn sở hữu storage. Nhưng không phải toàn bộ quá trình xử lý. 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ệnh gọi model và việc transcription voice đều dùng cloud API, nên các message đó đi qua model provider và Deepgram của bạn. Iva được cấp license MIT, vì vậy 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, 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?

MODEL_PROVIDER chấp nhận opencode (OpenCode Go), ollama (Ollama Cloud), openroutercodex. OpenRouter nhận 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 subscription ChatGPT hiện có bằng iva login và không dùng API key. Hãy đặt provider, đặt context window tương ứng với kích thước thực của model, rồi chạy iva restart, vì model chỉ được đọc một lần khi process khởi động.