# 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 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:** ```bash 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. ```bash 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 ```bash 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: ```bash 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): ```bash echo mypassword | sudo -S apt update # -S reads password from stdin (standard input) ``` **Become root entirely** (use carefully): ```bash 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. ```bash 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 ```bash # 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: ```bash 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: ```bash 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 ```bash 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: ```bash 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 ```bash 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](02-bash-scripting.md)