Self-Hosting Everything on a Gaming Laptop
How I run 40+ services on a Lenovo laptop with Proxmox — from media automation and document management to a full smart home. A tour of my self-hosted infrastructure.
I pay for nothing. No Google Drive, no LastPass, no Todoist, no streaming service middleman. Every piece of software that manages my life runs on a laptop sitting on a shelf in my apartment. A gaming laptop, specifically — one that was too loud for gaming and too powerful to just sit there.
This is the story of how a $900 Lenovo LOQ became the backbone of my digital life, running 2 virtual machines, 6 LXC containers, and 36 Docker services. From media automation and document management to smart home control and AI-powered morning briefings.
Why Self-Host?
The pitch for self-hosting usually comes in three flavors: privacy, learning, and cost. For me, it was all three, but they hit in that order.
Privacy came first. I’m a developer — I know what happens to data once you hand it to a company. Terms of service change. Acquisitions happen. “We value your privacy” is a sentence that precedes every single privacy violation. I wanted my passwords, my documents, my bookmarks, and my budget to live on hardware I control.
Learning came next. I’d been working with containers and infrastructure professionally, but there’s a difference between deploying someone else’s architecture and building your own from scratch. Self-hosting forces you to understand networking, DNS, reverse proxies, authentication flows, storage, and monitoring — not in theory, but in practice, at 2 AM when your SSL cert expired and nothing loads.
Cost sealed it. I tallied up my subscriptions one day: cloud storage, password manager, media services, note-taking apps, budgeting tools. It wasn’t catastrophic, but it was $50-70/month for services I could run myself. The laptop paid for itself in under a year.
Where It Started
My first “server” was a Raspberry Pi 3 — the $35 credit card-sized computer that launched a thousand homelabs. I installed Plex, Jackett, and Transmission on it, set up Samba for network shares, and convinced myself I had a media server. I also used it to play retro games through RetroArch — SNES, GBA, PS1 — and to watch movies on my TV. Or at least, I tried.
The Pi 3 has a quad-core ARM CPU clocked at 1.2 GHz and 1 GB of RAM. Plex transcoding was a slideshow. Jackett searches took forever. Transmission would choke if more than two torrents ran simultaneously. RetroArch was actually the thing it handled best — emulating a 1994 console on 2016 hardware was well within its means, but anything beyond PS1 was pushing it.
Still, that tiny board taught me more about Linux, networking, and self-hosting than any tutorial ever could. I learned to SSH into a headless machine, configure Samba shares, set up port forwarding, troubleshoot file permissions, and accept that 1 GB of RAM is not enough for anything. When I eventually outgrew it, I didn’t stop self-hosting — I just needed more power.
The Machine
Most homelabbers run a Dell OptiPlex, an old enterprise server, or a purpose-built NAS. I run a Lenovo LOQ 15IRH8 — a gaming laptop. Here’s why that’s not as crazy as it sounds.
| Spec | Details |
|---|---|
| CPU | Intel i7-13620H — 10 cores, 16 threads, up to 4.9 GHz |
| RAM | 16 GB DDR5 |
| Storage | 1 TB NVMe SSD (LVM thin provisioning) |
| Network | Built-in Gigabit Ethernet + Wi-Fi 7 (unused) |
| Power | ~35W idle with screen off |
A laptop as a server has a few underrated advantages:
- Built-in UPS. The battery keeps everything running during power outages. No external UPS needed. When the power goes out at 3 AM, my Home Assistant automations don’t miss a beat.
- Built-in display. When something goes wrong at the hypervisor level, I don’t need to hunt for a monitor and cable. I open the lid.
- Silent when idle. With the screen off and no GPU load, the fans rarely spin up. It’s quieter than a NAS.
- Compact. It sits on a shelf. No rack, no dedicated space needed.
The tradeoffs are real — limited RAM expandability, single NVMe slot, laptop thermals under sustained load. But for my workload, 16 GB and 1 TB have been enough for two years.
Architecture Overview
The entire stack runs on Proxmox VE, a Debian-based hypervisor that manages virtual machines and LXC containers. Proxmox uses LVM thin provisioning on the 1 TB NVMe, which means I can over-provision storage and only consume actual disk space as data is written.
The Virtualization Strategy
I use three tiers of isolation, each chosen for a reason:
Virtual Machines — for workloads that need their own kernel or OS. Unraid needs to manage its own storage stack. Home Assistant OS ships as a complete appliance image with its own supervisor, add-on system, and update mechanism — it’s designed to run as a VM.
LXC Containers — for services that benefit from near-native performance without full VM overhead. Jellyfin gets its own LXC because media transcoding is CPU-intensive and I don’t want it competing for resources with 30 other containers. AdGuard Home runs in an LXC because DNS needs to be rock-solid and isolated. n8n gets its own container because workflow automation can occasionally eat surprising amounts of memory.
Docker Containers — for everything else. The bulk of my services run as Docker containers inside a single LXC (ID 101), managed through Portainer. Docker is perfect for stateless or semi-stateless services where the overhead of a full LXC isn’t justified.
Storage Layout
The 1 TB NVMe is partitioned with LVM:
| Partition | Size | Purpose |
|---|---|---|
| EFI | 1 GB | Boot partition |
| pve-root | 96 GB | Proxmox OS |
| pve-swap | 8 GB | Swap space |
| pve-data | 816 GB | Thin pool for VMs, LXCs, and containers |
Each VM and LXC gets a thin-provisioned disk from the pool. Unraid’s VM has no pre-allocated disk because it manages its own virtual drives. The Docker LXC (101) gets 52 GB for all container data and volumes.
With 16 GB of RAM shared across 2 VMs, 6 LXCs, and 36 Docker containers, memory management matters. Home Assistant OS gets 4 GB, Unraid gets 2 GB, and the rest share what’s left. Swap usage hovers around 7 GB during peak load — not ideal, but stable. The next upgrade will be more RAM, not more storage.
Network & Access
The Router
Everything connects through a TP-Link Archer BE800 — a Wi-Fi 7 tri-band router. It’s overkill for a homelab, but it’s what I use for daily life too. The Proxmox server connects via Ethernet, and IoT devices (smart home sensors, cameras) connect to a dedicated IoT Wi-Fi network.
DNS & Ad Blocking
AdGuard Home (LXC 200) serves as the network-wide DNS server. Every device on the network resolves DNS through it, which means:
- Ads and trackers are blocked at the DNS level — no browser extensions needed
- I get visibility into what every device on the network is querying
- Local DNS entries point
service.localhostnames to internal IPs
Reverse Proxy & Domains
Nginx Proxy Manager handles all reverse proxying. I own a domain through Cloudflare, and each service gets its own subdomain. NPM terminates SSL with Let’s Encrypt certificates and routes traffic to the correct container.
The flow looks like this:
User → volc.men → Cloudflare DNS → My IP (DDNS) → Router → NPM → Service
Cloudflare DDNS runs as a Docker container that monitors my public IP and updates the DNS records whenever it changes. No static IP needed.
Some services are public-facing (accessible from anywhere via domain), while others are local-only (accessible only on the home network or via Twingate).
Remote Access
Twingate provides zero-trust remote access to services I don’t want exposed to the public internet. Instead of opening ports or running a VPN server, Twingate creates encrypted tunnels from my devices to specific services. I can access my Proxmox dashboard, Portainer, or DBGate from anywhere without exposing them.
The Services
Storage: Unraid (VM 100)
Unraid runs as a VM and acts as the central NAS. It serves SMB and NFS shares to other VMs and containers — media libraries for Jellyfin, document storage for Paperless, general file storage for everything else. With only a virtual disk inside Proxmox for now, the plan is to eventually pass through physical drives when I expand storage.
Media Stack
The media stack is the most interconnected part of the setup. Here’s how the pieces fit together:
| Service | Role |
|---|---|
| Jellyfin (LXC 102) | Media server — streams movies, shows, music to any device |
| Sonarr | TV show automation — monitors, downloads, organizes series |
| Radarr | Movie automation — same as Sonarr but for films |
| Prowlarr | Indexer manager — centralizes search across sources |
| Jackett | Indexer proxy — additional source support |
| Seerr | Request system — lets household members request media |
| Deluge | Torrent client — handles downloads |
| Recyclarr | Quality profiles — syncs TRaSH Guides quality settings to Sonarr/Radarr |
| Audiobookshelf | Audiobook and podcast server with progress tracking |
| LavaMusic + Lavalink | Discord music bot for playing music in voice channels |
The flow: someone requests a movie through Seerr → Radarr picks it up → Prowlarr/Jackett search for it → Deluge downloads it → Radarr renames and organizes it → Jellyfin detects and serves it. Fully automated.
Recyclarr deserves special mention — it automatically applies community-maintained quality profiles from TRaSH Guides, ensuring optimal file quality and naming conventions without manual configuration.
Document Management: Paperless-NGX
Paperless-NGX is one of the most life-changing services in the stack. Every document — bills, receipts, contracts, medical records — gets scanned or uploaded, OCR’d, tagged, and made searchable.
The document pipeline:
| Service | Role |
|---|---|
| Paperless-NGX | Core document management — ingest, OCR, tag, archive |
| Paperless-AI | AI-powered automatic tagging and categorization |
| Apache Tika | Content extraction from complex file formats |
| Gotenberg | PDF generation and conversion |
| MeiliSearch | Fast full-text search across all documents |
I drop a PDF into the consumption folder (or email it to a dedicated address), and minutes later it’s OCR’d, auto-tagged by the AI, and searchable. Two years of paperwork, fully digitized and instantly findable.
Productivity
| Service | What It Does |
|---|---|
| Linkwarden | Bookmark manager with full-page archiving — never lose a link to link rot |
| Vikunja | Task and project management — Todoist replacement |
| n8n (LXC 106) | Workflow automation — connects services, triggers actions, processes data |
| Changedetection.io | Monitors websites for changes — price drops, content updates, availability |
| Homepage | Dashboard that shows all services at a glance with live status and stats |
Changedetection runs with Selenium and SockPuppetBrowser as headless browser backends, so it can monitor JavaScript-rendered pages that simple HTTP requests would miss.
Finance & Home
| Service | What It Does |
|---|---|
| Actual Budget | Envelope-style budgeting — tracks spending, sets goals, imports transactions |
| Wallos | Subscription tracker — monitors recurring costs and alerts before renewals |
| Grocy | Household management — grocery lists, pantry inventory, chore tracking |
Security & Authentication
Authentik is the SSO (Single Sign-On) identity provider. Instead of managing separate accounts for every service, I sign in once through Authentik, and it handles authentication for Paperless, Linkwarden, Vikunja, Beszel, and others via OAuth2/OIDC.
Vaultwarden is a self-hosted Bitwarden-compatible password manager. Every password, TOTP code, and secure note lives here. It syncs across all my devices through the standard Bitwarden clients.
Monitoring & Maintenance
| Service | Role |
|---|---|
| Beszel | Lightweight server monitoring — CPU, RAM, disk, network graphs |
| Watchtower | Automatic container updates — pulls new images and recreates containers |
| Portainer CE | Docker management UI — deploy, monitor, and manage all containers |
| DBGate | Database management GUI — inspect and query PostgreSQL directly |
Supporting Services
Behind the scenes, several services keep everything running:
- PostgreSQL — primary database for Authentik, Linkwarden, Paperless, and others
- Redis — caching and session storage for Authentik and other services
- MeiliSearch — full-text search engine (currently used by Paperless)
- Gotenberg — document-to-PDF conversion for Paperless
- Apache Tika — content extraction from Word docs, emails, and other formats
- Selenium + SockPuppetBrowser — headless browsers for Changedetection
Smart Home: Home Assistant
Home Assistant OS runs as a dedicated VM (103) with 4 GB of RAM. It’s the brain of the apartment — controlling lights, climate, curtains, cameras, and appliances through a mix of Zigbee devices (via Zigbee2MQTT), Wi-Fi smart home products, and IR blasters.
It runs 42+ automations covering motion-activated adaptive lighting, AI-powered morning briefings via Telegram, automated climate control, smart curtain scheduling, vacuum coordination, and security camera alerts. The whole thing is tied together with a custom dashboard using the Frosted Glass theme, Mushroom chips, and Bubble Card.
I wrote a dedicated deep-dive on the Home Assistant setup — the Zigbee network, every automation, the dashboard, and the troubleshooting I did along the way. Read the full Home Assistant article here.
Troubleshooting & Fixes
Self-hosting isn’t all smooth sailing. Here are some real issues I hit and how I fixed them.
Authentik + Linkwarden: The Missing Email
After setting up Authentik as the SSO provider for Linkwarden, I discovered that Linkwarden requires an email address on the user record — but OAuth login through Authentik created users without one. Linkwarden silently broke on certain operations.
The fix was surgical: connect directly to the database and update the user record.
psql -U postgres
# Connect to the Linkwarden database
\c linkwarden
# Check the current state
SELECT * FROM "User";
# Set the missing email
UPDATE "User"
SET email = 'your@email.com'
WHERE id = '1';
-- Or by username:
UPDATE "User"
SET email = 'your@email.com'
WHERE username = 'yourusername';
Not elegant, but effective. This is a one-time fix — subsequent logins preserve the email.
Beszel + Authentik: Email Verification Scope
Beszel requires the email scope to either return email_verified: true or omit the field entirely. As of Authentik 2025.10, the default behavior returns email_verified: false, which causes Beszel to reject the authentication.
The fix: create a custom scope mapping in Authentik.
- Open Authentik Admin → Customization → Property Mappings → Create
- Select type: Scope Mapping
- Set scope name to
email - Set the expression to:
return {
"email": user.email,
"email_verified": True,
}
- Assign this custom mapping to the Beszel OAuth provider, replacing the default email scope.
This tells Beszel that the email is verified (it is — Authentik manages our users), and authentication works.
When integrating services with Authentik, always check what the service expects from OIDC scopes. Many apps have opinionated requirements about email verification, username format, or group membership. Authentik’s custom property mappings are the escape hatch — you can make the token return whatever the consuming service needs.
What I’ve Learned
Two years of self-hosting on a laptop has taught me a few things:
Start with the problem, not the solution. It’s tempting to deploy every shiny self-hosted app you see on r/selfhosted. But the services that actually stick are the ones that solve a real problem you have today. Paperless-NGX solved my drowning-in-documents problem. Actual Budget solved my where-did-my-money-go problem. Half the services I tried and removed were solutions looking for a problem.
LXC containers are underrated. Most homelab guides default to either full VMs or Docker for everything. LXCs hit a sweet spot — near-native performance with proper isolation, and they’re lighter than VMs. For services like Jellyfin (CPU-intensive transcoding) or AdGuard Home (needs to be bulletproof), the overhead of a full VM isn’t justified but the isolation from other containers is.
Monitoring matters more than you think. Beszel and the energy monitoring in Home Assistant have caught issues I would have missed — a container silently eating RAM, the water heater running for 3+ hours, a DNS query spike from a misbehaving device. You can’t fix what you can’t see.
Document everything as you go. Future you will not remember why you set that custom scope mapping in Authentik or which port Paperless uses. I learned this the hard way after rebuilding a container and spending hours re-discovering my own configuration.
16 GB of RAM is enough. Barely. With 7 GB of swap in use during peak load, I’m clearly pushing the limits. Everything works, but there’s no headroom for experimentation. The laptop supports 32 GB — that’s the most impactful upgrade I could make.
This setup has been running 24/7 for over two years on a laptop that cost less than most people’s annual subscription bills. It handles my media, my documents, my passwords, my budget, my smart home, and my morning news. Every byte of data lives on my shelf, in my apartment, under my control.
Is it more work than paying for cloud services? Absolutely. Is it worth it? Every single time I don’t see an ad, don’t get a “we’ve updated our privacy policy” email, or don’t wonder where my data ended up — yes.