Linux, Servers & Code: The Complete Systems Guide
Understand what actually happens inside your computer, then put it to work: how the Linux kernel, bootloader and distros fit together, a hands-on terminal tutorial, how to set up and secure a real server, how to configure your home router, and beginner-friendly fundamentals for Python, Java, HTML and Android — everything you need to go from "I click icons" to "I understand and control my systems."
Before you start. Practice terminal and server commands on a spare machine, a cheap single-board computer, or a virtual machine first — not on the only computer you can't afford to break. Commands like rm, chmod and anything run with sudo can cause real data loss if mistyped. This guide is educational reference material; always check your specific distro's documentation for exact package names and file paths, which vary between distributions.
Every website you visit runs on a server, most of those servers run Linux, most of the internet's routers and switches run a Linux-derived operating system, and the phone in your pocket is Linux underneath its Android skin. Learning the fundamentals here — the kernel, the shell, how a boot process works, how software talks to a network — is the single highest-leverage skill in all of technology, because it's the same handful of ideas showing up everywhere.
- What a kernel actually does, and how a distro is built on top of it
- How a Linux machine boots, from power-on to login (BIOS/UEFI, GRUB, init)
- Real terminal commands: navigation, files, permissions, processes, packages
- How to set up, secure and administer a headless Linux server
- How to configure your home router: DHCP, port forwarding, Wi-Fi security
- The core syntax and first script for Python, Java, HTML and Android
Work through the systems tabs in order if you're new to Linux; jump straight to a language tab if you already know your way around a terminal. Every section is self-contained, so bookmark this page and come back to whichever topic you need.
If you don't yet have a machine to experiment on, our Build Your Own Home Server guide walks through repurposing an old PC, buying a Raspberry Pi, or building a dedicated box — the perfect low-stakes place to apply everything in the Server Setup and Router tabs below.
An operating system is the software layer that sits between your hardware and every program you run, managing memory, the CPU, storage, and every connected device so applications don't need to talk to hardware directly. Linux is, strictly speaking, just the kernel — the core piece that does that management. What people casually call "Linux" (Ubuntu, Fedora, Debian, and so on) is technically GNU/Linux: the Linux kernel bundled with the GNU tools, a package manager, and a set of default applications into a complete, usable operating system.
This is also why the Android tab exists on this page: Android uses this exact same Linux kernel at its base, with a very different set of layers stacked on top.
| Responsibility | In plain terms |
|---|---|
| Process scheduling | Decides which program gets the CPU, and for how long, thousands of times per second |
| Memory management | Allocates RAM to programs and keeps them from overwriting each other |
| Device drivers | Talks to your disk, network card, GPU and every other piece of hardware |
| System calls | The controlled "front door" apps use to ask the kernel to do something |
| Filesystem access | Reads and writes files, and enforces who is allowed to touch what |
| Path | What lives there |
|---|---|
| /etc | System-wide configuration files |
| /home | Personal files and settings for each user |
| /var | Variable data: logs, caches, databases, mail queues |
| /usr | Installed programs and their supporting files |
| /bin, /sbin | Essential command binaries, incl. admin-only tools |
| /boot | The kernel image, initramfs, and GRUB's own files |
| /dev | Device files representing hardware (disks, terminals) |
| /proc, /sys | Virtual files exposing live kernel and process info |
| /tmp | Temporary files, usually cleared on reboot |
A "distro" packages the Linux kernel with a package manager, default software, and its own configuration philosophy. Nearly every distro traces back to one of a handful of families — knowing the family tells you which commands and package names to expect.
| Family | Examples | Package manager | Best for |
|---|---|---|---|
| Debian | Debian, Ubuntu, Linux Mint, Raspberry Pi OS | apt | Beginners, servers, huge community support |
| Red Hat | Fedora, RHEL, Rocky Linux, AlmaLinux | dnf | Enterprise servers, cutting-edge desktop (Fedora) |
| Arch | Arch Linux, Manjaro, EndeavourOS | pacman | Advanced users who want full control and the latest packages |
| SUSE | openSUSE, SUSE Linux Enterprise | zypper | Enterprise environments, robust admin tooling (YaST) |
From pressing the power button to a login prompt, a Linux machine passes through the same handful of stages every time.
Firmware built into the motherboard runs first, checks the hardware (POST), and hands control to the bootloader on the drive marked bootable.
Shows the boot menu (if enabled), then loads the Linux kernel and an initial RAM disk (initramfs) into memory. Covered in full detail below.
The kernel takes over, detects hardware, mounts the real root filesystem, and starts the very first process: PID 1.
PID 1 starts every other service in the correct order — networking, logging, your desktop environment or login prompt.
A login manager (graphical) or a plain terminal prompt (headless server) waits for you to authenticate and starts your session.
GRUB (GRand Unified Bootloader) is the software that runs immediately after the firmware and is responsible for finding and starting your operating system — or letting you choose between several, if you dual-boot.
| /boot/grub/grub.cfg | The generated config GRUB actually reads — don't hand-edit it |
| /etc/default/grub | The file you do edit (timeout, default entry, kernel options) |
| update-grub | Regenerates grub.cfg on Debian/Ubuntu after a config change |
| grub-mkconfig -o … | The underlying command update-grub wraps, used on other distros |
Holding Shift (BIOS) or repeatedly tapping Esc (UEFI) at boot reveals the GRUB menu — useful for booting an older kernel, entering recovery mode, or fixing a system that won't start normally.
Almost every modern distro uses systemd as PID 1, replacing the older SysVinit scripts. You'll use its systemctl command constantly — it comes back in the Server Setup tab for managing your own services.
| systemctl status NAME | Check if a service is running |
| systemctl start/stop NAME | Start or stop it right now |
| systemctl enable/disable NAME | Set (or unset) it to start automatically at boot |
| journalctl -u NAME | Read that service's logs |
A graphical file manager can't SSH into a headless server, script a repeated task, or tell you exactly why a service failed. The terminal is slower at first and dramatically faster forever after — every command below works on virtually any Linux distro, and most carry over directly to macOS.
| Command | Does | Example |
|---|---|---|
| pwd | Print the current directory | pwd |
| ls | List files (add -la for hidden files + details) | ls -la |
| cd | Change directory (cd .. goes up one level) | cd /var/log |
| mkdir | Create a new directory | mkdir projects |
| cp | Copy a file or folder (-r for folders) | cp -r site/ backup/ |
| mv | Move or rename a file | mv old.txt new.txt |
| rm | Delete a file (-r for folders) — no undo, no trash | rm -r old-build/ |
| find | Search for files by name, type or age | find . -name "*.log" |
rm -rf deletes without confirmation and without a trash bin. Double-check the path before pressing Enter, especially with wildcards.| cat file | Print a whole file to the screen |
| less file | Scroll through a long file (q to quit) |
| head / tail | Show the first / last lines (tail -f follows live) |
| nano file | Beginner-friendly terminal text editor |
| grep "text" file | Search inside a file for matching lines |
Once you're comfortable, vim is dramatically faster once learned but has a real learning curve — nano is the better starting point.
Every file has an owner, a group, and three permission sets (owner / group / everyone else), each with read, write and execute bits.
| chmod 755 file | Owner: read/write/execute, others: read/execute |
| chmod +x file | Add execute permission for everyone |
| chown user:group file | Change who owns the file |
| sudo command | Run one command with administrator privileges |
| ps aux | List every running process |
| top / htop | Live, interactive process & resource monitor |
| kill PID | Ask a process to stop (kill -9 forces it) |
| df -h | Show disk space usage, human-readable |
| free -h | Show RAM and swap usage |
| Task | apt | dnf | pacman |
|---|---|---|---|
| Install | install | install | -S |
| Remove | remove | remove | -R |
| Update all | update && upgrade | upgrade | -Syu |
| Search | search | search | -Ss |
This is where the terminal starts to feel powerful: instead of one command at a time, you connect commands so the output of one becomes the input of the next.
A server is usually "headless" — no monitor, no keyboard, running quietly in a corner or a closet. You administer it entirely over the network, almost always through SSH. Everything below assumes a Debian/Ubuntu-family server; the concepts carry over to every distro, only the exact package names change.
Once key-based login works, harden it in /etc/ssh/sshd_config:
| PasswordAuthentication no | Require a key — blocks brute-force password guessing |
| PermitRootLogin no | Forces admins to log in as a normal user, then sudo |
| Port 2222 | Optional — moves SSH off the default port 22 |
Restart the service to apply changes: sudo systemctl restart ssh. Keep an existing session open while you test a new one, so a config mistake can't lock you out.
Every long-running program on your server — a web server, a game server, your own script — should run as a systemd service so it starts on boot and restarts if it crashes.
Save as /etc/systemd/system/myapp.service, then:
| Task | ufw (Debian/Ubuntu) | firewalld (RHEL/Fedora) |
|---|---|---|
| Enable | ufw enable | --add-service=ssh |
| Allow a port | ufw allow 22/tcp | --add-port=22/tcp |
| Check status | ufw status | --list-all |
Cron runs commands on a schedule — backups, updates, cleanup scripts. Edit your schedule with crontab -e.
Read top to bottom: minute, hour, day-of-month, month, day-of-week — an asterisk means "every."
- Update regularly:
sudo apt update && sudo apt upgrade - Enable automatic security updates (
unattended-upgradeson Debian/Ubuntu) - Install
fail2banto auto-block repeated failed login attempts - Change every default username and password immediately after setup
- Only expose to the internet what genuinely needs to be reachable — see the Router tab for VPN alternatives to port forwarding
A server whose address changes breaks every bookmark and script pointed at it. The cleanest fix is a DHCP reservation on your router (covered in the next tab) rather than a static IP set on the server itself — it stays consistent even if you reinstall the OS.
/etc/netplan/*.yaml; run sudo netplan apply after editing.Your router is the device that connects your home network to the internet and hands out local addresses to everything else — it's also almost always the most under-secured device in the house, since most people never open its settings after the initial setup.
That address (commonly 192.168.0.1 or 192.168.1.1) opened in a browser is your router's admin panel. Change the default admin password the first time you log in — it's printed on a label on the router and public knowledge for that model.
| Setting | What it does |
|---|---|
| DHCP range | The pool of local IPs the router hands out automatically to new devices |
| DHCP reservation | Pins one device's MAC address to always receive the same local IP |
| Port forwarding | Routes incoming internet traffic on a specific port to one device inside your network |
| DNS settings | Which server translates domain names to IP addresses for your whole network |
| Wi-Fi security | Should be WPA3, or WPA2 if your hardware is older — never WEP or open |
| Guest network | A separate Wi-Fi network isolated from your main devices |
| Firmware updates | Patches security holes — check periodically, since most routers don't auto-update |
- Find your device's MAC address (
ip linkon Linux, printed on the device, or listed in the router's connected-devices page) - Open your router's DHCP or LAN settings and look for "Address Reservation" or "Static Lease"
- Enter the MAC address and the local IP you want it to always receive
- Reboot the device once to confirm it picks up the reserved address
Port forwarding opens a direct path from the internet to one device — genuinely useful, but every open port is one more thing to secure.
- Give the target device a DHCP reservation first (above)
- In the router's Port Forwarding section, map an external port to that device's internal IP and port
- Test from outside your network (mobile data works well) — a local test can succeed even when the internet-facing rule is wrong
Smart plugs, cameras and other IoT devices have a poor security track record. A guest network or VLAN keeps them on a separate segment that can reach the internet but not your main computers, phones or server — so a compromised lightbulb can't be used to reach anything that actually matters.
| ping 8.8.8.8 | Is there a working connection at all? |
| traceroute host | Where along the path is traffic slowing or stopping? |
| dig / nslookup host | Is DNS resolving the domain to the right IP? |
| ip a | What IP, and which network interfaces, does this machine have? |
Python reads almost like plain English, which makes it the most common first programming language — and it scales all the way up to automation scripts, home-automation glue code, data science and full web backends.
| Debian/Ubuntu | sudo apt install python3 python3-pip |
| Fedora | sudo dnf install python3 |
| macOS | brew install python |
| Windows | winget install Python.Python.3 |
Check it worked: python3 --version
Save as hello.py, then run: python3 hello.py
A virtual environment keeps each project's packages separate, so installing one project's dependencies never breaks another's.
- Automation scripts for repetitive terminal tasks
- Home automation and Raspberry Pi projects (pairs well with the Server tab)
- Web backends with Flask or Django
- Data analysis with pandas, or basic machine learning
Java compiles to bytecode that runs on the Java Virtual Machine (JVM), so the same program runs unchanged on Linux, Windows or macOS — "write once, run anywhere." It's strongly typed and object-oriented, and it's the traditional language behind native Android apps, which is why it reappears in the Android tab.
| Debian/Ubuntu | sudo apt install default-jdk |
| Fedora | sudo dnf install java-latest-openjdk |
| macOS | brew install openjdk |
Check it worked: java -version and javac -version
Save as Hello.java, then: javac Hello.java && java Hello
Java organizes code around classes (blueprints) and objects (instances of them). A class can extend another to inherit its behavior, and interfaces define a contract multiple unrelated classes can implement.
Real projects use Maven or Gradle to manage dependencies and builds instead of compiling by hand. Java (and Kotlin alongside it) powers native Android apps, huge enterprise backends, and Minecraft's original codebase.
Every web page — including the interactive tools throughout this very site — is built from three layers: HTML for structure and content, CSS for appearance, and JavaScript for behavior. Learn these three and you can build, or at least read and modify, almost anything on the web.
| <h1>–<h6> | Headings, largest to smallest |
| <p> | A paragraph of text |
| <a href=""> | A hyperlink |
| <img src=""> | An image |
| <div>, <span> | Generic containers (block vs. inline) |
| <ul>, <li> | A bulleted list and its items |
| <form>, <input> | A form and its input fields |
Android is built directly on top of the Linux kernel from the How Linux Works tab — the same process scheduling, memory management and permission model, with Google's own layers stacked on top for apps and touch interfaces.
ADB is a terminal tool that talks directly to an Android device over USB (or Wi-Fi) — the same "learn the command line" payoff from earlier tabs, applied to your phone.
| adb devices | List connected devices |
| adb install app.apk | Install an app package |
| adb shell | Open a Linux shell on the device itself |
| adb logcat | Stream live system and app logs |
| adb pull / push | Copy files off / onto the device |
Enable it on the device first: Settings → About Phone → tap "Build Number" 7 times → Developer Options → USB Debugging.
Native Android apps are written in Kotlin (now Google's preferred language) or Java from the tab above, built in Android Studio. Every screen is built around an Activity with its own lifecycle: created, started, resumed, paused, stopped, destroyed.
"Rooting" grants apps and the user the same unrestricted administrator access on Android that sudo grants on a Linux desktop — full filesystem access, the ability to remove pre-installed apps, and deep customization. The exact process is device- and manufacturer-specific and changes often, so this guide won't walk through steps that go stale within months — search your exact device model for a current, reputable guide if you choose to pursue it.
Nothing here is required to start — a spare laptop and free software cover everything on this page. These make the learning curve smoother once you're hooked.
Some links on this page are affiliate links — if you buy through them we may earn a small commission at no extra cost to you. Replace the placeholder links above with your own Pretty Links before publishing.
This page covers the fundamentals; the KreatedByU forum is where full project walkthroughs live — installing a specific distro, building a specific server app, a full Android ROM flash, a real Python project from start to finish. The cards below are placeholders, ready to link out as tutorials get posted.
