How to Build a Home Server: VPN, Proxy, and Services on Your Own Network

21 min read
Intermediate Home Server Self-Hosting VPN Proxy Raspberry Pi Networking Guide

Prerequisites

  • A Raspberry Pi, mini PC, or old computer
  • A home internet connection with a router you can configure
  • Basic comfort with the Linux command line

Quick Answer: Get a Raspberry Pi or mini PC, install Ubuntu Server, set a static IP, forward ports on your router, install WireGuard VPN with SamNet-WG, and optionally run MTProxyMax for Telegram proxy. Total cost: $35-150 one-time + your existing internet.


Why Host at Home?

A VPS costs $3-10/month. A home server costs electricity (~$5-15/year for a Pi). But the real reasons go beyond cost:

Home Server VPS
Monthly cost ~$1 electricity $3-10/month
Storage Unlimited (add drives) 25-100 GB
Speed (local) Gigabit+ Limited by internet
Privacy Your hardware, your data Provider has physical access
Bandwidth Your ISP plan 1-5 TB/month
IP reputation Clean residential IP Often flagged/blocked
Uptime Depends on your power/internet 99.9%+
Best for VPN, media, storage, local services Public websites, high availability

A residential IP is gold for VPN and proxy. VPS IPs are often flagged by services like Netflix, banks, and captive portals. Your home IP looks like a normal person's connection.


Part 1: Choose Your Hardware

Option A: Raspberry Pi (Best Budget Option)

Model RAM Power Draw Cost Good For
Pi 4B 4/8 GB ~5W $55-75 VPN, proxy, Pi-hole, light Docker
Pi 5 4/8 GB ~8W $60-80 Everything, faster
Pi Zero 2 W 512 MB ~1W $15 Pi-hole only, ultra low power

Get: Pi 4B 4GB ($55) + 32GB microSD ($8) + USB-C power supply ($10) + case ($10) = ~$83 total

For better reliability, boot from a USB SSD instead of microSD:

  • 120GB SATA SSD ($15) + USB-to-SATA adapter ($8)
  • SD cards die under constant writes; SSDs don't

Option B: Mini PC (Best Performance)

Used or refurbished mini PCs give you x86 compatibility, more RAM, and NVMe storage:

Device RAM Storage Power Cost
Lenovo ThinkCentre M720q 8-16 GB 256 GB SSD ~15W $80-120 used
HP ProDesk 400 G5 8-16 GB 256 GB SSD ~15W $70-110 used
Dell OptiPlex Micro 8-16 GB 256 GB SSD ~15W $80-130 used
Intel NUC 8-32 GB NVMe ~15W $100-200 used
Beelink Mini S12 8-16 GB 256 GB SSD ~10W $120-160 new

Get: Any used mini PC with 8GB RAM and an SSD for $80-120. More than enough for 5-10 Docker services.

Option C: Old Laptop or Desktop

Any computer from the last 10 years works. A 2015 laptop with 4GB RAM can run everything in this guide. Just install Linux on it.

Advantages: Free (you already have it), built-in battery backup (laptop), more storage. Disadvantages: Higher power draw (50-100W), noisy fan, takes up more space.


Part 2: Install Linux

Raspberry Pi

  1. Download Raspberry Pi Imager
  2. Select Raspberry Pi OS Lite (64-bit) — no desktop needed for a server
  3. Click Edit Settings:
  • Set hostname: homeserver
  • Enable SSH
  • Set username/password
  • Configure Wi-Fi (or use Ethernet — recommended for servers)
  1. Flash to microSD/USB, insert, power on
  2. SSH in:
ssh [email protected]
# or find the IP from your router's DHCP client list
ssh [email protected]

Mini PC / Old Computer

  1. Download Ubuntu Server 24.04 LTS
  2. Flash to USB with Etcher or Rufus
  3. Boot from USB (press F12/F2/Del for boot menu)
  4. Follow installer — choose "Ubuntu Server (minimized)" for the lightest install
  5. Enable OpenSSH during installation
  6. After reboot, SSH in from your main computer:
