Setting up a home server is one of the most rewarding projects for developers. You get full control over your data, the ability to self-host services, and the satisfaction of running your own infrastructure. This guide covers everything from hardware selection to security hardening.
Why Self-Host?
Before diving in, here's why running a home server is worth the effort:
- Privacy: Your data never leaves your home
- Cost: VPS alternatives cost $20-100/month; home server runs on existing hardware
- Learning: You'll learn DevOps, networking, and Linux administration
- Reliability: No one can shut down your server except you
Hardware Recommendations
You have three main options for home server hardware:
Option 1: Mini PC (Recommended)
Best balance of power, cost, and noise:
- Intel NUC: Starting at $250, power-efficient, runs Ubuntu flawlessly
- ASRock Beebox: Mini form factor, upgradable, ~$400
- HP EliteDesk: Ultra-small, ~$350, fanless options
Option 2: Repurposed Hardware
Use what you already have:
- Old laptop: Remove screen, keep closed, excellent battery backup
- Desktop tower: Use only for server (not gaming), most power per $
Option 3: NAS (Network Attached Storage)
If you need file storage + compute:
- Synology DS923+: ~$600, Docker support, excellent UI
- QNAP TS-470: ~$550, quieter than Synology, similar features
- TrueNAS Scale: ~$700, ZFS NAS, open hardware
Ubuntu Server Installation
Step 1: Download Ubuntu Server
Get the LTS (Long Term Support) version for stability:
- ubuntu.com/download/server
- Choose Ubuntu 24.04 LTS (supported until 2029)
- Download the ISO (not desktop)
Step 2: Create Bootable USB
# On macOS
brew install balena-etcher
balena-etcher ubuntu-24.04-live-server-amd64.iso
# On Linux
sudo dd if=ubuntu-24.04-live-server-amd64.iso of=/dev/sdX bs=4M status=progress
Step 3: Install Ubuntu
- Boot from USB and select "Install Ubuntu Server"
- CRITICAL: Choose "OpenSSH Server" during installation
- Set up user account with sudo privileges
- Enable automatic security updates
- Install LVM partitioning if you plan to expand storage later
Initial Server Setup
Update System
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git ufw fail2ban
Configure Firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
Disable Root Login
# Create new user
sudo adduser yourusername
sudo usermod -aG sudo yourusername
# Copy your SSH key
sudo -u yourusername mkdir -p /home/yourusername/.ssh
sudo cp ~/.ssh/authorized_keys /home/yourusername/.ssh/
sudo chown -R yourusername:yourusername /home/yourusername/.ssh
sudo chmod 700 /home/yourusername/.ssh
sudo chmod 600 /home/yourusername/.ssh/authorized_keys
# Disable root SSH
sudo sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart sshd
Essential Services to Install
Docker (for running everything)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker yourusername
Docker Compose (for orchestration)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Nginx (reverse proxy)
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
Portainer (Docker management UI)
docker run -d -p 9000:9000 --name portainer --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer-ce
Security Hardening
Fail2Ban (SSH protection)
sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
HTTPS with Let's Encrypt
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com
Automatic Backups
# Install restic backup tool
curl -LO https://github.com/restic/restic/releases/download/v0.16.4/restic_0.16.4_linux_amd64.bz2
bunzip2 restic_0.16.4_linux_amd64.bz2
sudo mv restic /usr/local/bin/
# Create backup script
nano ~/backup.sh
~/backup.sh content:
#!/bin/bash
restic -r /backup/restic backup /home /var/lib/docker
restic -r /backup/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12
chmod +x ~/backup.sh
crontab -e
Add to crontab:
0 2 * * * /home/yourusername/backup.sh
Recommended Services to Self-Host
Must-Haves
- Pi-hole: Network-wide ad blocking
- Nextcloud: Your own Google Drive replacement
- Homarr: Custom homepage for all services
Nice-to-Haves
- Jellyfin: Your own Netflix/Plex
- Immich: Your own Google Photos
- Uptime Kuma: Status page for all services
- Nginx Proxy Manager: GUI for reverse proxy config
Cost Breakdown
| Item | One-Time Cost | Monthly Savings |
|---|---|---|
| Intel NUC (i5, 16GB RAM) | $350 | -$25 (DigitalOcean) |
| 2TB External Drive | $80 | -$10 (Backblaze) |
| Electricity (~$10/mo) | - | -$10 |
| Domain + DNS | $12/year | -$2 (Cloudflare) |
| Total First Year | ~$450 | Saved $444 |
Next Steps
Once your server is running, explore:
- Setting up Docker stacks for specific services
- Monitoring with Grafana + Prometheus
- Automation with Ansible or simple bash scripts
- Backups to cloud storage (off-site redundancy)
Recommended Hosting Providers (If Home Server Fails)
- DigitalOcean: Simple pricing, good documentation
- Linode: Great performance, hourly billing
- Hetzner: Best value in Europe, great for privacy
- Vultr: Global locations, instant deployment
Planning your home server? This guide covers everything you need to get started. For help or questions, check out the Linux on iMac guide for Ubuntu basics.