Everything Wants a Second Life

Nothing has only one use until you decide it does.

If I Can't See It, I Don't Understand It

Nothing has only one use until you decide it does.

If I Have to Do It Twice, I Build a System

Nothing has only one use until you decide it does.

Think Inside the Box

Nothing has only one use until you decide it does.

Embrace the Mistake

Nothing has only one use until you decide it does.

Friday, September 11, 2026

From a Broken Laptop to a Server

I live on a very small Caribbean island, so there isn't much of a market for used technology. Most of my opportunities come from Facebook Marketplace, and because the population is small, good deals don't show up very often.

So when I saw someone selling two relatively new HP laptops with broken screens, I stopped to look.

It was a little strange. Screens don't usually just break from normal wear and tear, and I had no idea what had happened to them. My best guess: someone kept stacking heavy things on top of them. But honestly, that didn't matter much to me.

Broken HP laptop screen, shattered display pattern

They were relatively new models — an HP G8 and an HP G9, one with an Intel processor and the other with AMD. I started doing the math in my head.

Maybe $50 for a laptop. Another $50 for a replacement screen. I could do the repair myself, and I'd have a perfectly useful laptop for using in bed at night without having to turn on my main computer.

I offered $100 for both. We eventually settled on just one.

Then I checked the specifications more carefully. The screen resolution was pretty basic, and once I couldn't find the replacement screen I wanted — at the resolution I actually cared about — I started thinking about it differently. I didn't actually need another laptop collecting dust.

What I needed was another server.

So instead of replacing the screen, I turned it into a headless machine.

Broken laptop connected to external monitor during setup

Why move multimedia off my main machine in the first place

Running a home server has given me a lot of freedom, and I've learned a huge amount along the way. But one thing became obvious pretty quickly: different services need different things, and lumping everything onto one machine isn't always the smart move.

My multimedia services — music and video streaming — were originally running on my main desktop, IMPERFECT. It made sense at first: powerful CPU, plenty of RAM, no problem handling the load. But that was exactly the issue. I was keeping a full desktop running around the clock just so a movie or a song would be available if someone wanted one. Power consumption aside, it was also just annoying — if I wanted to watch something, I had to go turn the computer on first.

That's backwards. A media server should be the thing that's always on, quietly waiting. The desktop should be the thing I turn on when I actually need to do something with it, not the thing I have to boot just to press play.

So the broken laptop solved two problems at once: it gave the multimedia stack a dedicated, low-power home, and it freed my main desktop from having to stay on 24/7 for services that don't need that kind of horsepower anyway.

The technical rundown, for anyone who wants it

If you're the type who wants the actual stack instead of just the story, here's what's running — and it's more than I expected to end up with when I started:

  • OS: Ubuntu Server 26.04 LTS, no desktop environment — just Docker and whatever it takes to keep the containers alive
  • Storage: the original NVMe drive, upgraded for more local headroom, plus network mounts to my NAS for anything that outgrows local disk

Services, all in a single Docker Compose stack:

Navidrome for music. Migrating it turned up its own small lesson — I went looking for the old instance's data, ready to carefully back up playlists and listening history before the move. The data volume turned out to be completely empty. Whatever I thought was being saved there, never actually was. Nothing to migrate, so I just started fresh.

Ubuntu Server terminal session during headless setup

Jellyfin for movies and series, split across two sources by design. Anything new — freshly downloaded, not yet watched, still "hot" — lands on the laptop's local disk first, in its own folder that Jellyfin treats as its own library. That's deliberate: local disk is fast, and I don't want new content depending on network speed or NAS availability the first time someone wants to watch it.

Once something has been watched and isn't "new" anymore, it gets moved manually over to the NAS — which is where the bulk of the actual library lives, mounted read-only inside the container. I haven't automated that move yet. I want to actually live with the manual process for a while first and see what "not new anymore" really means in practice before I write a script that decides that for me. The plan, eventually, is something that sweeps the local folder on a schedule and relocates anything older than some threshold — but I'd rather get the threshold right by observing real usage than guess at it upfront.

Either way, from Jellyfin's side, both sources just show up as one unified library. Nobody browsing has to know or care where a given movie physically lives.

qBittorrent, no VPN in front of it. That's a cost I'm not covering right now, and I'd rather say that plainly than pretend otherwise.

FileBrowser, so moving files between local storage and the NAS doesn't mean SSHing in every time just to drag one folder into another.

  • Networking: this laptop has no physical Ethernet port at all, so everything runs over WiFi. That meant setting a static IP directly on the wireless interface — and separately reserving a static IP for a USB-Ethernet adapter I sometimes plug in for maintenance, so the two never fight over the same address if I ever use both at once. Local DNS entries point clean hostnames at all of it, and it's wired into the same family dashboard as the rest of the homelab.
  • Power: no battery — I pulled it out and genuinely don't remember where it ended up. Lid-close behavior is disabled at the systemd level, since Ubuntu's default is to suspend the machine the moment the lid shuts, which is exactly backwards for something meant to run 24/7 with the lid closed for good.
  • Monitoring: wired into my existing Uptime Kuma dashboard. If any of the four services drops, I know before anyone in the house notices the music stopped.

