Introduction
I wanted a personal AI assistant on Telegram, running on a phone I already carry — not another always-on cloud box. Nanobot is an open-source assistant with a Telegram channel. pip install was the easy part. The hard part was making it behave on real Android: correct architecture, Python packages that look like Linux, replies with Termux in the background, and startup after reboot without opening the app every time.
I tested this on Android 16 (HONOR 200, MagicOS). The same constraints show up on many OEM skins — aggressive battery rules, boot scheduling — even when the steps are generic.
| Piece | Role |
|---|---|
| Termux (ARM64) | Linux environment on Android |
| proot-distro → Debian ARM64 | Userspace where pip and wheels behave like on Linux |
| Nanobot 0.3.5 | Gateway + Telegram integration |
| tmux + restart loop | Keep the gateway running; retry on crash |
| Termux:Boot | Run scripts after BOOT_COMPLETED |
| OEM app / battery settings | Let Termux work in the background |
Confirmed on my device (October 2026): Nanobot in a Debian venv (Python 3.13.5), Telegram works with Termux backgrounded, and the gateway comes back after a real reboot without manually opening Termux.
For commands, dead ends, and APK notes, see the full setup notes on Notion. This post is the story; that page is the lab notebook.
If you already use Telegram as a frontend — like in my Converso Chatbot project — the UX is familiar. Here the backend lives on the phone.
Stack overview
- Telegram Messages to and from you
- Nanobot gateway
Python · virtualenv ·
nanobot gateway - Debian ARM64
proot-distro— Linux userspace, not a VM - Termux ARM64 · tmux · boot scripts · logs
- Android OEM battery policy · boot delivery · background limits
Termux gives you a shell and packages on Android. proot-distro installs a Debian ARM64 rootfs inside Termux. That is not a full virtual machine: there is no separate kernel, only a Linux userspace under proot. For Nanobot, that was enough to use normal ARM64 wheels instead of fighting Android-specific builds.
On Termux I also use:
~/bin/nanobot-loop— runsnanobot gatewayinside Debian, logs, retries on exit~/.termux/boot/00-start-nanobot— boot hook, wake lock attempt, starts tmux sessionnanobot-host- Logs under
~/nanobot-logs/(boot.log,gateway.log)
Boot fix that worked for me: oswaldlow/termux-boot tag v0.8.1-boot-fix, with a matching-key Termux build (same signing family as that fork). Termux APK I recorded:
termux-app_v0.119.0-beta.3+apt-android-7-github-debug_arm64-v8a.apk
(GitHub ARM64 debug build — a non-debug ARM64 build from the same line is preferable when you can use it. Keep Termux and add-ons from compatible sources.)
I am not claiming the boot fork fixes every Android 16 device, or that the original boot failure root cause is proven. Reboot auto-start is confirmed on my phone only.
32-bit Termux on a 64-bit phone
The first surprise was not Nanobot — it was architecture.
Android reported:
arm64-v8a,armeabi-v7a,armeabi
Termux reported a 32-bit userspace:
uname -m # armv8l
dpkg --print-architecture # arm
The CPU supports ARM64, but Termux was arm, not aarch64. That broke later assumptions about wheels and Rust targets.
Lesson: compare Android’s supported ABIs and Termux’s architecture separately.
I reinstalled with an ARM64 Termux APK and verified:
uname -m # aarch64
dpkg --print-architecture # aarch64
Uninstalling Termux wipes its private data — back up anything you need first.
Dead end: native Termux Python
I tried installing Nanobot directly in Termux. Build prep for watchfiles / maturin failed when Rust could not target the Android ABI Termux reported, e.g.:
Python reports SOABI: cpython-314-arm-linux-androideabi
Computed rustc target triple: arm-unknown-linux-androideabi
Target triple not supported by rustup: arm-unknown-linux-androideabi
That is Android/Termux packaging, not “the phone is too slow.”
Binary-only install in Termux also failed for me:
python -m pip install --only-binary=:all: rapidfuzz watchfiles
Pip found no matching distribution for rapidfuzz in that environment. I did not want to compile native Android deps one by one.
What worked: Debian ARM64 + venv
In Termux:
pkg update && pkg upgrade -y
pkg install proot-distro -y
proot-distro install debian
proot-distro login debian
Inside Debian:
uname -m # aarch64
dpkg --print-architecture # arm64
apt update
apt install -y python3 python3-venv python3-pip git curl build-essential
python3 -m venv ~/nanobot-env
source ~/nanobot-env/bin/activate
python -m pip install --upgrade pip
python -m pip install --only-binary=:all: rapidfuzz
python -m pip install nanobot-ai
nanobot --help
nanobot onboard
The venv must live inside Debian. An old Termux venv is a different filesystem — I hit No such file or directory on source ~/nanobot-env/bin/activate until I created /root/nanobot-env in Debian.
Config: /root/.nanobot/config.json. Another Termux window can proot-distro login debian and edit the same file.
Example config.json (placeholders only)
{
"agents": {
"defaults": {
"model": "gpt-4.1-mini",
"provider": "openai"
}
},
"providers": {
"openai": {
"apiKey": "PASTE_YOUR_OPENAI_API_KEY_HERE"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "PASTE_YOUR_TELEGRAM_BOT_TOKEN_HERE"
}
}
}
Restrict Telegram to your user(s) (allowlist / pairing). Review tool permissions before enabling shell or filesystem access.
Telegram’s optional deps failed once in my gateway log; a retry worked. I did not save the pip error — I will not guess it here.
Background execution: tmux is not enough
For manual runs inside Debian:
apt install -y tmux
tmux new -s nanobot
source ~/nanobot-env/bin/activate
nanobot gateway
Detach: Ctrl+B, then D. Reattach: tmux attach -t nanobot.
Nanobot ran in tmux, but Telegram still failed when Termux was backgrounded. tmux only keeps the terminal session alive; it does not override Android process management or battery policy.
OEM settings (where HONOR / MagicOS mattered for me)
On MagicOS (HONOR 200), background replies started working after I changed Termux in system settings:
- Search settings for App launch (names vary by OEM/Android version).
- Select Termux → disable automatic management if offered.
- Allow background activity / auto-launch / run in background (wording varies).
- Set battery optimization to don’t optimize (or equivalent) for Termux.
- Avoid “phone manager” style cleaners that force-stop Termux.
On Samsung, Xiaomi, OnePlus, etc., the menus differ but the pattern is the same: whitelist Termux for background work before you blame Nanobot or tmux.
Optional experiment (not confirmed necessary for me): in Termux, pkg install termux-api and termux-wake-lock (Termux:API companion app may be required). Wake locks cost battery.
Boot after reboot: Termux:Boot + restart loop
Termux:Boot runs executable scripts in ~/.termux/boot/. Open the Termux:Boot app once after install.
| File | Purpose |
|---|---|
~/bin/nanobot-loop | Gateway inside Debian, log + retry loop |
~/.termux/boot/00-start-nanobot | Boot log, wake lock, delay, start nanobot-host tmux |
nanobot-loop (Termux bash)
#!/data/data/com.termux/files/usr/bin/bash
LOG="$HOME/nanobot-logs/gateway.log"
mkdir -p "$HOME/nanobot-logs"
while true; do
echo "[$(date)] Starting Nanobot gateway" >> "$LOG"
proot-distro login debian -- /bin/bash -lc \
'source /root/nanobot-env/bin/activate && exec nanobot gateway' >> "$LOG" 2>&1
rc=$?
echo "[$(date)] Gateway exited with code $rc; retry in 10 seconds" >> "$LOG"
sleep 10
done
00-start-nanobot (boot script)
#!/data/data/com.termux/files/usr/bin/bash
mkdir -p "$HOME/nanobot-logs"
exec >> "$HOME/nanobot-logs/boot.log" 2>&1
echo "===== Boot script fired: $(date) ====="
termux-wake-lock
sleep 15
if tmux has-session -t nanobot-host 2>/dev/null; then
echo "[$(date)] Existing tmux session; not duplicating."
exit 0
fi
tmux new-session -d -s nanobot-host "$HOME/bin/nanobot-loop"
chmod 700 on both scripts.
Official Termux:Boot 0.8.1 vs real reboot
With official Termux:Boot 0.8.1, manual broadcast worked:
am broadcast -a android.intent.action.BOOT_COMPLETED \
-n com.termux.boot/.BootReceiver
After a real reboot, my boot log did not update — scripts did not run automatically. The receiver and ~/.termux/boot/ path were fine; delivery after reboot was not (on my device, Android 16).
A plausible explanation is BootJobService / JobScheduler behavior on newer Android. That is a hypothesis, not a proven root cause.
Switching to v0.8.1-boot-fix plus matching Termux signing fixed reboot startup for me: Telegram works without opening Termux manually. I did not record the fork Boot APK filename — install from the release and match keys with your Termux build.
Security, battery, reliability
| Topic | Notes |
|---|---|
| Secrets | Never publish config.json; use placeholders in docs |
| Telegram | Restrict who can talk to the bot; review enabled tools |
| Uptime | Android can kill background apps; this is not server-grade HA |
| Hardware | Continuous use → heat and battery wear |
| Still untested for me | Long screen-off, network loss, force-stop / cleaner behavior |
This setup works for my personal assistant use case — not for everyone or every OEM.
Checklist if you try this
- ARM64 Termux — verify
aarch64before deep pip debugging. - Debian via proot-distro — venv and Nanobot inside Debian.
- OEM battery / background for Termux — do this before tuning tmux.
- Termux:Boot — if
am broadcastworks but reboot does not, consider the boot-fix fork and matching APK keys; verify withboot.logon your phone. - Logs —
boot.logandgateway.log; full commands in Notion.
Installing Nanobot was only the beginning. Android policy (background + boot) is what turned a demo into something I could message after reboot — on my HONOR 200 that meant MagicOS settings; on other phones, find the equivalent Termux whitelist.
Treat one working device as one data point. Keep logs, match APK signing families, and do not wipe a working Debian venv to chase a guess.
