Adam Schussel
Back to projects

Self-Hosted Infrastructure Lab

A production-inspired environment for containerized services, private networking, virtualization, observability, automation, resilient storage, and on-demand GPU compute.

A sanitized view of the environment I design and operate daily. Exact addressing, credentials, internal naming and security-sensitive implementation details are omitted.

Role
Designer and sole operator
State
In daily use, actively evolving
host
Dell PowerEdge T330, headless
os
Arch Linux
cpu
Intel Xeon E3-class
memory
~48 GB
storage
PERC H730 RAID controller, multiple disks
runtime
Docker, Docker Compose
virt
KVM / libvirt
gpu node
RTX 3060 Ti, 8 GB, on demand
Addresses, hostnames, paths, versions and disk layout are left out on purpose.

Architecture

Public and private ingress, segmented service networks, persistent data, observability and on-demand compute.

Sanitized architecture of the infrastructure lab Public clients reach web-facing services through public DNS and a reverse proxy. Trusted devices reach private services, internal DNS and an isolated VM through an encrypted overlay. Inside the infrastructure node, services sit on separate networks above an internal-only data tier, persistent volumes, a redundant array, and off-host backups. An automation layer routes AI inference to a separate GPU compute node that runs only on demand. Public path Private path Infrastructure node Linux, Docker, KVM, always on GPU compute node Workstation, on demand Normally in standby Off-host Public clients Any network Trusted devices Enrolled in overlay Public DNS Dynamic DNS, ACME Reverse proxy Traefik, TLS Internal DNS Pi-hole resolver Encrypted overlay Headscale mesh Monitoring Prometheus, Grafana Public app network Web-facing services Private app network Admin, personal apps Isolated VM KVM, off by default Linux host Arch, Docker, libvirt Data tier Internal only Automation & AI n8n, Open WebUI Redundant array Controller RAID Persistent volumes Survive redeploys Backup copies Versioned, off-host RTX 3060 Ti Ollama, 8 GB VRAM

Swipe sideways to explore the diagram.

  • Operating
  • Public ingress
  • Private overlay

A sanitized model, not a network map. Components are grouped by role; counts, addresses and exact wiring are omitted.

Defense in depth

Security is designed as several independent boundaries rather than one perimeter. Each layer assumes the one outside it might fail. Mark a layer as compromised to see what still stands between a request and the data.

Service data
Linux host Least privilege, updates and monitoring underneath every layer.

Remaining boundaries

Public path 4 of 4
Private path 4 of 4

All layers intact. Select any layer to assume it has failed.

Illustrates the principles I apply. It is not a reproduction of my firewall, proxy or overlay configuration.

Self-hosting principles

I self-host where it gives me meaningful control over privacy, exposure, data and operations.

Privacy by architecture

Personal data and sensitive services remain on systems I administer. Private applications use private access paths instead of being exposed simply because they are convenient to reach.

Ownership and control

I control deployment, updates, storage, service lifecycle and migration. The infrastructure remains understandable and portable instead of depending on one hosted product.

Minimal exposure

Public ingress is deliberate. Administrative interfaces, internal databases and infrastructure tooling do not need the same exposure model as public web services.

Layered isolation

Container networks separate routine application services. Virtual machines provide a stronger boundary when I am testing security tools, untrusted workloads or isolated AI environments.

Recoverability

Application state, redundancy and backups are treated as separate concerns so services can be rebuilt without treating a running container as permanent infrastructure.

Operate with evidence

Metrics, health checks and history make changes measurable. I want to know what changed and when instead of relying on memory or manual inspection.

Containers and VMs, chosen per workload

I use containers as the default application runtime and virtual machines when I want a stronger security or experimentation boundary.

Default runtime

Containers

Long-running services fit naturally into Docker: small isolated processes, repeatable Compose definitions, explicit networks and persistent data kept outside the container lifecycle.

  • Web and application services
  • Databases and supporting services
  • Automation and monitoring
  • Fast rebuilds and predictable deployment
Stronger boundary

Virtual machines

KVM/libvirt gives me a separate kernel and operating environment when isolation matters more than efficiency. That makes VMs useful for security testing and experiments I do not want sharing the normal application environment.

  • Security testing and lab workloads
  • Untrusted or specialized tooling
  • Network-isolated experiments
  • Isolated AI model and runtime testing

Observability

Metrics are collected continuously, kept as history, and visualized, so questions about the system are answered with data instead of by logging in and looking around.

Sources

Linux host, containers

Exporters

Node Exporter for the host, cAdvisor for per-container usage

Prometheus

Scrapes on an interval and stores time series

Grafana

Dashboards and historical trends

Illustrative panel layout. Not live data.

What I watch

  • CPU utilization
  • Memory pressure
  • Filesystem usage
  • Per-container resources
  • Network throughput
  • Service availability
  • Uptime
  • Long-term trends

History is the useful part. When something feels slow, I can check whether memory, disk or a single container changed, and when.

Storage: redundancy is not a backup

RAID keeps services available when a disk fails. It does not protect against deletion, corruption or mistakes, because it faithfully mirrors those too. The storage design treats the two as separate layers.

ApplicationsRecreated freely
Persistent dataVolumes outlive containers
Redundant arrayAvailability
Backup copiesRecovery
Which layer handles which failure
Failure Volumes RAID Backups
Container recreatedCoversn/an/a
One disk failsNoCoversRestore
File deleted by mistakeNoMirrors itCovers
Bad update corrupts dataNoMirrors itCovers
Controller or host lostNoNoIf off-host
RansomwareNoNoIf isolated

Storage and backup details are intentionally summarized here. Disk layout, schedules, destinations and recovery procedures are not published.

On-demand local AI compute

My server stays online for storage, networking, automation and web services. GPU inference is handled by my workstation only when I need it, keeping model traffic local without running a high-power GPU system around the clock.

Always on

Infrastructure server

Orchestration, storage and application interfaces.

Open WebUI Automation Data services
On demand

GPU workstation

Local model inference and GPU-heavy workloads.

RTX 3060 Ti 8 GB VRAM Ollama

Local by default

Prompts and model traffic stay on infrastructure I control.

Specialized compute

The always-on server handles services; the workstation provides GPU acceleration when a workload actually needs it.

Lower idle cost

High-power hardware does not need to remain active just to keep the rest of the self-hosted environment online.

How it got here

It started on a $20 used desktop and grew one problem at a time.

  1. A used small-form-factor desktop

    A 2011 office PC upgraded to 32 GB of RAM and a few terabytes of disk. First Compose stacks, first reverse proxy, first self-hosted password manager.

  2. Remote access and monitoring

    A VPN for administration, then Prometheus and Grafana once guessing about resource usage stopped being good enough.

  3. Server hardware

    Moved to a PowerEdge T330 with a Xeon, more memory and a hardware RAID controller.

  4. Overlay networking and VMs

    A coordinated encrypted overlay for private access, and KVM for workloads that need a harder boundary.

  5. On-demand GPU compute

    Local inference runs on a separate GPU workstation when high-compute workloads need it.

  6. Resilient storage

    Storage redundancy and backup strategy are treated as separate operational layers.