kitestacks-homelab/homelab-mastery/build-guide/without-ai/01-linux-foundations.md
kenpat 1e8319ee75 docs: comprehensive homelab-mastery rewrite with full build guides
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>
2026-06-19 01:08:43 -05:00

12 KiB
Raw Blame History

Without AI — Part 1: Linux Foundations

Track: Advanced (No AI)
Time for this section: 12 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 23 hours on evenings and weekends:

Phase What You Are Learning / Building Estimated Time
1 — Linux Foundations Shell, filesystem, permissions, SSH 12 weeks
2 — Bash Scripting Variables, loops, conditionals, scripts 12 weeks
3 — Python Basics Data structures, sqlite3, HTTP requests 12 weeks
4 — Docker Deep Dive Images, volumes, networks, compose 12 weeks
5 — Networking DNS, ports, TLS, Tailscale, firewalls 12 weeks
6 — Full Build Deploying all 11 services + cloud failover 48 weeks
7 — Troubleshooting Debugging, production issues, fixes Ongoing
Documentation Writing what you built and why 1 week

Total: approximately 36 months working part-time (evenings + weekends).

Full-time (8 hours/day): 610 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 username
  • monk — 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 execute
  • r-- — group permissions: read only
  • r-- — everyone else: read only
  • kenpat 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:

  1. Navigate to /var/log and read the last 20 lines of syslog
  2. Create a directory structure: ~/practice/a/b/c/
  3. Create a file in c/ with your name in it using echo "your name" > ~/practice/a/b/c/name.txt
  4. Read it with cat
  5. Check its permissions with ls -la
  6. Change its permissions to read-only: chmod 444 ~/practice/a/b/c/name.txt
  7. Try to edit it — what happens?
  8. Find all .conf files in /etc/ that contain the word "ubuntu"
  9. Generate an SSH key pair with ssh-keygen
  10. SSH into your VPS

Next: Part 2 — Bash Scripting