One thing still unresolved: Wake-on-LAN. I can't confirm whether it's even enabled in the BIOS, because — you guessed it — the screen is broken, and by the time I thought to check, the lid was already shut in its final resting spot under one of my access points. For now, it just stays on. Given how little power this thing actually draws, that's a trade I'm fine making.

And because apparently I couldn't just put it on a shelf like a normal person

I tucked it underneath one of my access points and left it there, plugged in and quietly doing its job.

Laptop tucked under a WiFi access point on a shelf

I don't even remember where I put the battery.

And that's fine.

The original idea was to find a cheap laptop for myself. What I ended up with was a little server that I didn't have to buy separately.

That's one of the things I like about this whole homelab experiment: it's constantly forcing me to reconsider what something is worth.

A broken screen doesn't necessarily mean a broken computer. An old laptop doesn't necessarily need to become someone's next laptop. Sometimes the useful part of a piece of hardware is the part you weren't originally looking at.

My kids get laptops from school that I don't necessarily need. My wife isn't particularly interested in using a laptop. And I'm not going to buy technology just because I can.

But when something comes along that I can repurpose, I don't want to automatically dismiss it just because it isn't useful in the way it was originally designed.

Friday, August 28, 2026

One Game at a Time

Parenting · Gaming · Philosophy

One Game at a Time

I remember waiting an hour by the radio for one song.

Not scrolling for it. Not streaming it on demand. Just sitting there, waiting for MTV or the radio to play it, because that was the only way to hear it again.

If I saved up enough, I'd buy the CD.

And that CD was freedom.

It meant I could finally listen to the same song as many times as I wanted.

Games worked the same way.

If I saved up for one, I played everything it had. I found the hidden levels. I tried every mode, every mechanic, every way of playing it. I even attempted speedruns, back when that word barely meant anything outside a small crowd.

Scarcity made me thorough.

My son doesn't have that problem.

He has the opposite one.

Free, paid, pirated — the options are endless. When there's always another game waiting, it's easy to pick something up, play it for a while, get bored, and move on.

Nothing forces you to finish anything.

So I decided something would.

My game library isn't small; I can afford more games. It's small for him on purpose.

Giving him access to everything I own would be easy. But that's not the point.

The point isn't giving him a world of options.

It's asking him to pick one game from the world I've already narrowed down, finish it, and only then pick again.

Dante's desktop showing a curated, limited game library

The whole library. Not that much bigger than it looks.

He doesn't get a new game until the last one is done.

Whether he finishes it well, finishes it fast, or finishes it reluctantly — that's his choice.

But there is no next game until this one is closed.

And it's already paid off.

He finished Hollow Knight.

Then Silksong.

Dante's desktop wallpaper themed around Hollow Knight: Silksong

Dante's desktop — Hollow Knight: Silksong still on wallpaper duty.

He went back and fought bosses more than once, not because he had to, but because he wanted to get better at them. He started setting himself challenges nobody asked him to attempt.

That's the part I wanted.

Not that he finished two games.

That he invested enough time in something to become genuinely good at it.

That kind of time investment leaves something behind. Video games can teach this in a simple, contained way that real life usually teaches the hard way:

What you actually invest your time in gives something back.

Sometimes immediately.

Sometimes much later.

But something remains.

That's why my son plays one game at a time.

We don't always get to choose what entertains us in life. More often than we'd like, we have to do things we don't enjoy simply because they need finishing.

I want my son to learn that lesson early, somewhere the stakes are low.

A video game.

Not a job. Not a responsibility he can't walk away from. Not something where failure carries consequences that matter.

Just a game.

If he decides to finish what he starts, and whether he finishes it well or badly, that's his decision to make.

But he won't get to start something new until he does.

And that's also why freemium games aren't part of his library.

Not because they're free.

Because many of them are designed around a completely different relationship with your time. They don't simply ask you to play. They are built to monetize attention — sometimes in ways that resemble the mechanics of a casino more than those of a traditional game.

That's a different kind of hook.

And it's not one I want anywhere near him.

I don't want to teach him that the next thing is always better.

I want to teach him that sometimes, the thing you're already doing is worth staying with.

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.

Monday, August 24, 2026

Chasing the Cheese

Homelab · Networking · Troubleshooting

Chasing the Cheese


The first thing to do today is to chase the cheese, just as a mouse does in a maze.

After going in a circle over a solution which, at first, appeared rather simple.

I had not experienced any serious network problems for more than two months. One morning, while I was quietly having my breakfast, I noticed that the connection had gone down. I then finished my breakfast, had my coffee and went to look at the monitor.

All services were down.

Perfect.

The cheese was located somewhere in the maze.

To begin with, I believed that the internet connection had simply gone down. I looked at the admin computer and found that it wasn't connected to the network. I then restarted the OPNsense server, hoping that it was one of those issues which can be fixed by a restart and some patience.

It didn't work. At that moment I understood that the problem was likely more complicated than it appeared.

There is an emergency procedure specifically for cases like this. I carried out the bypass and, for now, kept the admin computer connected directly to the ISP. The concept was straightforward: ensure that at least the basic functions continued while I worked on discovering what was going on with the main network.

It took about five or six minutes for the bypass to stabilise, but even then the connection was still not behaving properly. There's where the labyrinth started.

Wrong Turn One

The First Problem.

To begin troubleshooting I connected directly to the server.

First mistake.

When I needed to be working on the LAN, I plugged the cable into the WAN port since I was looking for a DHCP problem and so I began to check what was going on in OPNsense.

The console began to provide me with clues, even though none of them appeared to point directly to the issue.

DHCP was down.

When I checked the processes, I didn't see either dhcpd or kea-dhcp4 running; the only one there was the WAN DHCP client.

I used some commands that I had remembered from earlier installations of pfSense.

clog.

It didn't exist.

I attempted the command service dhcpd onestart.

Nothing.

Then service kea-dhcp4 onestart.

Nothing.

Finally, service kea onestart.

The system began Kea.

However, the process stopped right away.

By that stage I began to consider the possibility that I was encountering a known bug in the version of OPNsense that I was using, one that might have something to do with a socket or with a previous process which had become blocked.

I was searching for a solution on the server.

The problem did not lie there.

The Turning Point

The Piece of Information That Changed Everything.

I attempted to log in using SSH.

Timeout.

Not a connection rejection.

A timeout.

I then looked at the network configuration from a different machine and found something interesting: my Wi-Fi was on a different subnet, namely 192.168.1.x, since it was connected directly to the ISP's router through the bypass.

But then I asked a much more basic question:

Did ping ever work?

The answer was no.

Not even directly connected.

The fact about that matter completely altered the diagnosis.

I looked at the server's physical interfaces.

ifconfig igb0

And there it was:

status: no carrier.

There was never any physical connection.

I was just as puzzled by wg0, but it was a virtual interface and had no connection with the physical port.

So I checked igb1.

Here was the problem.

The cable was plugged into the incorrect physical port on the dual NIC.

I repositioned the cable to igb0.

The interface became active.

Ping.

Working.

I reconnected the WAN and checked the connection using 10 out of 10 packets with 8.8.8.8.

Problem solved.

Or so I thought.

The cheese was still dripping.

Wrong Turn Two

The Second Problem.

The network was restored.

It then began to drop every ten or fifteen minutes.

The switch would freeze, and the only fix was to turn it off and then on again.

Once.

Twice.

Three times.

Always the same.

The switch in question was a Linksys SE3008v2, a simple unmanaged switch. It had no interface available, no logs that could be examined, and no straightforward method of finding out what it was doing.

Therefore I began to look at the topology.

I had two switches.

The first held the connected critical infrastructure — OPNsense, the NUC, the NAS, and other equipment.

The second held the office computer and several access points.

You can see a map of the full network layout in this earlier post.

The first idea was simple: what would happen if I take out the first switch?

I could simplify the network temporarily and carry on with just one switch until I received a replacement.

However, there was a problem.

I couldn't remove OPNsense.

I then had to discover what was causing the switch to overload.

Then I saw it.

The lights on the switch were flashing rapidly.

All of them.

This wasn't normal traffic. It seemed as if a tiny green disco had been set up in my office.

All the evidence indicated that there was a broadcast storm.

The Hunt

Isolate the Problem.

I cut the uplink that connected Switch 1 to Switch 2.

Switch 1 settled down immediately.

The loop lived downstream. Now I needed to find exactly where.

I disconnected everything from Switch 2. Only the uplink stayed in place.

Sixty seconds. Nothing.

Ninety seconds. Still nothing.

Switch 2 itself wasn't the problem.

One by one, I started bringing devices back online.

Archer first. Twenty minutes. Clean. It was even serving internet on its own.

Then Linksys02101.

Within minutes, the uplink and Archer's port both lit up — frantic, sustained, the same green disco from before.

Linksys itself stayed almost calm.

I disconnected it.

The storm stopped in seconds.

The cause had a name now: Linksys02101.

I checked its configuration, expecting to find Wireless Bridge mode — the classic mistake, an access point talking to another one over the air while it's still wired into the same switch. Two paths. One loop.

It wasn't that.

Plain Bridge Mode. Correctly set. Exactly as it should have been.

I never found out why.

The Fix

The Solution.

Getting the Linksys off the shared network was the goal — not necessarily figuring out what was actually wrong inside it. I set it up in full router mode: its own subnet, its own DHCP running locally instead of trusting OPNsense's, a unique SSID separate from the shared mesh name, hung off the Tenda instead of the main switch. With NAT in between, it wouldn't matter what mechanism had been causing the loop — there'd be no path left for it to travel back into the rest of the network.

