The Pocket Data Center: A OnePlus 6 as an Always-On Linux Server
There's a graveyard of retired flagship phones in desk drawers. My OnePlus 6 has a flagship-class ARM64 chip that comfortably outruns a Raspberry Pi 4's, 8 GB of RAM, plus something no single-board computer ships with: a built-in battery that doubles as a UPS. The only thing holding it back as a server was Android.
So I wiped it, put a mainline Linux kernel on it, and turned it into a low-power, always-on server for my own services.
The OS and the Container Stack
Running server workloads inside Android (Termux and friends) is a fun novelty, but you're fighting the OS for every background process, and real container tooling is off the table. I wanted a real Linux system.
I unlocked the bootloader and flashed postmarketOS. Built on Alpine Linux, it has a tiny footprint: the result was a headless Linux box that left nearly all of the phone's resources to the workloads.
With the Docker daemon running on ARM64, I deployed self-hosted, containerised services:
- Home automation: central routing for my local IoT devices.
- Gitea and Coolify: a personal Git server and deploy pipeline, so I could push code and have it deployed on the phone.
Overcoming Hardware Friction
A phone running 24/7 as a server has three natural enemies: its own battery, storage wear and the power going out. Each needed an engineered answer.
The "spicy pillow" problem
A lithium-ion cell held at full charge around the clock ages fast and can swell. I wrote a small charge-limiter service that drove the kernel's charging controls under /sys/class/power_supply/: charging stopped at 60% and resumed only when the battery fell below 40%. Holding the cell in that window kept it out of the high-voltage range that drives swelling.
eMMC death by IOPS
Databases and CI tools write constantly, and a phone's internal eMMC storage isn't built for that kind of write amplification. A USB-C OTG adapter mounted an external SSD, and /var/lib/docker lived there; the eMMC only booted the OS, while all heavy I/O landed on the SSD.
UPS duty and low-battery alerting
On battery, the phone was its own UPS during a power cut, but I still needed a warning before the battery ran out. The battery monitor also watched the discharging state: on battery and below 15%, it fired a webhook and an SMS alert, then shut the Docker containers down cleanly.
Out-of-Band Alerts Over the Cellular Modem
An alert that can only travel over the network it's reporting on isn't much of an alarm. With a SIM in the phone's Qualcomm modem, ModemManager exposed the modem's messaging to Linux, turning the device into an out-of-band SMS alerter for the low-battery alerts described above.
Voice calls were the fun part. On mainline kernels, routing the modem's digital voice stream (PCM) to the internal earpiece often fails without proprietary DSP firmware, so I went around it. With a wired TRRS headset and ALSA routing the call audio to the 3.5 mm jack instead of the earpiece, the phone made and received live cellular calls straight from Linux.
Zero-Trust Exposure
To reach dashboards and APIs from outside without opening ports on my home router, the phone ran a Cloudflare Tunnel (cloudflared): an outbound-only connection, with TLS terminated at Cloudflare's edge, DDoS protection and identity-based access control in front. No port forwarding, nothing listening on the public internet.
The Efficiency Metric: Power and Cost
Engineering isn't only about making things work; it's about running them efficiently. An older 1U rack server or a typical homelab box draws roughly 120 W at idle or light load. This phone ran the same light container workloads on an average of about 4 W.
Enter your local electricity rate to see the yearly difference: