CMF Phone 1 заменил VPS: разработчик превратил смартфон в домашний сервер

Автор блога seg6 держал личную инфраструктуру (несколько веб-приложений, сервис удалённого браузера Surf с управляемым Chrome, прокси-сервер Caddy) на небольшом VPS у Hetzner, но платить за него не хотел. Новый выделенный сервер тоже стоил бы заметных денег в месяц, а покупка отдельной машины с достаточным объёмом памяти была невыгодна из-за резко выросших цен на DRAM. Тогда автор вспомнил про уже купленный смартфон CMF Phone 1: восемь ARM-ядер, 8 ГБ оперативной памяти, 128 ГБ флеш-памяти, Wi-Fi 6, 5G-модем и встроенный аккумулятор, и решил превратить его в сервер.
Первая попытка, полностью заменить Android на обычный дистрибутив Linux через порт postmarketOS, провалилась: страница поддержки устройства выглядела многообещающе, но на практике не работали Wi-Fi, Bluetooth и аппаратное ускорение, а сама установка закончилась чёрным экраном и «полукирпичом». Восстановление стоковой прошивки Nothing OS потребовало Windows (её пришлось поднимать в QEMU, а затем ставить на отдельную машину) и заняло отдельный квест. Вывод автора: у Android уже есть рабочие драйверы для всего железа, Wi-Fi, управления питанием, батареи, GPU, модема, и выбрасывать это ради «обычного» пользовательского окружения было ошибкой.
Во второй попытке Android остался нетронутым, а роль хост-окружения досталась Termux: он даёт OpenSSH, супервизор процессов runit, Caddy, Cloudflared и обычный набор Unix-инструментов. Termux:Boot запускает supervisor и SSH после каждой перезагрузки, а Tailscale выдаёт телефону стабильный приватный адрес в личной сети автора. Поскольку штатное управление питанием Android плохо совместимо с ролью сервера, Ansible-плейбук дополнительно накатывает на телефон профиль: постоянную блокировку сна, отключение лёгкого и глубокого простоя, исключение Termux, Termux:Boot и Tailscale из фоновых ограничений, отключение лимитера дочерних процессов, запрет на отключение Wi-Fi и Tailscale в роли always-on VPN.
Приложения запускались как обычные Linux ARM64 OCI-образы через proot-distro, эмуляцию файловой системы Debian поверх Termux без root-прав и без специального ядра. Для большинства сервисов этого хватало, но для чувствительной к задержке нагрузки, самого браузера Surf, прослойка PRoot оказалась узким местом: запуск процессов, открытие библиотек и работа с профилями браузера проходили через её эмуляцию слишком медленно. Ради этого автор всё же получил root на телефоне, не чтобы заменить Android, а чтобы монтировать ту же файловую систему Debian и заходить в неё настоящим chroot. Улучшение производительности автор описывает без обиняков: оно оказалось «не мелким». После этого на chroot перевели и остальные, менее требовательные сервисы; Docker и компилятор на телефоне теперь вообще не нужны, рабочая станция автора резолвит образ по дайджесту, экспортирует его файловую систему, а Ansible проверяет и разворачивает её на телефоне.
Весь хост управляется декларативно через Ansible: версии, определения сервисов, маршруты, настройки питания, секреты и проверки здоровья лежат в одном приватном репозитории. Релизы закрепляются по дайджесту или чек-сумме и разворачиваются в версионированные каталоги за атомарной символьной ссылкой current; неудачная проверка чек-суммы или health-check останавливает выкладку, откат, это просто возврат к прежней версии в Git. Секреты в открытом виде на телефоне не хранятся: значения Ansible Vault лежат зашифрованными в репозитории, а пароль от хранилища получают, попросив SSH-агент 1Password подписать фиксированный вызов, сам приватный ключ на телефон никогда не попадает.
Отдельная задача, трафик из дома. HTTP-приложения идут через Cloudflare Tunnel: телефон сам инициирует исходящее соединение, Cloudflare направляет по нему запросы по имени хоста, а локальный Caddy раскладывает их по loopback-портам; входящих правил на роутере при этом нет вовсе, поэтому при смене сети туннель просто переустанавливается. Для браузера Surf этот путь не подошёл: его соединение чувствительно к задержке, само терминирует TLS, а старый iPad, который к нему подключается, жёстко привязан (pinning) к идентичности сервера, обычный туннель Cloudflare, терминирующий TLS на своей стороне, для этого не годится. Дома используется Cloudflare DDNS и проброс одного порта на роутере; iPad в локальной сети подключается напрямую. Для случаев вне дома автор обернул весь TLS-поток Surf в обычный WebSocket: Cloudflare видит и пересылает WebSocket, а настоящее аутентифицированное соединение Surf остаётся зашифрованным сквозным образом внутри него, ценой ещё одного сетевого прохождения (round trip); при первом тесте такого подключения задержка iPad составила около 60 мс. Итог автор описывает так: телефон остался включённым дома, а он сам с рабочего ноутбука через Tailscale подключился к рабочей станции и телефону из офиса и пользовался старым iPad через размещённый на телефоне Surf, VPS для этого больше не понадобился.
Ключевые факты
- Автор перенёс личную инфраструктуру (веб-приложения, удалённый браузер Surf, трекер личных финансов, сервис демонстрации экрана) с небольшого VPS Hetzner на уже купленный смартфон CMF Phone 1, восемь ARM-ядер, 8 ГБ ОЗУ, 128 ГБ флеш-памяти.
- Первая попытка, заменить Android на дистрибутив postmarketOS, провалилась: не заработали Wi-Fi, Bluetooth и аппаратное ускорение, устройство ушло в чёрный экран, восстановление стоковой Nothing OS потребовало Windows в QEMU.
- Итоговая схема оставляет Android нетронутым: Termux как хост-окружение (runit, Termux:Boot, Tailscale), Ansible-профиль отключает энергосбережение Android, приложения запускаются как Linux ARM64 OCI-образы через proot-distro или, для требовательного к задержке браузера Surf, через настоящий chroot после получения root, переход с proot на chroot дал заметный, «не мелкий», прирост производительности.
- Вся конфигурация хоста, версии сервисов и секреты декларативно управляются через Ansible и Git: релизы закрепляются по чек-сумме/дайджесту, разворачиваются за атомарной символьной ссылкой, откат, возврат к прежнему коммиту; пароль Ansible Vault получают через подпись SSH-агентом 1Password, так что приватный ключ на телефон не попадает.
- Входящий трафик для HTTP-сервисов идёт через Cloudflare Tunnel и Caddy без открытых портов на роутере; для чувствительного к задержке браузера Surf, привязанного к идентичности сервера через TLS pinning, дома используется прямой проброс порта, а вне дома весь TLS-поток обёрнут в WebSocket поверх того же туннеля (задержка около 60 мс при первом тесте).
Почему это важно
История показывает практическую альтернативу аренде облачного сервера: смартфон, который и так лежал в ящике, оказался мощнее и надёжнее, чем ожидалось, восемь ARM-ядер и 8 ГБ памяти хватило на замену полноценного VPS, включая ресурсоёмкий удалённый браузер. Это часть более широкого движения домашнего самостоятельного хостинга (self-hosting/homelab), где идея не в экономии нескольких долларов в месяц, а в контроле над собственной инфраструктурой и переиспользовании железа, которое иначе простаивало бы.
Кому это важно
Материал адресован разработчикам и энтузиастам домашнего хостинга, которые хотят снизить зависимость от облачных провайдеров и по-другому взглянуть на старые смартфоны как на вычислительное железо. Полезен и тем, кто интересуется Ansible-подходом к инфраструктуре как коду в личных, непромышленных масштабах, а также тем, кто настраивает удалённый доступ к браузеру или приложениям через нестабильную домашнюю сеть.
Как это применить
Практический рецепт из поста: не сносить Android, использовать его как слой для работы с железом (Wi-Fi, батарея, GPU, модем), а поверх поднимать Termux с runit в роли супервизора сервисов и Termux:Boot для автозапуска после перезагрузки; стабильный адрес для администрирования даёт Tailscale. Android-профиль в Ansible должен явно отключать агрессивное энергосбережение (wake lock, исключения из ограничений в фоне, запрет отключения Wi-Fi). Обычные приложения можно запускать как OCI-образы через proot-distro без root; для нагрузок, чувствительных к задержке, root и настоящий chroot. Для входящего HTTP-трафика без открытых портов на роутере подходит Cloudflare Tunnel с Caddy на loopback; для TLS-pinned соединений, которые не переживают терминацию TLS на стороне туннеля, обёртка потока в WebSocket.
Можно ли доверять
Это личный отчёт разработчика от первого лица на собственном блоге, с конкретными техническими деталями (архитектура, конфигурация Ansible, схемы прохождения трафика) и указанием на реальные проблемы, с которыми он столкнулся, включая собственные неудачи (провал с postmarketOS, «полукирпич»). Материал набрал 331 балл и 131 комментарий на Hacker News, техническая аудитория его заметно обсуждала, что говорит в пользу правдоподобия описанного, но независимая проверка утверждений автора (кроме реакции комментаторов) отсутствует. Настоящее имя автора в тексте не указано, подписан псевдонимом seg6.
Риски и подводные камни
Получение root на телефоне и перепрошивка несут реальный риск окончательно «окирпичить» устройство, автор сам описывает момент, когда телефон завис с чёрным экраном. PRoot и даже chroot в этой схеме остаются средой совместимости, а не границей безопасности: все процессы делят с Android одно ядро и сетевой стек, поэтому изоляция между приложениями слабее, чем у полноценных контейнеров или отдельной виртуальной машины. Итоговый сервер, не обычный Linux-сервер: в нём нет systemd и стандартного демона Docker, что ограничивает совместимость с типовыми инструментами эксплуатации. Схема зависит от домашнего интернета и мобильной батареи телефона, а туннелирование TLS-потока Surf через WebSocket добавляет дополнительный сетевой переход и заметную задержку при подключении не из дома.
«Это не обычный Linux-сервер. Здесь нет systemd, нет привычного демона Docker, и притворяться, что они есть, незачем. Но под всем этим, ядро Linux с очень мощным пользовательским окружением, и этого оказывается достаточно.»
— автор поста (seg6)