Linux Fundamentals
Volume 5 — Platform Engineering
The Bash Reference chapter (Volume 1) covered the shell — the commands you type. This chapter is one level down: the operating system those commands run on. Every App Service Linux container, every Docker base image, and any Azure VM you'd manage all sit on some Linux distribution, and understanding the OS itself explains behavior the shell commands alone don't.
1. What "Linux" Actually Means
Strictly, "Linux" refers only to the kernel — the core program managing hardware, processes, and memory. A distribution ("distro") bundles that kernel with a package manager, standard utilities, and often a specific philosophy about how the system should be organized.
| Distribution family | Package manager | Common in |
|---|---|---|
| Debian / Ubuntu | apt | The base for most .NET/Node Docker images (mcr.microsoft.com/dotnet/aspnet is Debian-based by default) |
| Alpine | apk | Minimal container images — much smaller, but uses musl instead of glibc, which occasionally causes subtle compatibility issues with compiled dependencies |
| RHEL / CentOS / Fedora | yum / dnf | Common in enterprise on-prem environments, less common in container images |
Why this matters practically: a Dockerfile built on a Debian-based image and one built on Alpine can behave differently for the exact same application — different default shell (bash vs. ash), different available packages, and Alpine's musl libc has caused real, hard-to-diagnose issues for some compiled native dependencies that assume glibc. If a container behaves differently locally (OrbStack) vs. in Azure App Service, confirming both are actually using the same base image is a reasonable first check.
2. The Filesystem Hierarchy Standard (FHS)
Unlike Windows, Linux has one unified directory tree starting at /, with a conventional (not strictly enforced) structure most distributions follow:
| Path | Purpose |
|---|---|
/etc | System-wide configuration files |
/var | Variable data — logs (/var/log), caches, databases |
/home | User home directories |
/usr | User-installed programs and their data |
/usr/bin, /usr/local/bin | Executable programs |
/tmp | Temporary files, often cleared on reboot |
/opt | Optional/third-party software, often self-contained installs |
/proc | A virtual filesystem exposing live kernel/process information, not real files on disk |
/var/log is the single most important entry in this table for day-to-day debugging — application logs, system logs, and service logs conventionally live here (or are aggregated from here), and it's the first place to look on a Linux host or VM before assuming an application-level logging tool is the only source of truth.
3. Users, Groups, and Permissions at the OS Level
The Bash Reference chapter covered chmod mechanically; this is the model underneath it. Every file has exactly one owning user and one owning group, and permission checks happen in a fixed order: owner, then group, then everyone else — the first category that matches is the one whose permission bits apply, so being in the matching group can grant less access than the owner has, but a user is never checked against multiple categories at once.
whoami # current user
id # current user's UID, GID, and group memberships
cat /etc/passwd # list of all users on the system (or a summary, depending on config)
groups username # which groups a specific user belongs to
Root is the Linux superuser — UID 0, unrestricted by normal permission checks. sudo grants a normal user temporary root-equivalent access for a specific command, governed by rules in /etc/sudoers (edited with visudo, never directly, to avoid syntax errors locking out sudo entirely).
4. Processes and Init Systems
Every running program is a process, with a parent-child relationship tracing back to process ID 1 — the init system, the very first process the kernel starts, responsible for starting everything else.
systemd is the init system used by most modern distributions (Debian, Ubuntu, RHEL, Fedora) — it manages services, their startup order and dependencies, and their logs.
systemctl status nginx # check a service's current status
systemctl start nginx # start it
systemctl enable nginx # start it automatically on every future boot
journalctl -u nginx -f # follow that service's logs live
(This is covered in depth, with the full command set and a real unit file example, in the Linux Administration chapter.)
5. Package Managers
A package manager installs software along with its dependencies, and tracks what's installed for clean removal/upgrades later — the OS-level equivalent of npm/NuGet for applications.
# Debian/Ubuntu
apt update && apt install -y curl
# Alpine
apk add --no-cache curl
apt update refreshes the local package index from remote repositories — it does not itself install or upgrade anything; apt upgrade (separately) actually applies available updates. This two-step split is a common point of confusion for anyone used to a single combined command.
6. Environment Differences That Actually Bite
| Difference | Why it matters |
|---|---|
| glibc vs. musl (Debian/Ubuntu vs. Alpine) | Some compiled native dependencies assume glibc and fail or behave subtly differently under musl |
Default shell (bash vs. ash/sh) | A script relying on Bash-specific syntax can fail on Alpine's default minimal shell — #!/bin/sh and #!/bin/bash are not interchangeable if the script uses Bash-only features |
| Case sensitivity | Linux filesystems are case-sensitive by default (File.txt ≠ file.txt) — unlike macOS's default filesystem and Windows entirely, which is exactly why a project that "works fine" on a developer's Mac can fail in a Linux-based App Service or pipeline over an inconsistent import/file-reference casing |
Line endings (LF vs CRLF) | Windows-authored files can carry CRLF line endings that cause #!/bin/bash scripts to fail on Linux with a cryptic bad interpreter error — see the troubleshooting table below |
7. Troubleshooting Playbook
| Symptom | Likely cause | What to check |
|---|---|---|
| Import/file reference works on macOS, fails on Linux (App Service, pipeline) | Case-sensitivity mismatch — macOS's default filesystem is case-insensitive, Linux is not | Confirm every import/reference matches the actual file name's case exactly |
bad interpreter: /bin/bash^M: no such file or directory | Script has Windows-style CRLF line endings | Convert to Unix LF line endings (dos2unix scriptname.sh, or configure the editor/Git to use LF) |
Script works with bash script.sh, fails with ./script.sh on some systems | Shebang line missing, wrong, or the script isn't executable | Confirm #!/bin/bash is the first line and chmod +x has been applied |
| Package install fails, "unable to locate package" | Local package index is stale | apt update before apt install, not just the install command alone |
| Container behaves differently than expected between environments | Different base images (Debian vs. Alpine) between two supposedly equivalent Dockerfiles/environments | Confirm both actually use the same base image tag, not just a similar one |
| Log content that should exist is missing | Looking in the wrong location, or the application logs somewhere other than /var/log | Check the application's actual configured log destination — not every app writes to the FHS-conventional location |
8. Quick Reference
| Category | Item | Detail |
|---|---|---|
| Concept | Kernel vs. distribution | Linux is the kernel; a distro bundles it with tools and a package manager |
| Filesystem | /var/log | Conventional location for system and application logs |
| Filesystem | /etc | System-wide configuration |
| Users | sudo | Temporary root-equivalent access for a specific command |
| Users | visudo | The only safe way to edit sudo rules |
| Init | systemd | The modern init system managing services on most distros |
| Init | systemctl / journalctl | Manage and inspect services and their logs |
| Package manager | apt (Debian/Ubuntu) | apt update && apt install |
| Package manager | apk (Alpine) | apk add --no-cache |
| Gotcha | glibc vs. musl | Alpine's musl can break glibc-assuming compiled dependencies |
| Gotcha | Case sensitivity | Linux is case-sensitive; macOS default filesystem is not |
Part of the Traxs Engineering Handbook — Volume 5: Platform Engineering. Companion chapters in this volume: Linux Administration, Kubernetes Fundamentals, CI/CD, Observability, Secrets Management.