It froze mid-configuration. Not later, not under load — while I was still setting it up.

That settled it. Whatever was actually wrong with that router, reconfiguring around it wasn't going to fix it. It came out of service entirely, replaced for now with a simple wireless range extender — no Ethernet port at all, nothing for it to loop through even if it tried. A real mesh system is already planned for October. Until then, this holds.

The Point

A whole day, and I still don't know why.

Problems like this eat the whole day. Not almost — the whole day; this one didn't wrap up until 6 PM.

It's the kind of thing no tutorial prepares you for. I don't know if formal education ever really does, either. But I trust my contingency plans enough now that leaving the property without internet — even partially — doesn't stress me out anymore, as long as the services that actually matter keep running. Someone telling me "we have no internet" doesn't rattle me. I just tell them to wait, that I'm working on it.

I've gotten good at following a process when something breaks. But some hardware problems look simple at first and turn out to be genuinely hard to pin down — this was one of them. One of the access points, the newest one in the mesh, was quietly bottlenecking the entire network. Incredible, honestly. These are things I don't see coming. Halfway through the day, I was convinced the real problem was the OPNsense server's motherboard.

Realizing that failures like this can happen at the level of any single component means thinking about newer hardware eventually — not urgent, just something to keep moving toward. The goal isn't making sure this never happens again. It's making sure that when it does, the property keeps running while I'm away.

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.

Monday, August 17, 2026

Automating My Fire Tablet Macrodeck

Homelab · Automation · Quality of Life

Automating the Fire Tablet Dashboard (So I Stop Thinking About It)



The quality of life of the tools I use every day isn't something I'm willing to negotiate on. Throughout this whole process of building a healthy, well-managed network, I've implemented tools I rely on daily — with the catch that I have to keep track of whether I left it on, whether I left it plugged in, or whether, when I sit down to work, I need to charge it first.

More than a technical issue, this is about usability. Getting something to just work automatically usually isn't about skill — it's about taking the time to configure the right solution when the opportunity is already sitting there.

Every new service I add to a well-run network trips the same wire: something has to be started by hand.

The Problem

Two bad options, and neither one respects the hardware.

With this tablet, that meant two bad options. Either I let the screen time out on its own, then plug it back in and wait for it to charge past 2% before I could wake it and reopen MacroDeck. Or I leave it plugged in and awake permanently — and since most of what I repurpose is aging Android hardware nobody wants anymore, permanently-on is its own quiet problem.

The goal was to automate a tool I already use and already trust — not add a workaround for it. Left as-is, the tablet would either be dead when I actually needed it, or slowly wear down hardware that's already past its prime just to stay reachable.

This isn't about being lazy. It's about automating a workflow with tools that are already free and already installed, and keeping the resulting knowledge around for the next device that needs it.

First Attempt

Chasing Windows' own sleep events didn't work.

Of course, none of this was as simple as "enable ADB, add a Windows scheduled task, done." The first version tried to hook directly into Windows' own power events — Kernel-Power Event 42 to catch the system entering sleep, Power-Troubleshooter Event 1 to catch it waking up — firing an ADB script over USB at each transition. Waking worked reliably. Sleeping never did.

The reason took some digging: right as Windows logs that it's entering sleep, the USB controller is already cutting power. The ADB command doesn't have time to complete before the connection dies. It's a race condition against the OS itself, not a misconfiguration — and no amount of tweaking the trigger fixed it.

The Fix

Stop fighting the race. Switch to Wi-Fi, and let a heartbeat do the work.

The fix was to stop trying to win that race. I switched the tablet's ADB connection from USB to Wi-Fi, and let go of the idea that IMPERFECT needed to catch the exact moment it went to sleep. Instead, IMPERFECT sends a simple "still here" signal to the tablet every 58 minutes while it's on. The tablet's own screen timeout is set to 60 minutes. If that signal stops arriving — because IMPERFECT suspended, hibernated, or shut down — the tablet just falls asleep on its own, on Android's terms, with nobody needing to catch the exact moment it happened.

How it works

📶 Wi-Fi ADB — tcpip 5555, no cable needed
💓 Heartbeat — every 58 min while IMPERFECT is on
😴 Timeout — tablet sleeps on its own after 60 min of silence
🔌 Full wake — swipe + MacroDeck, on real resume from sleep

Quick Setup Guide

Get it running on your own tablet.

Requirements: ADB debugging enabled on the tablet, once, over USB

1. Enable Wi-Fi ADB (one-time, over USB)

adb tcpip 5555

2. Disable "stay awake while charging" and set the native timeout

adb shell settings put global stay_on_while_plugged_in 0
adb shell settings put system screen_off_timeout 3600000

3. wake-tablet.bat — full wake, fires on real resume from sleep

adb connect 192.168.2.170:5555
timeout /t 1 /nobreak >nul
adb -s 192.168.2.170:5555 shell input keyevent 224
timeout /t 1 /nobreak >nul
adb -s 192.168.2.170:5555 shell input swipe 300 820 300 205 300
timeout /t 1 /nobreak >nul
adb -s 192.168.2.170:5555 shell monkey -p com.suchbyte.macrodeck -c android.intent.category.LAUNCHER 1

