Docker lessons from building a DIY NAS: what actually matters

I spent three weeks turning an old laptop into a network storage device. It seemed straightforward enough—install Linux, configure some storage, maybe throw Docker in for good measure. What I actually got was a masterclass in why Docker matters and why skipping the fundamentals will cost you later.

This wasn’t a polished tutorial project. I hit real walls. I debugged container networking at 11 PM. I accidentally filled the disk with logs and learned why that matters. And through it all, Docker went from feeling like unnecessary overhead to being the only thing keeping my setup sane.

Container isolation saved me from my own mistakes

docker
Photo by Willian Justen de Vasconcellos on Pexels

Here’s what happened: I installed a Plex media server directly on the host first. Then an archive tool. Then a backup utility. Before long, I had seven different services fighting over system resources, stepping on each other’s configuration files, and making the whole system fragile. Adding one more service meant risking the stability of everything else.

Docker changed that completely. Each service got its own isolated environment. Plex couldn’t mess with my backup tool’s settings. A runaway process in one container wouldn’t tank the whole system. I could update one service without touching the others.

The learning curve was real, though. I had to understand that containers aren’t lightweight virtual machines—they share the host kernel. I had to learn about volumes and bind mounts because I kept losing data when containers restarted. But once that clicked, the benefits were undeniable. Isolation isn’t just a nice feature. It’s the difference between a system you can maintain and one that becomes increasingly fragile.

I started documenting my services in docker-compose files. Suddenly I had a clear record of what was running and how it was configured. That documentation became invaluable when things broke.

Networking in Docker requires you to think differently

This is where I hit my biggest wall. I assumed Docker networking would work like regular networking. It doesn’t. Not exactly.

I spent hours trying to figure out why my Plex container couldn’t talk to my database container. They were on the same machine. Why was this hard? Because Docker’s default bridge network doesn’t provide DNS resolution between containers using their service names. I’d been writing IP addresses directly, which broke the moment I rebuilt a container.

The fix was to use a custom Docker network. Simple. But I had to learn that first. I had to understand that containers don’t work like VMs on a virtual network—they work more like processes with network namespaces.

Port mapping added another layer of confusion. I’d forward port 8080 on the host to port 8080 in the container, then wonder why traffic wasn’t getting through. I wasn’t thinking about the container’s perspective. From inside the container, it’s listening on port 8080. From outside, you hit port 8080 on the host IP. These aren’t the same thing.

Understanding Docker networking meant understanding network namespaces and how the host bridges to them. It’s not difficult once it clicks, but it requires shifting how you think about network topology.

Storage and persistence demand respect

Containers are ephemeral by design. That’s a feature. It’s also a gotcha if you don’t plan for it.

I learned this when I restarted a container and lost three days of cached data. The container had been writing to its own filesystem, which got thrown away on restart. I should have seen that coming. I didn’t.

Docker volumes are the answer, but there’s a learning curve here too. Do you want a named volume that Docker manages? A bind mount to a host directory? A tmpfs mount for temporary data? Each has different characteristics and use cases.

Named volumes are cleaner and Docker handles the details. Bind mounts give you more control and let you use the data outside Docker. I ended up using bind mounts for most things—my backup data, my media library, my configuration files. I wanted to be able to access and backup that data directly.

That choice came with a tradeoff: I had to manage file permissions carefully. The process inside the container runs as a specific user, and that user needs permission to read and write files on the host. Getting this wrong means containers can’t access their data, or worse, they create files the host user can’t touch.

I spent time learning about user namespaces and how to map container users to host users properly. It mattered. Getting storage right means your data survives container restarts, host reboots, and rebuilds.

Resource limits prevent one bad container from killing everything

On a laptop running as a NAS, resources are tight. I had limited RAM. The disk wasn’t particularly fast. A single runaway process could grind the whole system to a halt.

Docker lets you set memory limits, CPU limits, and disk I/O limits per container. I didn’t do this at first. Then my Plex server started transcoding video and consumed all available RAM in minutes. The system became completely unresponsive.

Setting limits was the fix. Plex can’t eat more than 2GB of RAM. The backup service gets 512MB. It means some operations run slower, but the system stays usable. That’s a worthwhile tradeoff on constrained hardware.

The lesson here is simple: on shared hardware, isolation has to include resource controls, not just filesystem and network isolation.

What I’d do differently next time

I’d start with docker-compose from day one instead of running containers manually. I’d document networking decisions upfront. I’d plan storage and permissions before writing any configuration. I’d set resource limits from the start, not after a crisis.

Most importantly, I’d stop treating Docker as optional infrastructure and start treating it as the way the system actually works. It’s not an extra layer to add when things get complicated. It’s the foundation that makes things manageable.

That old laptop now runs five different services reliably. It backs up important data. It serves media to devices around the house. It handles regular maintenance without my constant attention. Docker didn’t create magic. It created structure. And structure, once you understand it, makes everything easier.

Source: I built a NAS from an old laptop—here’s what Linux taught me the hard way

Leave a Reply

Your email address will not be published. Required fields are marked *

WordPress Appliance - Powered by TurnKey Linux