ssh [email protected]

Part 3: Initial Server Setup

Update System

sudo apt update && sudo apt upgrade -y

Set a Static IP

Your server needs the same IP every time. If it changes, port forwarding breaks.

Raspberry Pi OS (Bookworm+):

sudo nmcli con show    # Find your connection name
sudo nmcli con mod "Wired connection 1" ipv4.addresses 192.168.1.100/24
sudo nmcli con mod "Wired connection 1" ipv4.gateway 192.168.1.1
sudo nmcli con mod "Wired connection 1" ipv4.dns "1.1.1.1 8.8.8.8"
sudo nmcli con mod "Wired connection 1" ipv4.method manual
sudo nmcli con up "Wired connection 1"

Ubuntu Server:

sudo nano /etc/netplan/00-installer-config.yaml
network:
  version: 2
  ethernets:
    eth0:                        # Your interface name (check: ip addr)
      dhcp4: false
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1       # Your router IP
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8
sudo netplan apply

Full guide: How to Set Up a Static IP

Set Up SSH Keys

# On your PC/Mac (not the server):
ssh-keygen -t ed25519
ssh-copy-id [email protected]

# Now disable password login on the server:
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart ssh

Full guide: SSH Keys Setup

Enable Firewall

sudo apt install ufw -y
sudo ufw allow ssh
sudo ufw enable

Open additional ports as needed (we'll do this in later sections).

Full guide: UFW Cheat Sheet

Install Docker

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in

Full guide: Docker Cheat Sheet

Install Fail2ban

sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban

Part 4: Understand Your Home Network

Before you can make your server accessible from outside, you need to understand how your home network works. This is the most important section — if you don't get this, port forwarding won't make sense.

How Your Network is Structured

Internet → ISP → Your Modem → Your Router → Your Devices
                                    ↓
                              ┌─────────────┐
                              │ 192.168.1.1 │  Router (gateway)
                              └─────┬───────┘
                    ┌───────────────┼───────────────┐
                    │               │               │
              192.168.1.50    192.168.1.100    192.168.1.150
              Your phone      Home server      Your laptop

Key Concepts

Private IP (e.g., 192.168.1.100) — This is your server's address inside your home network. Think of it like an apartment number inside a building. Devices inside your network use this to talk to each other. Anyone outside your network can't see or reach these addresses — they're completely invisible to the internet.

Public IP (e.g., 203.0.113.50) — This is the address your ISP gives your entire home. Every device in your house shares this one address. When you visit a website, the website sees your public IP. Think of it as your building's street address — every apartment shares it.

NAT (Network Address Translation) — Your router is the translator. When your phone requests a website, the router replaces your phone's private IP (192.168.1.50) with the public IP (203.0.113.50), sends the request out, remembers which device asked, and sends the response back to the right device. This is why 50 devices can share one public IP.

The problem: NAT works great for outgoing requests (you asking for a website). But what about incoming requests? If someone on the internet tries to connect to your public IP on port 51820, your router doesn't know which device to send it to. It just drops the connection. That's where port forwarding comes in.

Port forwarding — You tell the router: "Any incoming traffic on port 51820 → always send it to 192.168.1.100 (my server)." Now outside traffic has a path to your server.

Find Your Public IP

curl ifconfig.me

Or use: What's My IP

Check if Your ISP Allows Incoming Connections (CGNAT)

Some ISPs use something called CGNAT (Carrier-Grade NAT). This means there's another layer of NAT between your router and the internet — your "public" IP is actually shared with hundreds of other customers. Port forwarding won't work because you don't control that outer NAT layer.

How to check if you're behind CGNAT:

# Check your router's WAN IP (in your router's admin page)
# Then check your actual public IP:
curl ifconfig.me

# If they're DIFFERENT, you're behind CGNAT
# If they're the SAME, you have a real public IP — port forwarding will work

Also: if your router's WAN IP starts with 100.64.x.x to 100.127.x.x, that's the CGNAT range — you're definitely behind it.

If you're behind CGNAT, you have options:

  • Call your ISP and ask for a dedicated/public IP (many ISPs offer this for free or $5/month — just ask)
  • Use a VPS as a relay (Cloudflare Tunnel or SSH reverse tunnel — see Part 11)
  • Use Tailscale (works through NAT without any port forwarding — see Part 11)

Part 5: Port Forwarding

Port forwarding is the bridge between the outside world and your home server. Without it, your server is invisible to the internet.

How Port Forwarding Works

Think of ports like doors on your server. Port 80 is the door for web traffic, port 22 is for SSH, port 51820 is for WireGuard VPN. Your server has 65,535 ports, but only a few are open and listening.

Someone outside → Your Public IP:51820 → Router → 192.168.1.100:51820 (your server)

Without port forwarding, someone trying to reach your public IP on port 51820 hits your router, and the router says "I don't know where to send this" and drops it. Port forwarding creates a permanent rule: "port 51820 always goes to 192.168.1.100."

Set Up Port Forwarding

  1. Log into your router — usually 192.168.1.1 or 192.168.0.1 in a browser
  2. Find Port Forwarding (sometimes under "NAT", "Virtual Server", or "Applications")
  3. Add a rule:
Setting Value
Service name WireGuard (or whatever)
External port 51820
Internal IP 192.168.1.100 (your server)
Internal port 51820
Protocol UDP (for WireGuard)
  1. Save

Common Ports to Forward

Service Port Protocol
WireGuard VPN 51820 UDP
MTProto Proxy 443 TCP
SSH (optional, risky) 2222 (not 22!) TCP
Web server 80, 443 TCP
Plex/Jellyfin 32400 / 8096 TCP

Verify Port is Open

After forwarding, verify from outside your network:

  • Use Port Scanner — enter your public IP and port
  • Or from a phone on cellular (not Wi-Fi): nc -zv YOUR_PUBLIC_IP 51820

Security Warning

Never forward port 22 (SSH) directly. Use a non-standard port (e.g., 2222) and key-only authentication, or access SSH through your VPN only. Exposing SSH on port 22 gets brute-forced within minutes.


Part 6: WireGuard VPN (Access Your Home from Anywhere)

What is a VPN and Why Run Your Own?

A VPN (Virtual Private Network) creates an encrypted tunnel between your device and a server. All your internet traffic flows through that tunnel, so anyone watching (your ISP, the coffee shop Wi-Fi, a government firewall) only sees encrypted gibberish going to one IP address.

Commercial VPNs (NordVPN, ExpressVPN, etc.) route your traffic through their servers — you're trusting them with your data. By running your own VPN at home, you trust nobody. Your traffic goes through your own server, exits through your own ISP, and uses your own residential IP.

Use cases:

  • Access your home network remotely (files, services, cameras)
  • Encrypt your traffic on public Wi-Fi
  • Appear to be at home when you're traveling (streaming, banking)
  • Bypass censorship using your home country's internet

WireGuard is the fastest and simplest VPN protocol. It's built into the Linux kernel, uses modern cryptography, and connects in under a second.

Install with SamNet-WG

SamNet-WG (wg-orchestrator) gives you a complete WireGuard management interface:

curl -sSL https://raw.githubusercontent.com/SamNet-dev/wg-orchestrator/main/install.sh | sudo bash

Configure

sudo samnet

The TUI opens. Select:

  1. Server Setup — it auto-detects your network
  2. Set endpoint — your public IP or dynamic DNS hostname (see Part 8)
  3. Set port — 51820 (make sure this is forwarded on your router)

Add Clients (Peers)

sudo samnet → Peers → Add Peer
  • Name it (e.g., "my-phone", "laptop")
  • A QR code appears — scan it with the WireGuard app on your phone
  • For laptops: export the config file

What SamNet-WG Gives You

  • TUI management — visual interface for everything
  • QR codes — instant mobile setup
  • Per-peer bandwidth tracking — see who's using how much
  • Web dashboard — optional browser-based management
  • Auto-configuration — handles keys, routing, and firewall

Open Firewall

sudo ufw allow 51820/udp

Test

  1. Disconnect your phone from Wi-Fi (use cellular)
  2. Connect to WireGuard
  3. Visit What's My IP — should show your home IP
  4. Try accessing your server's local IP (192.168.1.100)

You now have your own VPN. No monthly fees, no logs, no third-party trust.

Full guide: WireGuard Setup


Part 7: MTProto Proxy (Telegram Proxy for Others)

What is MTProto and Why Host It at Home?

MTProto is Telegram's custom protocol for communicating between the app and Telegram's servers. When a government blocks Telegram (like in Iran, China, or Russia), they block connections to Telegram's servers. An MTProto proxy acts as a middleman — your Telegram app connects to the proxy, and the proxy connects to Telegram. The government sees traffic going to your proxy (which looks like normal HTTPS), not to Telegram.

Why host at home instead of a VPS? VPS IPs are often in data center IP ranges that censors monitor and block. Your home IP is a regular residential connection — it's far less likely to be flagged. Plus, anyone using your proxy benefits from a clean IP that isn't shared with thousands of other proxy users.

Install MTProxyMax

MTProxyMax is a full-featured Telegram proxy manager:

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SamNet-dev/MTProxyMax/main/install.sh)"