4. heartbeat-tablet.bat — lightweight ping, every 58 minutes

adb connect 192.168.2.170:5555
timeout /t 1 /nobreak >nul
adb -s 192.168.2.170:5555 shell input keyevent 224

5. Two Task Scheduler jobs

One triggered on system resume (Power-Troubleshooter, Event ID 1) running wake-tablet.bat, and one recurring every 58 minutes running heartbeat-tablet.bat — with "start when available" enabled, so a missed cycle catches up the moment the machine wakes instead of getting skipped.

This is tuned for a Fire Tablet running MacroDeck, but the heartbeat pattern works for any always-plugged-in Android device you want to keep reachable without fighting Windows' own sleep timing.

The Point

The simple fix beat the elegant one.

Here's a solution that works — and it feels less like scripting and more like orchestrating: two devices talking to each other cleanly across a network that's already well set up and documented, like a well-run line of dominoes. None of it works without that groundwork already in place.

It's not having to think about turning things on and off, or wondering whether something's charged. This is the first step in automating my workspace — not the last.

What's the oldest device you've kept alive with a script instead of replacing it? Drop it below.

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.

Thursday, July 30, 2026

Beyond the Internet — Watching the Network

Networking · Infrastructure · Monitoring

Beyond the Internet — Watching the Network.

When I first started building my homelab, I wasn't trying to create a lab at all.

I was simply solving a problem for myself. Normally, I build things because a client asks for them. This time, I was the client. Well — the direct client, not the final one.

One service became two. Two became five. Then ten. Before I realized it, the homelab had grown into something that other people relied on every day.

And that changed everything about how I needed to think about it.

Sometimes the internet isn't the problem. Sometimes the network still has work to do — and nobody knows it until someone notices that the photos aren't syncing.

The Problem

The network might still appear online while something important is broken.

A while ago, I created a simple troubleshooting guide so anyone in the house could recover the internet if it went down. That solved one problem.

But the network is much more than internet access now. Today the homelab runs photo storage, a music server, a DNS filter, a firewall, a Cloudflare Tunnel, a service launcher, and an external management system for a client. Each of these services can fail independently — and when one does, the network might still appear "online" while an important part of it is actually broken.

That's when I realized I didn't need another troubleshooting guide. I needed visibility.

The Solution

One screen. Five services. Green or red.

I wanted anyone to be able to glance at a screen and immediately know whether everything was healthy, what service was down, and whether something needed attention. No commands. No SSH. No digging through logs.

Uptime Kuma — a self-hosted monitoring tool — runs in Docker on the NUC. It checks each service every 60 seconds and shows a simple status: up or down. That's all anyone needs to see.

Uptime Kuma showing all services green

Uptime Kuma — 5 services monitored, all green.

Monitored services

🔥 Firewall — OPNsense · 192.168.2.1
🛡️ DNS — Pi-hole · dns.home:8080
📷 Fotos — Immich · fotos.home:2283
🎵 Music — Navidrome · music.home:4533
🔧 Taller — taller.creativelydifferentbuilds.com

The Physical Dashboard

A repurposed Samsung A51 — always on, always visible.

The monitor lives on a Samsung A51 running Fully Kiosk Browser in kiosk mode — screen always on, always showing the status of every service. It connects to Uptime Kuma over the local network at monitor.home:3001.

The goal is simple: anyone in the house — whether they understand the technical details or not — can glance at the screen and know if something needs attention. Green means everything is working. Red means something needs a look.

Samsung A51 showing Uptime Kuma with all services green

Samsung A51 repurposed as a physical dashboard — always on, always visible.

The Launcher

Access for the family — no technical knowledge required.

Alongside the monitor, the service launcher now includes a card for Uptime Kuma. Anyone in the house opens servicios.home:8888 from any device — phone, tablet, or PC — and has direct access to every available service. No IP addresses. No ports to remember. Just names.



The Monitor card is now in the launcher — accessible from any device on the network.

What's Next

The list keeps growing — and that's the point.

As more services come online — home automation, security cameras, a local AI assistant, a family photo album, a music library — each one gets a card in the launcher and a monitor in Uptime Kuma. The infrastructure grows, but the experience stays simple.

Eventually, I'd like to build a guest access system — a QR code menu with curated services for visitors. A pre-selected family photo album. A shared music library. Maybe a local AI assistant. Content that's safe to share, easy to access, and requires nothing more than scanning a code.

That's still an idea. But the infrastructure to support it is already here.

Quick Setup Guide

Get Uptime Kuma running in under 5 minutes.

Requirements: Docker installed on any always-on machine

1. Run the container

docker run -d \
  --name uptime-kuma \
  --restart unless-stopped \
  -p 3001:3001 \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:1

2. Open the dashboard

Go to http://[your-server-ip]:3001 and create your admin account.

