DEV Community

Gerus Lab
Gerus Lab

Posted on

We Turned a Broken Android Phone Into a Home Dev Server (Vibe-Coded the Whole Thing)

At Gerus-lab, we build production systems for Web3, AI, and SaaS clients every day. But sometimes the best engineering lessons come from weekend projects — specifically, from a cracked-screen Xperia XZ1 that was collecting dust in a drawer.

This post is about turning old hardware into a real dev server, vibe-coding the setup with AI, and what that experience taught us about where AI-assisted development actually belongs.

The Problem: A Laptop Is Not a Server

We run a lot of internal tools at Gerus-lab: internal APIs, monitoring scripts, AI assistants, Telegram bots that ping us when something breaks. For a while, these ran on a dev laptop — which meant every time the laptop went to sleep, the tools died.

The obvious answer is "just rent a VPS". And we do, for production. But for personal internal tools? You don't want to pay $10-20/month for something that only serves you. You want something that's always on, locally available, and zero-cost.

That's when someone on our team looked at the pile of old devices in the office and asked: why not a phone?

Why an Old Flagship Phone Is Surprisingly Good Hardware

Here's the thing people forget: flagship phones from 5-6 years ago had incredible specs. An Xperia XZ1 (2017) has:

  • Snapdragon 835 (8-core, 2.5 GHz)
  • 4GB RAM
  • 64GB internal storage
  • Always-on USB
  • Battery with charge control options

That's a machine that runs circles around the $5/mo VPS tier. And it's sitting in a drawer not doing anything.

The catch: Android isn't a server OS. But with root access and the right setup, it becomes one.

The Vibe-Coded Setup (Yes, Really)

We want to be honest about something: we vibe-coded significant parts of this setup. Meaning we described what we wanted to an AI agent, it generated code, we ran it, hit errors, fed errors back to the AI, and iterated.

Here's the actual stack we ended up with:

├── termux/                    # Linux environment on Android
│   ├── sshd                  # SSH server for remote access
│   ├── nginx                 # Reverse proxy
│   └── go-services/          # Internal API services
├── USB Ethernet adapter      # Stable wired LAN connection
├── Charge control daemon     # Prevents battery swell (80% cap)
└── Vosk + SileroTTS          # Voice interface (bonus)
Enter fullscreen mode Exit fullscreen mode

The most painful part? Getting a USB Ethernet adapter to work. The phone's kernel didn't include drivers for the chip in the TP-Link hub we bought. We had to recompile the kernel with the right driver modules — something we absolutely would not have figured out as fast without AI assistance walking us through the process.

# Check which USB devices are recognized
lsusb

# If your Ethernet adapter isn't showing up, you need kernel modules
# Check what's currently loaded
lsmod | grep -i cdc

# For ASIX-based adapters (common in TP-Link USB hubs)
# You'll need to recompile with CONFIG_USB_NET_AX88179_178A=y
Enter fullscreen mode Exit fullscreen mode

Once networking was sorted, the rest was surprisingly smooth.

Setting Up Termux as a Real Server Environment

Termux is the key piece. It gives you a proper bash environment, package manager, and the ability to run actual server software on Android — no root required for most of it.

# Install core server tools
pkg update && pkg upgrade
pkg install openssh nginx golang python

# Start SSH server
sshd

# Generate keys on your main machine
ssh-keygen -t ed25519 -C "homelab"
ssh-copy-id -p 8022 user@phone-ip

# Now you can SSH in from anywhere on the LAN
ssh -p 8022 user@192.168.1.x
Enter fullscreen mode Exit fullscreen mode

For services, we use Go — it compiles to a single binary, has minimal runtime overhead, and ARM builds work perfectly on phone hardware:

// Simple internal API hub in Go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"
)

type HealthResponse struct {
    Status    string    `json:"status"`
    Timestamp time.Time `json:"timestamp"`
    Host      string    `json:"host"`
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(HealthResponse{
        Status:    "ok",
        Timestamp: time.Now(),
        Host:      "xz1-homelab",
    })
}

func main() {
    http.HandleFunc("/health", healthHandler)
    fmt.Println("Internal API running on :8080")
    http.ListenAndServe(":8080", nil)
}
Enter fullscreen mode Exit fullscreen mode