What MTProxyMax Gives You

  • FakeTLS V2 — traffic looks like normal HTTPS (undetectable)
  • Multi-user — per-user bandwidth limits and expiry dates
  • Telegram bot — manage everything remotely with 17 commands
  • Proxy chaining — route through additional servers for extra privacy
  • Replication — sync to backup servers

Add Users and Get Links

mtproxymax secret add alice
mtproxymax secret add bob
mtproxymax secret link alice    # Get the proxy link

Share the link — users tap it in Telegram and connect instantly. No app install needed.

Port Forwarding

MTProxyMax with FakeTLS uses port 443 (looks like HTTPS):

  1. Forward port 443 TCP on your router to 192.168.1.100
  2. Open firewall: sudo ufw allow 443/tcp

Security

  • FakeTLS makes the traffic look like regular HTTPS — ISPs and censors can't tell it's a proxy
  • Your home IP serves the proxy — residential IPs are rarely blocked
  • Set bandwidth limits per user to prevent abuse: mtproxymax secret limit alice 50gb
  • Set expiry dates: mtproxymax secret expire alice 30d

Full guide: MTProto Proxy Setup


Part 8: Dynamic DNS (Your IP Changes? No Problem)

The Dynamic IP Problem

When you set up WireGuard, you tell your phone "connect to 203.0.113.50" (your home public IP). But most home ISPs give you a dynamic IP — it changes every few days or weeks, or whenever your modem reboots. One day your IP is 203.0.113.50, the next it's 198.51.100.50. Your VPN config still points to the old IP and stops working.

Dynamic DNS (DDNS) solves this. Instead of pointing your VPN to an IP, you point it to a hostname like home.yourdomain.com. A script on your server checks your IP every 5 minutes and updates the DNS record if it changed. Your VPN always connects to the hostname, which always resolves to your current IP.

Option A: Cloudflare DDNS (Free, Recommended)

If you have a domain on Cloudflare:

# Create a script that updates Cloudflare DNS with your current IP:
cat > /opt/cloudflare-ddns.sh << 'EOF'
#!/bin/bash
ZONE_ID="your-zone-id"
RECORD_ID="your-record-id"
API_TOKEN="your-api-token"
DOMAIN="home.yourdomain.com"

IP=$(curl -s https://api.ipify.org)
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120}"
EOF
chmod +x /opt/cloudflare-ddns.sh

# Run every 5 minutes
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/cloudflare-ddns.sh > /dev/null 2>&1") | crontab -

Now use home.yourdomain.com as your WireGuard endpoint instead of a raw IP.

