Self-Hosting a Server on an Old Laptop

I turned an old HP G62 laptop (i3, 6GB RAM) into a home server running Ubuntu Server 22.04. It hosts my files, blocks ads for my network, and manages my Docker containers. Here’s what I learned.

Why Bother

Cloud storage costs money and someone else holds your data. A home server costs electricity and an old laptop you weren’t using anyway. I wanted to own my files, run my own services, and learn how infrastructure actually works. That last reason turned out to be the most valuable — this project taught me more about networking, security, and Linux administration than any course.

The Setup

Hardware: HP G62 laptop, dual drive (100GB SSD + 278GB HDD), connected to the router via ethernet. No monitor, no keyboard — headless after initial setup. Lid closed, tucked on a shelf.

OS: Ubuntu Server 22.04 LTS. No GUI — everything through SSH. A desktop environment would waste RAM on a machine nobody’s looking at.

Network: Static IP assigned via DHCP reservation on the router. Server on ethernet for stability, my main laptop on WiFi.

INTERNET
   |
ROUTER (WiFi + Ethernet)
   |              \
(Ethernet)      (WiFi)
   |                \
HP Server         Main Laptop
192.168.x.10      (dynamic)

What’s Running

Everything in Docker, managed through Portainer:

  • Nextcloud (MariaDB + Redis) — file storage and sync. My personal Dropbox.
  • Pi-hole — network-wide ad blocking. Every device on my network gets cleaner browsing.
  • Portainer — container management GUI. Easier than raw Docker commands for daily stuff.
  • Uptime Kuma — monitors whether services are actually running.
  • Syncthing — file sync between devices.
  • Nginx — reverse proxy with HTTPS via Let’s Encrypt.

Security Hardening

This is the part most tutorials skip and the part that matters most:

  • SSH key authentication only — password login disabled completely.
  • Custom SSH port (not 22) to reduce noise from automated scanners.
  • Fail2ban watching SSH logs — auto-bans IPs after failed attempts. (A good use case for process tricks if you want to monitor the ban list in real time.)
  • UFW firewall — only the ports I need are open, everything else denied.
  • Docker network isolation — containers can’t talk to each other unless I explicitly allow it.
  • Security headers on Nginx — scored Grade A on security header tests.

Problems I Hit

CGNAT. My ISP uses carrier-grade NAT, which means I don’t have a real public IP. Port forwarding doesn’t work. I tried WireGuard first, then realized why it can’t work with CGNAT. Switched to Tailscale — it punches through NAT automatically using relay servers. Problem solved, and I understood the networking better for having failed first.

CDN blocks. Some package mirrors are blocked from Syria. Workaround: download packages on my main laptop (which has different network access), then SCP them to the server. Not elegant, but it works.

Lid close behavior. Laptops default to sleeping when you close the lid. Had to configure systemd to ignore the lid switch: edit /etc/systemd/logind.conf and set HandleLidSwitch=ignore.

What It Taught Me

This project is where I realized I’m not really a web developer or an ML researcher — I’m someone who thinks in infrastructure and systems. The satisfaction of having a reliable, secure, self-maintained server running 24/7 is different from anything I’ve felt building websites.

See Also