My server is a phone now
My Server is a Phone Now
By seg6 | August 4, 2026
I have successfully rooted a CMF Phone 1 to host my personal home infrastructure.
Previously, my digital life resided on a modest Hetzner VPS. This setup handled several web applications, a Caddy server, and a remote browser known as Surf. However, Surf eventually made the limitations of a shared VPS impossible to ignore.
When Chrome had to perform heavy lifting, the cheapest shared instances felt starved for resources. While upgrading to dedicated CPU machines would solve the performance bottleneck, the monthly cost made a personal browser feel like a .
Buying new hardware wasn't a great alternative either. Because DRAM prices have become completely absurd, building a new machine with sufficient memory felt like a poorly timed investment. I flirted with the idea of used mini PCs or using my main desktop as a part-time server, but then I remembered a device sitting in my drawer.
The Hardware
The CMF Phone 1 is essentially an overqualified server in a pocket-sized form factor:
| Component | Specification |
|---|---|
| CPU | 8 ARM Cores |
| RAM | 8 GB |
| Storage | 128 GB Flash |
| Connectivity | Wi-Fi 6 & 5G Modem |
| Power | Built-in Battery Backup (UPS) |
After some tinkering, this phone now hosts my finance tracker, a screen-sharing tool, Surf (with its managed Chrome instance), and various small web apps. These services are deployed via Git, survive reboots, and remain accessible across different networks.
The First Bad Idea: Replacing Android
My initial instinct was to wipe the slate clean and flash a standard Linux distribution. I found a postmarketOS port for the CMF Phone 1. While the device page had enough "green boxes" to entice a reckless user, I ignored the "broken" labels on critical components:
- Wi-Fi
- Bluetooth
- Hardware Acceleration
The result was a splash screen followed by a void of black. The recovery process was a nightmare: I had to run Windows inside QEMU, battle MediaTek drivers and USB passthrough, and watch the flashing tool freeze repeatedly. At one point, the device was soft-bricked, and I feared I had created an expensive paperweight.
Lesson Learned: Android already possesses the proprietary drivers for the GPU, modem, power management, and Wi-Fi. Trading that stability for a conventional userspace was a mistake.
I didn't need a Linux OS; I needed a way to run Linux applications while letting Android handle the hardware.
Termux as the Host Environment
My second attempt involved keeping stock Android and using Termux as the primary host. This provided a robust Unix-like environment with:
OpenSSHfor remote accessrunitfor service managementCaddyandCloudflaredfor networking- Standard package management
To ensure stability, I used Tailscale, giving the phone a persistent private IP. Now, I can simply run ssh cmf from any device on my tailnet.
The Technical Nuance
It is important to note that Termux is not a virtual machine. It executes processes against the Android Linux kernel, but because it uses a Bionic-based userspace, you cannot simply drop standard Debian images into it. This separation actually became an advantage: Termux acts as the lightweight control plane, while individual apps bring their own required filesystems.
Taming Android's Battery Logic
Android is designed to kill background processes—the opposite of what a server needs. I used an Ansible playbook to apply a specific "server profile":
- Install persistent wake lock
- Disable light and deep idle modes
- Exempt
Termux,Termux:Boot, andTailscalefrom background restrictions - Disable the child process limiter
- Prevent Wi-Fi suspension
- Set Tailscale as the "Always-on VPN"
The Boot Sequence
The Second Bad Idea: PRoot
Since most of my apps are distributed as ARM64 OCI images, I initially used proot-distro to run them within a Debian environment.
PRoot works by intercepting filesystem and process operations in userspace, tricking the process into thinking it's in a Debian root filesystem without requiring root access or kernel modifications. While convenient, it introduced a performance tax.
The PRoot Bottleneck:
For the Surf browser, the overhead was noticeable. Every time Chrome opened a library, read a profile, or shuffled capture data, it had to pass through the PRoot translation layer.
| Feature | PRoot | Chroot (Rooted) |
|---|---|---|
| Root Required | No | Yes |
| Performance | Slower (Userspace translation) | Native (Kernel speed) |
| Isolation | High | Medium |
| Complexity | Low | Moderate |
To fix this, I rooted the phone. I didn't do this to replace Android, but to allow a native chroot into the Debian filesystem.
# Conceptual flow of the final setup
Termux (runit) -> chroot /mnt/debian/ -> Chrome/Surf (Native Speed)
By using chroot, the workload finally reached the Android kernel directly. runit still manages the lifecycle, and data remains in Termux storage, but the performance is now native.