Complete documentation suite for KiteStacks covering all 11 services across 2-host active-active architecture. Includes beginner track (with AI, 8 files) and advanced track (without AI, 7 files) with time estimates, real troubleshooting cases, and command-by-command explanations. Updates certifications roadmap to reflect July 7 2026 A+ Core 2 exam goal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 KiB
Without AI — Part 1: Linux Foundations
Track: Advanced (No AI)
Time for this section: 1–2 weeks of evenings and weekends
Before you touch Docker or any service, you need a solid foundation in Linux. Every command you run in this homelab is a Linux command. If you skip this, you will be copying without understanding — which means you cannot debug when things go wrong.
Total Build Time Estimate (Without AI)
Before you start, here is an honest breakdown of how long this entire homelab takes to build from scratch — assuming you are learning as you go, working 2–3 hours on evenings and weekends:
| Phase | What You Are Learning / Building | Estimated Time |
|---|---|---|
| 1 — Linux Foundations | Shell, filesystem, permissions, SSH | 1–2 weeks |
| 2 — Bash Scripting | Variables, loops, conditionals, scripts | 1–2 weeks |
| 3 — Python Basics | Data structures, sqlite3, HTTP requests | 1–2 weeks |
| 4 — Docker Deep Dive | Images, volumes, networks, compose | 1–2 weeks |
| 5 — Networking | DNS, ports, TLS, Tailscale, firewalls | 1–2 weeks |
| 6 — Full Build | Deploying all 11 services + cloud failover | 4–8 weeks |
| 7 — Troubleshooting | Debugging, production issues, fixes | Ongoing |
| Documentation | Writing what you built and why | 1 week |
Total: approximately 3–6 months working part-time (evenings + weekends).
Full-time (8 hours/day): 6–10 weeks.
The wide ranges reflect the honest reality: some people hit a DNS issue that takes 3 hours to debug. Some services take a day to configure SSO for. Budget extra time. The troubleshooting you will do along the way is not wasted time — it is where most of the real learning happens.
What Is Linux?
Linux is an operating system — like Windows or macOS — but open source, free, and used to run most of the internet. Your home server, your cloud VPS, and almost every web server in existence runs Linux.
Why Linux and not Windows Server?
- Free — no licensing cost
- More control — no hidden processes you can't see or stop
- Docker runs natively on Linux (on Windows, Docker runs inside a hidden Linux VM)
- The entire cloud engineering industry is Linux-first
You will use Ubuntu 24.04 LTS — the most widely used Linux distribution for servers.
The Terminal
The terminal (also called the shell or command line) is where you work. There is no graphical interface for most server tasks. You type a command, press Enter, read the output, and type the next command.
Open a terminal on Ubuntu: Ctrl + Alt + T
You will see a prompt like:
kenpat@monk:~$
Breaking that down:
kenpat— your usernamemonk— the machine name (hostname)~— your current directory (~means your home directory,/home/kenpat)$— indicates you are a regular user (not root/admin)
The Filesystem
Linux organizes everything in a tree of directories (folders) starting at / (root).
/
├── home/ ← user home directories
│ └── kenpat/ ← your home directory (~)
├── etc/ ← system configuration files
├── var/ ← variable data (logs, databases)
├── usr/ ← installed programs
├── tmp/ ← temporary files (cleared on reboot)
├── opt/ ← optional software (we use this for kscloud1)
└── proc/ ← virtual filesystem — represents running processes
Key commands:
pwd # Print Working Directory — where am I right now?
ls # List files in current directory
ls -la # List all files, including hidden ones, with permissions
cd /home/kenpat # Change Directory — move to a specific path
cd ~ # Go to your home directory
cd .. # Go up one level
mkdir mydir # Make a new directory
mkdir -p a/b/c # Make directories including parents (-p = parents)
rm file.txt # Remove a file
rm -rf mydir/ # Remove a directory and everything inside it (-r = recursive, -f = force)
cp file.txt backup.txt # Copy a file
mv file.txt newname.txt# Move or rename a file
cat file.txt # Print the contents of a file
less file.txt # View a file page by page (q to quit)
nano file.txt # Open a file in the nano text editor
Practice: Run these commands. Navigate around the filesystem. Understand what you see.
pwd # Where are you?
ls / # What is in the root directory?
ls /home # What home directories exist?
ls -la ~ # What files are in YOUR home directory? (hidden files too)
cd /var/log # Go to the log directory
ls # What log files exist?
cat /etc/hostname # What is this machine's hostname?
cd ~ # Go back home
File Permissions
Every file in Linux has permissions that control who can read it, write to it, or execute it. This is crucial — misconfigured permissions are a common source of bugs.
-rw-r--r-- 1 kenpat kenpat 1234 Jun 19 10:00 myfile.txt
Breaking it down:
-— file type (d= directory,-= regular file,l= symlink)rw-— owner permissions: read, write, no executer--— group permissions: read onlyr--— everyone else: read onlykenpat kenpat— owner and group
chmod 644 myfile.txt # rw-r--r-- (owner read/write, others read)
chmod 755 myscript.sh # rwxr-xr-x (owner full, others read+execute)
chmod +x myscript.sh # Add execute permission for everyone
chown kenpat:kenpat file.txt # Change owner to kenpat, group to kenpat
chown -R 1000:1000 /mydir/ # Change owner recursively for entire directory
Why this matters in Docker: Docker containers run as specific user IDs. If a container expects to own a file (e.g., UID 1000) but the file is owned by root, the container cannot write to it. Many Docker setup issues come down to file permission mistakes.
Users and sudo
Linux separates regular users from the administrator (called root).
Root can do anything — delete system files, stop critical services, change any setting.
Regular users cannot.
sudo lets a trusted user run a single command as root:
sudo apt update # Run apt update as root
sudo systemctl restart docker # Restart Docker as root
sudo nano /etc/hosts # Edit a system file as root
Non-interactive sudo (used in scripts when there is no terminal to type a password):
echo mypassword | sudo -S apt update
# -S reads password from stdin (standard input)
Become root entirely (use carefully):
sudo -i # Opens a root shell. Prompt changes from $ to #
exit # Return to regular user
SSH — Connecting to Remote Machines
SSH (Secure Shell) lets you control a remote machine over an encrypted connection.
ssh kenpat@192.168.1.100 # Connect to a local machine
ssh root@5.78.x.x # Connect to your VPS as root
ssh -i ~/.ssh/mykey kenpat@host # Connect using a specific private key
ssh -L 5099:localhost:5000 kenpat@host # Local port forward
SSH Keys (Better Than Passwords)
Instead of typing a password every time, you generate a key pair:
- Private key (
~/.ssh/id_ed25519) — stays on your machine, never shared - Public key (
~/.ssh/id_ed25519.pub) — put this on the server
# Generate a new key pair
ssh-keygen -t ed25519 -C "monk-to-kscloud1" -f ~/.ssh/id_ed25519_kscloud1
# Copy your public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519_kscloud1.pub kenpat@your-vps-ip
# Connect using the key
ssh -i ~/.ssh/id_ed25519_kscloud1 kenpat@your-vps-ip
SSH Local Port Forwarding
Sometimes a service is running on a remote machine but not exposed publicly. You can forward a local port to a remote port through the SSH connection:
ssh -L 5099:localhost:5000 kenpat@kscloud1-tailscale-ip
This means: "On MY machine, port 5099 forwards to kscloud1's localhost:5000."
Now visiting http://localhost:5099 in your browser reaches kscloud1's port 5000.
Used in this homelab to access kscloud1's Kavita directly (bypassing Cloudflare) when configuring OIDC settings.
Package Management (apt)
Ubuntu uses apt to install, update, and remove software:
sudo apt update # Refresh the list of available packages
sudo apt upgrade -y # Install all available updates
sudo apt install -y curl git # Install specific packages
sudo apt remove package # Remove a package
sudo apt search keyword # Search for a package by name
dpkg -l | grep docker # List installed packages matching "docker"
Processes and Services
ps aux # List all running processes
ps aux | grep docker # Find processes matching "docker"
top # Live process monitor (q to quit)
htop # Better live monitor (install with: sudo apt install htop)
kill 1234 # Send kill signal to process ID 1234
kill -9 1234 # Force kill (cannot be ignored)
pkill conky # Kill all processes named "conky"
systemctl status docker # Check if Docker service is running
systemctl start docker # Start it
systemctl stop docker # Stop it
systemctl restart docker # Restart it
systemctl enable docker # Make it start automatically on boot
systemctl disable docker # Prevent it from starting on boot
Reading Logs
When something breaks, you read the logs to find out why:
journalctl -u docker # System logs for the Docker service
journalctl -f # Follow all system logs live
cat /var/log/syslog # System log file
tail -f /var/log/syslog # Follow (live tail) the system log
dmesg | tail -20 # Kernel messages, last 20 lines
Essential Tools
curl -s https://example.com # Make an HTTP GET request
curl -s https://example.com | head # Pipe output through head (first 10 lines)
wget https://example.com/file.zip # Download a file
grep "error" /var/log/syslog # Search a file for a pattern
grep -r "TUNNEL_TOKEN" ~/kitestacks-live/ # Search recursively in a directory
find ~ -name "*.env" 2>/dev/null # Find all .env files in home dir
find /opt -name "docker-compose.yml" # Find all compose files
wc -l file.txt # Count lines in a file
cut -d= -f2 file.env # Cut: split by = and take field 2
tr -d '\n' # Remove newlines from input
| # Pipe: send output of one command to another
> # Redirect: write output to a file (overwrites)
>> # Redirect: append output to a file
2>/dev/null # Redirect error output to /dev/null (discard errors)
Practice Exercises
Do these before moving on:
- Navigate to
/var/logand read the last 20 lines ofsyslog - Create a directory structure:
~/practice/a/b/c/ - Create a file in
c/with your name in it usingecho "your name" > ~/practice/a/b/c/name.txt - Read it with
cat - Check its permissions with
ls -la - Change its permissions to read-only:
chmod 444 ~/practice/a/b/c/name.txt - Try to edit it — what happens?
- Find all
.conffiles in/etc/that contain the word "ubuntu" - Generate an SSH key pair with
ssh-keygen - SSH into your VPS
Next: Part 2 — Bash Scripting