During COVID I needed a new computer. Something powerful enough to be a daily driver, but quiet enough that it wouldn't sit in my bedroom whirring like a jet on a runway. Dell had just brought the XPS 17 back from the dead, so that's what I reached for — and somehow walked away with three of them. The plan was to game remotely over Parsec.
The XPS 17 was supposed to be an awesome platform. I upgraded mine to the hilt: 64 GB of RAM and a bigger NVMe. But it shipped with a couple of fatal flaws. The most maddening was a memory leak in the internal iGPU driver that would happily chew through 128 GB of RAM and swap given the chance. The other was a power bug where, under max performance, the machine would slowly drain its own battery — while plugged in.
The XPS 17 was supposed to be my desktop replacement. Instead, it became the thing that pushed me to switch to a Mac.
So after I moved to an M2 Max MacBook Pro, the three XPS laptops sat idle. They'd get pulled in for odd jobs here and there — and this is no different.
Enter my build infrastructure. Today it's a handful of small VMs on a PowerEdge R620. It's a capable box, and frankly it handles my CI/CD builds just fine. But a few of my repos want more oomph than the rest. As my projects have grown and I've leaned harder on CI/CD, that little batch cluster started getting pegged for hours at a time — and development got slower than I'd like.
Then it dawned on me: I had an XPS 17 sitting right next to my desk. Why not give it a whirl?
I put act_runner and gitlab-runner on the same machine and started asking AI what the optimal build platform looked like — having it write up the Ansible playbooks to make standing it up quick.
The payoff was immediate. A build that used to take ~40 minutes now finishes in ~10 — a 4x cut.
I also scoped the build server down to exactly what it needs, on its own isolated VLAN: the internet and a few internal resources, nothing more. That keeps things clean — and safe, if the box is ever compromised.
With fast NVMe to boot, this workstation is finally getting a second life as a build server, and it's working beautifully. This post is how that laptop became prb-bld-01, and the handful of laptop-specific gotchas that stood between "boots Ubuntu" and "a build node I'd actually trust."
The Box
The hardware is that same Dell XPS 9700 from the Covid buying spree: an Intel i7-10875H (8 cores / 16 threads, 5.10 GHz single-core ceiling), the 64 GB of RAM I'd upgraded it with, and the internal WD SN730 NVMe. For the actual job — CPU and RAM — that's a genuinely strong spec. The best part is that it now does exactly one thing — builds — instead of being a daily driver fighting its own driver bugs.
And here's the quietly satisfying part: most of those bugs were Windows bugs. The iGPU memory leak and the battery-draining power gremlin that soured me on this machine were was an artifact of Dell's Windows driver stack, not the silicon. Reimaged to Ubuntu Server 26.04, the laptop simply doesn't exhibit them it — no runaway iGPU memory growth~~, no charge bleeding away under load~~. The hardware was fine all along; the platform was the problem. Trading Windows for Linux turned a flaky daily driver into a stable server.
Update (June 2026): I spoke too soon on the battery. After running the box harder — pushing the CPU and the GPU under sustained load instead of CPU-bound builds alone — the old power gremlin came back. Under enough draw, the machine still bleeds its battery while plugged in, exactly as it did under Windows. Ubuntu 26.04 didn't fix it — so this one was never just a Dell driver bug, it's the hardware itself. None of this matters to a node that lives on wall power, but the "the platform was the problem" verdict only holds for the iGPU leak; the charge-drain bug is here to stay.
It comes online as prb-bld-01 on its own isolated VLAN. The VLAN gives it exactly what it needs and nothing more: egress to the internet for base images and packages, plus reach to git.svc, the internal Gitea host. The rest of my network is walled off, so if a build job ever pulls something nasty, the blast radius is one laptop on a stub network.
Imaging
Before any automation touches it, the box gets a clean install.
I reimaged it to Ubuntu Server 26.04 LTS ("Resolute Raccoon"), installed onto the internal SN730. 26.04 is fresh — pre-26.04.1, so an early-adopter release in general — but I checked the one thing that actually gates my playbooks first: the Docker apt repo publishes the resolute codename, so the install resolves cleanly. (24.04 "Noble" remains a fine fallback if you'd rather not ride the new release.)
Two BIOS changes matter on a headless box:
- Disable Secure Boot. On a machine I'll never sit in front of, Secure Boot just means the NVIDIA kernel module needs a MOK-enrollment dance at every driver bump — a one-time password typed into a blue firmware screen on the next reboot. That's fine on a desktop you're looking at; it's a trap on a box whose only interface is SSH. Off it goes.
- Set the charge profile to "Primarily AC Use." The box lives plugged in forever, and this is Dell's mode built for exactly that — it babies the battery instead of pinning it at a hot 100% all day.
Teaching a Laptop to Be a Server
A laptop's instincts are all wrong for this. Close the lid and it wants to sleep; leave it idle and it throttles itself to sip power it isn't even running on. A small Ansible play sorts the obvious stuff — lid stays awake, sleep and suspend masked — and the thing settles into being a very flat 1U with a built-in UPS.
The fun one was performance. My first real build topped out around 3.3 GHz on a chip that turbos to 5.1. The usual Linux suspects were all innocent; the real culprit was a Dell firmware profile quietly capping power delivery. A one-time nudge to its performance mode and the clocks came right back.
Then there's the battery. A machine that lives on AC sits at 100% forever, slowly cooking the cell, so I let the BIOS baby it — that's what the "Primarily AC Use" charge mode is for. There's a nice irony in nursing the battery of the very laptop whose battery bug helped chase me to a Mac — with a twist: in that mode the OS still reports 100% even though charging stopped twenty points ago. The cap works; the number just lies to you.
Two Forges, One Box
The laptop earns the bld in its name by running two CI runners at once — a Gitea act_runner and a gitlab-runner — because my fleet has two git forges and I didn't feel like choosing. Both build through Docker and pull base images through a shared cache, so a layer fetched for one pipeline is warm for the next no matter which forge kicked it off.
Saving the NVMe
CI is brutal on a consumer SSD. Every docker build writes and rewrites gigabytes of image layers, and a busy day of pipelines can throw more writes at the drive than months of ordinary desktop use. The NVMe in here is a perfectly good consumer part, but consumer flash has finite write endurance — and a build server is a write amplifier. Left alone, it would happily eat through the drive's life in a year.
So the churniest part never touches the disk. The scratch layer store — where every build assembles its image, stacks up layers, and then throws the whole thing away — lives in RAM instead of on flash. That buys two wins at once: builds get faster, because those layer writes hit memory instead of the SSD, and the drive is spared the bulk of the churn. The images actually worth keeping still live on the NVMe; a nightly job just sweeps the throwaway ones and hands the freed space back. The net effect is that the drive sees a small fraction of the writes a naive setup would inflict on it — the difference between "replace this SSD next year" and "forget it's even there."
How It Turned Out
It stuck. prb-bld-01 now quietly handles the bulk of CI for the whole fleet, and the build that used to take ~40 minutes finishes in ~10. With the laptop carrying the load, the old datacenter build VMs got powered off into cold standby — not deleted, just waiting in case the laptop ever falls over.
The hardware was free; I already owned it and it was doing nothing. A machine that once devoured 128 GB of swap and drained its own battery on AC turned out to be a perfectly good build node the moment its only job was building. The flaws that made it a miserable laptop simply don't matter to CI.
It's the lesson I keep relearning, same as the Tesla P4 post: the idle hardware you already own is almost always the highest-leverage thing in the room. This XPS was a disappointment as a laptop — flaky enough to push me onto a Mac — but a reimage and an afternoon later it's carrying the fleet's builds. It didn't have to be perfect. It just had to be the machine that wasn't already busy. Now I just need to find it a better home than the corner of my desk.