What You'll Do
This guide takes you from a fresh Ubuntu Server install to a hardened, Docker-ready system. Perfect for running homelab services on bare metal, a VM, or a Raspberry Pi.
Prerequisites
- Ubuntu Server 24.04 LTS (or 22.04 LTS)
- SSH access to your server
- sudo privileges or root access
- A static IP address (recommended)
Part 1: Initial Setup
Step 1: Connect via SSH
ssh ubuntu@<server-ip>
Step 2: Update the system
sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y
Step 3: Set hostname
sudo hostnamectl set-hostname homelab-server
sudo nano /etc/hosts
Change 127.0.1.1 ubuntu to 127.0.1.1 homelab-server, then verify:
hostname
Step 4: Configure a static IP
Check your network interface name:
ip link show
Edit Netplan config:
sudo nano /etc/netplan/00-installer-config.yaml
Set static IP:
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.1.100/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
Apply:
sudo netplan apply
ip addr show
Part 2: Security Hardening
Step 1: Harden SSH
sudo nano /etc/ssh/sshd_config
Recommended settings:
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 5
sudo systemctl restart ssh
Step 2: Set up UFW firewall
sudo ufw enable
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 2222/tcp
sudo ufw status
Step 3: Install Fail2Ban
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Part 3: Essential Tools
sudo apt install -y \
curl wget git htop tmux vim \
net-tools dnsutils telnet nmap iotop nethogs
Part 4: Install Docker & Docker Compose
Step 1: Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Step 2: Add your user to the Docker group
sudo usermod -aG docker $USER
newgrp docker
docker ps
Step 3: Install Docker Compose
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
docker-compose --version
Step 4: Enable Docker on boot
sudo systemctl enable docker
Next steps
Your server is now hardened and Docker-ready. From here you can:
- Deploy Pi-hole in Docker
- Set up Proxmox on dedicated hardware
- Run Portainer stacks or a Cloudflare Tunnel for zero open WAN ports
How to install Docker on Ubuntu Server (official repo, best practice)
Goal: install Docker Engine + Docker Compose plugin the “right way” (official Docker repo), then verify it works.
Prerequisites
- Ubuntu Server (LTS recommended)
- SSH access as a sudo-capable user
Step 1 — Remove old/conflicting packages (safe cleanup)
sudo apt remove -y docker docker-engine docker.io containerd runc || true
Step 2 — Install prerequisites
sudo apt update
sudo apt install -y ca-certificates curl gnupg
Step 3 — Add Docker’s official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
Step 4 — Add Docker’s apt repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
Step 5 — Install Docker Engine + Compose plugin
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Step 6 — Start Docker and enable at boot
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
Step 7 — Allow your user to run Docker (optional but common)
This avoids typing sudo for every docker command.
sudo usermod -aG docker $USER
newgrp docker
Verify
docker version
docker compose version
Step 8 — Test with a container
docker run --rm hello-world
Expected: a “Hello from Docker!” message.
Troubleshooting
docker: Got permission denied- Make sure you ran the
usermodstep and started a new shell (or usednewgrp docker).
- Make sure you ran the
- Firewall issues
- Docker publishes ports via iptables/nftables rules; if you use UFW, you may need to explicitly allow ports and/or understand the Docker+UFW interaction.
Security notes
- If you don’t fully trust the user on the box, do not add them to the
dockergroup (it’s effectively root).
Next steps
- Install Portainer (see guide)
- Install Pi-hole in Docker (see guide)