Option B: Free DDNS Providers

Provider Free Tier Setup
DuckDNS 5 subdomains Simple, open-source
No-IP 3 hostnames (renew monthly) Popular, many router integrations
Dynu 4 hostnames Good free tier

Most routers have built-in DDNS support — check your router's settings for DuckDNS or No-IP.


Part 9: More Services to Run

With Docker installed, adding services takes about 2 minutes each. Docker runs each service in its own isolated container — they can't interfere with each other or with your server's operating system. You define what you want in a compose.yml file, run docker compose up -d, and it downloads and starts everything automatically.

Pi-hole (Network-Wide Ad Blocking)

Pi-hole acts as a DNS server for your entire network. When any device (phone, laptop, smart TV, IoT gadgets) tries to load an ad, Pi-hole intercepts the DNS request and blocks it. No browser extensions needed — it works at the network level for every device automatically. Typically blocks 30-50% of all DNS queries (that's how much of your traffic is ads and tracking).

# compose.yml
services:
  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    restart: unless-stopped
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
    environment:
      TZ: 'America/Chicago'
      WEBPASSWORD: 'your-password'
    volumes:
      - pihole-data:/etc/pihole
      - dnsmasq-data:/etc/dnsmasq.d
volumes:
  pihole-data:
  dnsmasq-data:
docker compose up -d

Set your router's DNS to 192.168.1.100. Every device on your network now blocks ads.

Guide: Pi-hole Setup

Nextcloud (Your Own Cloud Storage)

Nextcloud is a self-hosted replacement for Google Drive, Dropbox, and iCloud. You get file syncing across all your devices, file sharing with links, calendar, contacts, and even collaborative document editing. The difference: your files live on your hardware, not on Google's servers. With a home server, your storage is only limited by your hard drive size.

services:
  nextcloud:
    image: nextcloud
    restart: unless-stopped
    ports:
      - "8081:80"
    volumes:
      - nextcloud-data:/var/www/html
volumes:
  nextcloud-data:

Access at http://192.168.1.100:8081. From outside your network, access through your VPN.

Jellyfin (Media Server)

Jellyfin is like having your own Netflix. Point it at a folder of movies, TV shows, or music, and it organizes everything with metadata, artwork, subtitles, and streaming to any device — your TV, phone, tablet, or browser. Unlike Plex, Jellyfin is completely free with no premium tier or account required.

services:
  jellyfin:
    image: jellyfin/jellyfin
    restart: unless-stopped
    ports:
      - "8096:8096"
    volumes:
      - jellyfin-config:/config
      - /path/to/your/media:/media    # Replace with your actual media folder
volumes:
  jellyfin-config:

Access at http://192.168.1.100:8096. Apps available for Android, iOS, Android TV, Fire TV, Roku, and more.

Uptime Kuma (Monitoring)

Once you're running multiple services, you need to know when something breaks — ideally before you notice. Uptime Kuma is a beautiful monitoring dashboard that pings your services every 30-60 seconds and alerts you instantly via Telegram, Discord, email, or Slack when something goes down. It also tracks response times and uptime percentages over time.

services:
  uptime-kuma:
    image: louislam/uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - uptime-data:/app/data
volumes:
  uptime-data:

Access at http://192.168.1.100:3001. Add monitors for each service (HTTP, TCP, ping, DNS, Docker container).

Vaultwarden (Password Manager)

Vaultwarden is a self-hosted implementation of Bitwarden — the popular password manager. Instead of trusting Bitwarden's cloud servers with your passwords, you host them yourself. It works with all official Bitwarden apps and browser extensions. Your passwords are encrypted and stored on your server, synced across all your devices.

services:
  vaultwarden:
    image: vaultwarden/server
    restart: unless-stopped
    ports:
      - "8082:80"
    volumes:
      - vw-data:/data
    environment:
      SIGNUPS_ALLOWED: "false"    # Disable after creating your account
volumes:
  vw-data:

Access at http://192.168.1.100:8082. Create your account, then set SIGNUPS_ALLOWED to false so nobody else can register.


Part 10: Security Hardening

Your home server has open ports facing the internet. Within minutes of exposing a port, automated bots will find it and start probing for vulnerabilities. This isn't personal — it happens to every IP address on the internet. Here's how to make sure they get nothing.

Basic Checklist

# 1. SSH key-only (done in Part 3)
# 2. Firewall enabled (done in Part 3)
# 3. Fail2ban running (done in Part 3)

# 4. Automatic security updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades

# 5. Disable unused services
sudo systemctl disable --now bluetooth    # If not needed
sudo systemctl disable --now avahi-daemon # If not needed

Use Fortify (One-Click Hardening)

Fortify auto-detects your services and hardens everything:

bash <(curl -sL https://github.com/SamNet-dev/fortify/raw/main/install.sh)
fortify

It scores your security posture (0-100) and lets you harden each service:

  • SSH hardening (key-only, port change, cipher hardening)
  • Firewall rules (IPv4 + IPv6, SYN flood protection)
  • Anti-abuse (SMTP blocking, rate limiting)
  • WireGuard audit (preshared keys, permissions)

Guide: Fortify Server Hardening

Router Security

  • Change default router password
  • Disable WPS
  • Disable UPnP (it can auto-open ports without your knowledge)
  • Update router firmware
  • Only forward ports you actually need

Part 11: Remote Access Without Port Forwarding

If your ISP uses CGNAT or you can't port forward, don't give up. These methods let you access your home server from anywhere without opening a single port on your router.

Tailscale (Easiest — Recommended)

Tailscale is a mesh VPN service that uses WireGuard under the hood but handles all the hard parts (NAT traversal, key exchange, discovery) for you. Install it on your server and your devices, and they can reach each other directly — even through CGNAT, firewalls, and double NAT. No port forwarding, no configuration.

# On your home server:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Install Tailscale on your phone/laptop too. Each device gets a 100.x.x.x IP address. You can reach your server at its Tailscale IP from anywhere in the world.

Free tier: Up to 100 devices, 3 users. More than enough for personal use.

Cloudflare Tunnel (For Web Services)

Cloudflare Tunnel creates an outbound-only connection from your server to Cloudflare's network. Traffic flows: User → Cloudflare → Tunnel → Your server. Since the connection is outbound from your server, no port forwarding is needed. Best for exposing web services (Nextcloud, Jellyfin, dashboards) to the internet with Cloudflare's DDoS protection in front.

# Install cloudflared
curl -fsSL https://pkg.cloudflare.com/cloudflared-linux-amd64.deb -o cloudflared.deb
# For Raspberry Pi (ARM64), replace amd64 with arm64 in the URL above
sudo dpkg -i cloudflared.deb

# Authenticate with your Cloudflare account
cloudflared tunnel login

# Create a tunnel
cloudflared tunnel create home-tunnel

# Route a subdomain to your local service
cloudflared tunnel route dns home-tunnel myservice.yourdomain.com

Requires: A domain on Cloudflare (free plan works).

SSH Reverse Tunnel (DIY Relay)

If you have a cheap VPS ($3/month from RackNerd), your home server connects outbound to the VPS, creating a tunnel. Traffic arrives at the VPS and gets forwarded through the tunnel to your home server.

# On the VPS: enable GatewayPorts in sshd_config
# Add this line to /etc/ssh/sshd_config on the VPS:
#   GatewayPorts yes
# Then: sudo systemctl restart sshd

# From your home server, create the reverse tunnel:
ssh -R 51820:localhost:51820 -N -f user@your-vps-ip

# Now traffic to VPS-IP:51820 reaches your home server's port 51820

To make this persistent (survives reboots and disconnections), use autossh:

sudo apt install autossh -y
autossh -M 0 -f -N -R 51820:localhost:51820 user@your-vps-ip -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3"

Part 12: Maintenance

A home server isn't "set and forget" — it needs occasional attention. But we're talking 10 minutes a week, not hours. Here's a simple routine.

Weekly (5 Minutes)

# Check disk space — if this fills up, everything breaks
df -h

# Check all Docker containers are running (should show "Up")
docker ps -a

# Look for errors in the last week
journalctl --since "1 week ago" -p err | tail -20

# Temperature (Raspberry Pi only — throttles at 80°C)
vcgencmd measure_temp

Monthly (10 Minutes)

# Update operating system packages (security patches)
sudo apt update && sudo apt upgrade -y

# Update all Docker containers to latest versions
cd /path/to/your/compose/files
docker compose pull && docker compose up -d

# Check fail2ban — see how many IPs it's blocking
sudo fail2ban-client status

# Review firewall — make sure only expected ports are open
sudo ufw status numbered

Backup (Critical)

The most common home server disaster: SD card dies, hard drive fails, or you accidentally break something. If you don't have backups, you're starting from scratch.

# Create backup directory
sudo mkdir -p /backups

# Backup all Docker data (configs, databases, etc.)
cd /path/to/your/compose/files
docker compose stop
sudo tar czf /backups/home-server-$(date +%Y%m%d).tar.gz /var/lib/docker/volumes/
docker compose start

# Copy backup to your PC (so it's on a different physical device)
scp [email protected]:/backups/*.tar.gz ~/backups/

# Automate it (run weekly, Sunday 3 AM)
# Add to crontab: crontab -e
# 0 3 * * 0 cd /home/youruser && docker compose stop && tar czf /backups/weekly-$(date +\%Y\%m\%d).tar.gz /var/lib/docker/volumes/ && docker compose start

Rule of thumb: If you'd be upset losing it, back it up. If you'd be upset losing the backup, copy it to a second location.


The Complete Home Server Stack

┌──────────────────────────────────────┐
│           Your Router                │
│  Port 443 → server   (MTProto)      │
│  Port 51820 → server (WireGuard)    │
├──────────────────────────────────────┤
│    Home Server (192.168.1.100)       │
│  ┌──────────┐ ┌──────────┐          │
│  │WireGuard │ │MTProxyMax│          │
│  │  (VPN)   │ │(Telegram)│          │
│  └──────────┘ └──────────┘          │
│  ┌──────────┐ ┌──────────┐          │
│  │ Pi-hole  │ │ Jellyfin │          │
│  │ (ads)    │ │ (media)  │          │
│  └──────────┘ └──────────┘          │
│  ┌──────────┐ ┌──────────┐          │
│  │Nextcloud │ │  Uptime  │          │
│  │(storage) │ │  Kuma    │          │
│  └──────────┘ └──────────┘          │
│  Fortify (security) + UFW + SSH keys │
├──────────────────────────────────────┤
│  Raspberry Pi 4/5 or Mini PC        │
│  Ubuntu Server / Raspberry Pi OS    │
└──────────────────────────────────────┘

Cost Breakdown

Item One-Time Monthly
Raspberry Pi 4B 4GB + accessories ~$83
OR: Used mini PC ~$100
microSD / SSD ~$15
Electricity (Pi) ~$1
Electricity (mini PC) ~$3
Domain (optional) ~$1
Total (Pi) ~$98 ~$1/month
Total (Mini PC) ~$115 ~$3/month

Compare to monthly VPS costs: $3-10/month × 12 = $36-120/year. A home server pays for itself in the first year.


Related Guides

SamNet Open Source Tools

Tool What It Does Link
wg-orchestrator WireGuard VPN management with TUI, QR codes, web dashboard GitHub
MTProxyMax Telegram MTProto proxy with FakeTLS, multi-user, Telegram bot GitHub
fortify Server security hardening with scoring and one-click profiles GitHub
paqctl Censorship bypass with Paqet (KCP) and GFW-Knocker GitHub
torware One-click Tor Bridge/Relay with TUI and Telegram notifications GitHub
dnstm-setup DNS tunnel deployment wizard (8 tunnel types) GitHub

Related Tools