3. Add a monitor

Click + Add New Monitor → Type: HTTP(s) → enter the URL of your service → set interval to 60 seconds → Save. If the service uses a self-signed certificate, enable Ignore TLS/SSL error.

4. Add a local DNS record (optional)

In Pi-hole → Local DNS Records → add monitor.home pointing to your server IP. Now anyone on the network can open it by name.

There are many detailed guides out there for setting up Uptime Kuma — this is just the version that worked for me. If you run into something specific or need help getting it running in your setup, drop a comment below.

Real World Update

The internet was working. The photo service wasn't.

This is exactly why I built this. The internet was up. The network was running. But Immich — the photo service — went down, and the monitor caught it immediately with a timestamp.

The reason: photos don't have a permanent server yet. Immich runs on my main workstation, and when I shut it down for the night, the service goes with it. That's a known limitation — one that will be resolved when the services move to a dedicated always-on machine. For now, the monitor makes that limitation visible instead of invisible.

As soon as the workstation came back online, Immich recovered automatically. The monitor logged the downtime, the duration, and the recovery — without me having to check anything manually.

Samsung A51 showing Immich down after workstation was turned off

Immich down at 22:43 — timeout of 48000ms. Back up at 22:44 when the workstation came online. The monitor is in Spanish because my wife and kids are native Spanish speakers — the system should work for everyone in the house.

That's the point of visibility. Not to prevent every failure — but to know exactly when it happened, how long it lasted, and when it recovered. Without asking me.

The Honest State

It works perfectly. It looks like a work in progress.

Right now, the A51 is literally thrown on my desk — and it looks exactly like that. Next to the Fire Tablet running MacroDeck, the setup works perfectly but doesn't look intentional. Because it isn't yet.

"If a cluttered desk is a sign of a cluttered mind, of what, then, is an empty desk a sign of?"

— Albert Einstein

I've read that quote many times. And I agree with it — I don't want an empty desk. I want one that looks organized and functional. One that doesn't make a visitor wonder what happened here.

The plan is to mount both the A51 and the Fire Tablet on the wall with permanent connections to the PC. Everything within reach, nothing in the way. The desk stays as the workspace — the wall becomes the command surface.

That's the next project. Unless my mind takes a different route first — which, if you've read this blog, you already know is a real possibility.

The Point

A well-monitored network is one that anyone can trust.

The internet might be fine. But the network has more work to do. And now, anyone in the house can see exactly how it's doing — without asking me.

Green means everything is working. That's all anyone needs to know.

What are you monitoring in your homelab? Drop it below.

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.

Wednesday, July 29, 2026

If It Only Works for Me, It Doesn't Work.

Networking · Infrastructure · Design

If It Only Works for Me, It Doesn't Work.

When I started this blog, it was simply an excuse to write.

A place to document ideas, experiments, and the occasional lesson learned after breaking something.

My homelab started the same way. It began as a technical challenge. I wanted more control over my own infrastructure. More privacy. More ownership over the services I used every day.

At first, everything was built for one person. Me. I knew every IP address. Every port. Every password. Every service had its own bookmark, its own shortcut, its own way of being accessed.

That worked — but only for me.

If every new application requires me to explain "go to this IP address, on this port" — I haven't built a useful system. I've built a puzzle.

The Realization

This infrastructure isn't just mine.

My wife uses it. My children use it. Guests will eventually use parts of it. And hopefully, years from now, they'll use services I haven't even deployed yet.

If every new application requires me to explain "go to this IP address, on this port, using this browser" — then I haven't built a useful system. I've built a puzzle.

Don't Make Me Think

The best systems don't ask users to remember.

One idea has been influencing my thinking for years: Don't Make Me Think. Steve Krug wrote about it in the context of web design, but I believe the principle applies almost everywhere. The best systems don't ask users to remember. They don't require explanations. They simply make the right thing obvious.

I realized my homelab deserved the same treatment.

The Solution

Names instead of numbers.

Instead of asking people to remember addresses like 192.168.2.114:8080 or 192.168.2.20:2283, I configured local DNS records in Pi-hole so every service now has a name:

Local DNS records

firewall.home
dns.home
nas.home
fotos.home
music.home
servicios.home

Pi-hole local DNS records

Pi-hole Local DNS — 6 registros activos, nombres en vez de IPs.

Nobody has to remember where a service lives. Only what it does.

The Launcher

A starting point for everyone in the house.

I built a launcher that lives on any device in the house — a simple page that shows only what's relevant to each person. Not because they need access to everything. Quite the opposite.

The goal isn't to expose every service. The goal is to make the available ones effortless to find. No documentation. No explanations. No technical knowledge required.

It runs on the NUC — the machine that's always on — served by a simple Nginx container. Any device on the network opens servicios.home:8888 and sees it immediately.

Tarjetas de servicios del homelab

Servicios activos y planificados — cada uno con nombre, no con IP.

Launcher de servicios abierto en el Pixel

