cd ..

The Pocket Data Center: A OnePlus 6 as an Always-On Linux Server

Context: Independent, 2026 | Hardware: OnePlus 6 (ARM64) | OS: postmarketOS (Alpine-based) | Role: Bare-metal engineering
postmarketOS Alpine Linux Docker on ARM64 Linux power_supply sysfs Cloudflare Tunnel ModemManager · ALSA

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:

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:

$157.68 1U server, 120 W, per year
$5.26 This phone, 4 W, per year
$152.42 Saved per year
Note on hardware lifespan: the server ran 24/7, and the 40–60% charge window kept the battery out of the high-voltage range that drives swelling.