Cross-compile from your dev machine:

GOOS=linux GOARCH=arm64 go build -o api-server main.go
scp api-server user@phone-ip:/data/data/com.termux/files/home/
Enter fullscreen mode Exit fullscreen mode

Battery Management: The Critical Part Nobody Mentions

This is where people brick their setups. If you leave a phone plugged in at 100% charge 24/7, the battery will swell within months. This is dangerous.

The solution: charge limiting. With root access, you can set a charge cap:

# On rooted devices, write to the battery charge control file
# Location varies by device — common locations:
echo 80 > /sys/class/power_supply/battery/charge_stop_threshold

# Or for persistent settings, add to init.d script
# Some ROMs have built-in charge control — check first!
Enter fullscreen mode Exit fullscreen mode

For the XZ1 specifically, a custom ROM with built-in charge control was available. Always check your specific device before messing with sys files.

The Bonus: AI Voice Assistant

Once you have a device that's always on, with a microphone and speaker, connected to your LAN... it's basically a smart speaker waiting to happen.

We added:

  • Vosk — offline speech recognition (Android build available)
  • SileroTTS — text-to-speech (required some hacking to get Android build working)
  • A simple Go HTTP server as the routing hub
  • Connection to an LLM API for the actual intelligence

Latency is surprisingly good: local processing (speech in/out) is in milliseconds. The only slow part is the LLM API call — which is the same regardless of where you run it.

What This Taught Us About Vibe-Coding

Here's our honest take after this project: vibe-coding is a tool, not a replacement for engineering judgment.

Things AI handled well:

  • Boilerplate Go service code
  • Nginx config snippets
  • Debugging kernel module issues (explaining what the error meant)
  • Writing shell scripts

Things AI got wrong or couldn't help with:

  • Specific hardware quirks (you have to find the right kernel config flag yourself)
  • Security model of what should and shouldn't be exposed
  • Architectural decisions about how services should talk to each other

At Gerus-lab, we use AI assistance in our client projects too — for Web3 development, AI integrations, and backend systems. But we review everything before it ships. The AI-generated code for this phone server? We'd never put it in production without a full audit. For personal internal tools that serve one person? Totally fine.

The line is: who's affected if this breaks? If it's just you — ship fast, iterate, have fun. If it's a client's users — engineer properly.

Should You Do This?

Yes, if:

  • You have an old flagship phone (2016-2020 era) with a dead screen or cracked glass
  • You want always-on internal tools without VPS costs
  • You enjoy tinkering with hardware
  • You're comfortable with Linux basics

Maybe not, if:

  • You need more than ~4-8GB RAM
  • You need GPU compute (you could do this with certain Android devices that have decent GPUs, but it's much more complex)
  • You need persistent block storage beyond what the phone has

For the dev tool use case — internal APIs, monitoring, Telegram bots, personal AI assistants — an old flagship is genuinely excellent hardware.

The Full Stack We're Running Now

Since we kept adding things:

Service Purpose Tech
API hub Routes requests between services Go
Telegram bot Alerts + internal queries Go + webhooks
Monitoring Ping checks, service health Python
Voice assistant LAN-local AI queries Vosk + SileroTTS + LLM API
Emotion journal app Original reason this started Kotlin + local API

Total cost: one USB hub (~$15). Everything else: hardware we already owned.

The Bigger Picture

There's something philosophically interesting about this project: we talk a lot about sustainability in tech — not buying new hardware, reducing e-waste. Old smartphones are the most discarded category of consumer electronics. They're also incredibly capable computers.

A phone from 2017 running a Go API server and a voice assistant, consuming maybe 2-5 watts, beats a Raspberry Pi on raw compute while costing literally nothing because you already own it.

At Gerus-lab, we're fans of pragmatic engineering — using the right tool for the job, including the tool that's already in your drawer.


Working on a project that needs always-on infrastructure, AI integration, or backend services? We'd love to talk. Check out gerus-lab.com or reach out directly — we work with startups and teams building in Web3, AI, SaaS, and GameFi.

What's the most creative server setup you've built? Drop it in the comments — we're always looking for inspiration.

Top comments (0)