El launcher abierto en el Pixel — accesible desde cualquier dispositivo en la red.

The Philosophy

This may seem like a small change. Philosophically, it changes everything.

The infrastructure stops feeling like a collection of servers and starts feeling like a product. One designed for people instead of administrators.

Eventually I want to add much more — a local AI assistant, a family wiki, a digital library, internal tools, automation. The list keeps growing. But I've learned something important: every new service should become easier to discover, not harder. Adding functionality should never increase complexity.

External access is a completely different problem. That requires authentication, permissions, reverse proxies, VPNs, and much stricter security. I'll write about that separately.

Inside my network, my philosophy is simple: if someone has permission to use a service, they shouldn't have to think about how to reach it. They should simply open it.

The Point

A well-designed system disappears.

The funny thing is that this has very little to do with servers. It's really about design. A well-designed system disappears. People stop thinking about how to use it and simply use it.

That's the kind of infrastructure I want to build. Not one that impresses me. One that quietly works for everyone else.

If someone has permission to use a service, they shouldn't have to think about how to reach it. They should simply open it.

How do you handle service discovery in your homelab? Drop it below.

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.

Tuesday, July 28, 2026

Designing Around Constraints.

Philosophy · Design · A Life's Work

This is the final post in the six-part series Build Different — How I Think. If you haven't read the others, they're all worth starting from the beginning.

Designing Around Constraints.



I never start from a blank canvas. A blank canvas paralyzes me. I need something to push against — a restriction, a problem, a condition I can't ignore — before anything starts to move.

That's not a limitation I learned to work around. It's how I've always worked. And it took me most of my life to understand that it wasn't a flaw.

You never start from a blank canvas. You start from what's already there.

Before the Tools

A blank surface with no rules was uninteresting. A surface with limitations gave me something to design inside.

Before computers, before software, before design school — I drew.

Not on paper, necessarily. There were pieces of plaster chalk near the house growing up. We used them to draw on the street. In another neighborhood, I used markers on walls. Almost always monochromatic. Patterns. Mosaics. Geometric shapes on sidewalks. Not flowers or vases — my mother enrolled me in drawing classes and I was bored immediately. Still life didn't interest me. A mosaic on a sidewalk did.

I didn't know why at the time. I know now: my brain needed structure and repetition. A blank surface with no rules was uninteresting. A surface with limitations — the shape of a sidewalk tile, the width of a chalk line — gave me something to design inside.

My Father's Method

He never praised good grades. He rewarded good understanding.

My father was an engineer with more than 35 years of experience. And he had an ability that I've never seen replicated: he could explain anything to anyone using whatever was at hand.

If the person listening was an upholsterer, he explained mechanical engineering through upholstery. If they worked in pastry, he explained it through baking. If they were a designer, he spoke in design. He adapted the explanation to the way the other person processed information — not to show off, but because getting the concept across was what mattered. The medium was irrelevant. The understanding was everything.

He never praised good grades. He rewarded good understanding. His rule was simple: understand the concept first — everything else follows. Decompose the knowledge, then recompose it in a way you can work with.

I didn't know at the time that I was learning a method. I was just a sponge — absorbing everything from everyone, especially him. But that instruction became the foundation of everything I've done since: find the formula hidden inside the problem, understand it completely, and then you'll know exactly what needs to be done.

I spent 25 years absorbing that — from birth until I left home. I became an expert at seeing the world the way he saw it.

What I didn't know until much later was that this was also how he worked. He collaborated with presidents, with multinationals, with international organizations. He solved problems of extraordinary complexity. And he never announced it. He walked down the street like anyone else. The people who needed to know what he had done — knew. And they sent others. Always by referral. Always because the work spoke before he did.

I watched that for 25 years. And I absorbed it without realizing I was learning anything.

1998. The First Computer.

The blank canvas never inspired me. A specific goal always did.

I was twelve. A PC arrived at the house. I discovered the internet — version 1.0. I spent time searching for images. When I learned I could change the desktop background, that became the daily goal. Change the wallpaper. Find something better. Change it again.

That obsession led to the first practical design decisions I ever made: a folder with dividers, printed and organized. Covers printed for notebooks. Not design projects — just solutions to small needs with the tools I had.

Then came the tutorials. Photoshop at 13. 3DS Max at 15. Freehand, Illustrator, After Effects. I learned the tools without knowing the theory behind them. I designed without structure. The blank canvas never inspired me — but a specific goal always did. Make this wallpaper. Build this effect. Solve this visual problem.

University — The Why Behind the How

The university didn't teach me to design. It taught me to think in design.

I arrived at university thinking I already knew how to design. I had the tools. I had the hours. What I didn't have was the vocabulary for why anything worked.

Balance. Hierarchy. Alignment. Typography. Proportion. Repetition. Color theory. Psychology of form. High contrast techniques. Pointillism. Building a color chart from scratch. At first it felt unexpected. Then it clicked.

Every assignment arrived as a restriction — a format, a brief, a set of rules. And automatically, before I started, I already knew the direction. The constraint didn't block me. It activated me.

