Intro
You may or may not want to set up your own server at home. I did, mostly for learning purposes and for data science projects.
The following is a description of the process I followed for future reference. It’s fairly procedural as it’s only a lightly edited version of the iCloud note I kept along the way.
To start with, I bought a HP ProDesk 600 G5 Mini (Intel i5-9500T, 16GB RAM, 512GB HDD) on eBay for ~$150. This seemed like a reasonable price for a minimally capable machine that’s small and energy efficient. There are obviously many options; I was looking for something more powerful than a Raspberry Pi and less expensive than a workstation.
Besides the server itself, I needed the following peripherals to get started, all of which I had already.
- monitor for initial setup
- keyboard for initial setup
- Ethernet cable
- power cable
- flash drive for Ubuntu installer
Definitions
The following were some concepts I unfamiliar with or only somewhat familiar with before starting. This part isn’t meant to be a comprehensive guide as much as it is a subset of what I personally learned this weekend (primarily via ChatGPT).
Networking
- DHCP (Dynamic Host Configuration Protocol): A server protocol that automatically assigns IP addresses to devices on a network, ensuring they can communicate effectively without address conflicts.
- IPv4 vs IPv6: These are versions of the Internet Protocol. IPv4 uses a 32-bit address space, while IPv6 uses 128 bits, allowing for a vast number of unique addresses.
- Nameservers: These are the internet’s equivalent of a phone book, translating human-readable domain names to IP addresses.
- DNS (Domain Name System): This system translates domain names like www.example.com into IP addresses that network devices use to identify each other.
- Subnet: A subdivision of an IP network that can segment a large network into smaller, more manageable pieces.
- Nameservers: Specialized servers that translate domain names into IP addresses, allowing browsers to load internet resources.
Software
- BIOS (Basic Input/Output System): Firmware that initializes hardware during the boot process and provides runtime services for the operating system.
- NTP (Network Time Protocol): A networking protocol for clock synchronization between computer systems over packet-switched, variable-latency data networks.
- LUKS (Linux Unified Key Setup): A disk encryption specification that provides a platform-independent standard on-disk-format for use in various tools.
- LVM (Logical Volume Manager): A device mapper target that provides logical volume management for the Linux kernel.

Process
As noted above, the following is mostly just my process notes.
- Power on HP ProDesk 600 G5 Mini
- Boot Windows and make note of Windows product key
- Using my MacBook and a flash drive, create a bootable Ubuntu 22.04.3 LTS installer:
diskutil listto list disksdiskutil unmountDisk /dev/disk[number corresponding to flash drive from output previous command]i.e.diskutil unmountDisk /dev/disk4to unmount flash drivesudo dd if=/local/path/to/ubuntu-22.04.3-live-server-amd64.iso of=/dev/rdisk[number from above] bs=1mto copy iso to flash drive (be very careful to use the right disk number! also note ‘r’ inofpath)
- Update BIOS settings on ProDesk to allow booting from USB:
F10(varies by machine) to enter BIOS settings- Make sure USB Storage Boot is enabled and set to top of boot order
- Plug in flash drive to ProDesk and boot from USB:
- Cycle power; if BIOS settings were reconfigured correctly, you should see a screen with options to try or install Ubuntu
- Follow prompts to install Ubuntu
- Select “Try or Install Ubuntu Server”
- Configure network connections
- Select interface
- IPv4: “Manual”
- Subnet: Given in router settings
- Address: Chosen based on router settings—find DHCP range and choose a number outside that range
- Gateway: Given in router settings (usually same as address but with 1 as last number)
- Name servers: Usually Google’s or Cloudflare’s, i.e.
1.1.1.1, 1.0.0.1 - Search domains: “home”
- Configure proxy:
- I skipped this to start with
- Storage configuration:
- Use entire disk
- LUKS encryption
- LVM
- Create user
- Choose a username and password
- Install OpenSSH server
- Install updates
- Reboot
- Set up firewall
sudo ufw enableto enable firewallsudo ufw default deny incomingto block all incoming trafficsudo ufw default deny outgoingto block all outgoing trafficsudo ufw allow sshto allow sshsudo ufw allow [port number]to allow ssh from a safer port than the defaultsudo ufw allow out 80to allow outgoing HTTP requestssudo ufw allow out 443to allow outgoing HTTPS requestssudo ufw allow out 53to allow outgoing DNS requestssudo ufw allow from any to any port 123 proto udpto allow NTP (for time synchronization)sudo ufw status verboseto check status
- Configure ssh
sudo apt updateto update package listssudo apt install openssh-serverto make sure ssh server is installed (should have been already from installer)sudo systemctl status sshto verify statussudo nano /etc/ssh/sshd_configto edit config file; add:- Port [port number]
- PermitRootLogin no
- AllowUsers [username]
- PubkeyAuthentication yes
sudo systemctl restart sshto apply changes- On MacBook:
ssh-keygen -t rsato generate key pair- Choose default location
- Enter passphrase
ssh-copy-id -i ~/.ssh/id_rsa.pub -p [port number] [username]@[ip address]to copy public key to server
- Configure fail2ban
sudo apt install fail2bansudo cp /etc/fail2ban/jail.{conf,local}sudo nano /etc/fail2ban/jail.localto add desired settings to config filesudo systemctl start fail2bansudo systemctl enable fail2bansudo fail2ban-client status sshdsudo tail -f /var/log/fail2ban.logto monitor logs
- SSH into live, configured server:
ssh -p [port number] [username]@[ip address]- Look around to make sure everything looks good
- Set up server in long-term physical location
- Unplug server from monitor and plug into router via Ethernet
- Power on
- Plug in keyboard
- Enter LUKS password with spare keyboard (blindly)
- Wait for a couple minutes
- SSH in from MacBook again
Next steps
- Install Fig, a command-line tool with lots of useful features like autocomplete and aliases
- on MacBook:
fig integrations install ss - on server:
curl -fSsL https://repo.fig.io/scripts/install-headless.sh | bash - on server:
exec bash --norcto reset shell
- on MacBook:
- Set timezone and sync (note: after a surprisingly long time fiddling with this, I punted on syncing and settled on setting the timezone using my location string)
- Install
glancesfor monitoringsudo apt install glancesglances
- Expand volume size
lvextend -L+156G /dev/mapper/ubuntu--vg-ubuntu--lvsudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
Conclusion
This is all fairly boilerplate stuff but I just want to hedge again that this post is primarily to keep track of what I did for future reference and not an authoritative guide. That said, if you see something in this post that you think departs from best practices, I would love to hear about it—please comment below or reach out.