A friend told me after graduation that university had been easy for me because I already knew how to design. It bothered me — it made my effort seem small. I told him: the university didn't teach me to design. It taught me to think in design. I didn't fully understand what I meant until years later.

2009 — The First Hard Technical Constraint

The tightest technical constraints produced the most creative solutions.

One of my first projects after university was building a virtual world inside a web browser. This was 2009. HTML5 didn't exist yet. Web-based 3D engines were in their infancy.

I joined the team and proposed a change: use a game engine to render everything in real time inside the browser. The restriction was severe — limited polygons, baked renders, textures compressed to 1024 pixels, all running inside a browser that wasn't designed for any of it.

It didn't last long. The funding ran out. But the lesson stayed: the tightest technical constraints produced the most creative solutions. Not despite the limitations — because of them.

The Paint Factory

The box changed. The approach didn't.

After that came the paint factory — the leading brand in the Dominican Republic. Pre-made label templates. Specific color systems. Budget limits at every level. Design that had to work within the brand, within the printing process, within the cost structure. The box changed. The approach didn't.

SIUBEN — 2013. The Hardest Brief.

How do I make someone want to look at this?

I became a father before I started at SIUBEN. I arrived focused on design. The real challenge came with the first book — a national statistical study. Hundreds of pages of data. Complex tables. Dense numbers.

I physically rejected looking at a complex statistical table — and I had to make one readable. If you've read the previous post in this series, you already know why that rejection wasn't just aesthetic.

I asked myself: how do I make someone want to look at this?

The answer was the same process I had been using my whole life, applied to data for the first time: Understand the data. Decompose it into parts. Restructure it into something worth seeing.

I used the same design principles I had learned in university — contrast, form, hierarchy, typography, negative space — but applied them to statistics instead of graphics. I didn't discover how to make infographics. I discovered I already knew how. I just hadn't applied it to data yet.

The publication was a significant success. Then I repeated the model. Understand. Decompose. Restructure. Every time.

The Formula Behind Everything

Every field has a formula. The skill is understanding it — and then designing inside it.

After 20 years of working across graphic design, communications, government, construction, and technology, I've noticed that every discipline follows the same structure:

The structures

Methodology of Research
Problem → (Data + Analysis) → Interpretation → Knowledge

Creative Brief
Challenge / Need → (Audience + Insight) → Key Message → Creative Solution

Advertising Campaign
Objective → (Insight + Creative Concept) → Media Plan → Impact / Conversion

Homelab
Need / Use Case → (Hardware + Software) → Configuration → Functional Service / Automation

3D Design / Render
Concept / Plans → (Modeling + Texturing) → Lighting / Render → Final Image / Animation

Software Development
Requirement → (Code + Logic) → Testing → Deployed Application

Fabrication / Workshop
Design / Diagram → (Cutting + Assembly) → Finishing → Completed Piece / Furniture

The domain changes. The structure doesn't. Every field has a formula. The skill is understanding it — and then designing inside it.

Working Behind the Scenes

Not visibility. Function.

My father never walked around showing his portfolio like a business card waiting to be praised. He worked hard. He did it right. He didn't announce it. And the right people always found him.

I learned that by watching him for 25 years — not because he taught it as a lesson, but because it was simply how he lived.

In almost 20 years of professional work, I've worked with every type of client — commercial, institutional, governmental, international. I've never entered a competition. I've rarely shown my work publicly. What exists is on Behance and Dribbble — and most of it is years old. The rest belongs to the people it was built for, under agreements that prevent me from showing it.

That aligns with something I've understood about myself for a long time: I work best as the number two. The person who makes things function without needing to be the protagonist. The one who finds the solution inside the constraint and hands it off without a signature.

There is a specific pleasure in watching something work — a system, a publication, a network, a kitchen — and knowing that you built it, without needing anyone else to know. My father taught me that pleasure. He lived it for 35 years. He worked with presidents and walked down the street like anyone else.

That's the version of success I understand best. Not visibility. Function.

The Closing

And what's already there is always enough to build something worth building.

My father simplified complexity. My mother invested in therapy I didn't understand at the time. The university gave me vocabulary for instincts I already had. Twenty years of clients gave me constraints I couldn't ignore. And every restriction — economic, technical, physical, temporal — produced work that unlimited freedom never would have.

You never start from a blank canvas. You start from what's already there.

And what's already there is always enough to build something worth building.

If any part of this series connected with the way you work — drop it below. I'd genuinely like to know.

Build Different — How I Think · Complete Series

Post 1 — Embrace the Mistake
Post 2 — Think Inside the Box
Post 3 — If I Have to Do It Twice, I Build a System
Post 4 — If I Can't See It, I Don't Understand It
Post 5 — Everything Wants a Second Life
Post 6 — Designing Around Constraints

This post contains Amazon affiliate links. If you purchase through them, I may earn a small commission at no extra cost to you. Every product listed here is something I personally own and use daily.