Most backend and DevOps work eventually comes down to a terminal on a Linux box at 2am, and the gap between "I can use Linux" and "I can actually troubleshoot Linux under pressure" is exactly the gap that matters in that moment. This isn't a general Linux tutorial — it's the specific, practical subset that backend and DevOps engineers actually reach for, organized around real troubleshooting, not command trivia.
The filesystem hierarchy, functionally
You don't need to memorize the entire FHS, but knowing where things actually live saves real time: /etc for configuration, /var/log for logs (and /var in general for variable, growing data — which is exactly why a full disk is so often a /var problem), /usr for installed software, /opt for third-party applications that don't fit the standard layout, /tmp for exactly what it sounds like (and exactly why you shouldn't rely on anything there surviving a reboot). When a service won't start, /etc/<service>/ and /var/log/<service>/ are almost always your first two stops, before anything more exotic.
Process management: systemd, properly
systemctl status <service> is the starting point for almost every "why isn't this working" investigation — it tells you if a service is running, when it last restarted, and (often) the last few log lines that explain why. systemctl restart, enable/disable (controls whether it starts on boot, separate from whether it's running now — a common point of confusion), and journalctl -u <service> -f for following logs live are the daily-driver commands. Understanding unit files (/etc/systemd/system/*.service) — what starts a service, what user it runs as, what it depends on — turns "restart it and hope" into actually understanding why it stopped.
Process and resource inspection under pressure
top/htop for a live view, but ps aux --sort=-%mem (or -%cpu) when you need a static snapshot to actually read carefully rather than watching numbers scroll. free -h for memory (and understanding that Linux using "available" memory for disk cache isn't the same as being low on memory — a genuinely common misread). df -h for disk space, du -sh */ to find what's actually consuming it when df says a partition is full but you're not sure why. iostat/vmstat when the bottleneck might be I/O, not CPU or memory — a distinction that changes what you fix entirely.
Networking troubleshooting, the actual sequence
When something can't connect, working through layers in order saves time versus guessing:
- Is the service even listening?
ss -tlnp(the modern replacement fornetstat -tlnp) shows what's bound to what port, and as which process. - Can you reach it locally?
curl localhost:<port>from the box itself rules out the application layer before blaming the network. - Is a firewall involved?
iptables -Lorufw status(depending on the distro) — a huge share of "it's not connecting" issues are a firewall rule, not the application. - Is DNS resolving correctly?
dig <hostname>ornslookup— and if you're not confident on what a DNS record actually does at this point, DNS Records Explained for Hosting Engineers covers exactly this. - Is the route actually working end to end?
traceroute/mtrfor anything that looks like a network path problem rather than a single-hop issue.
This order matters — checking DNS before confirming the service is even listening locally is a common way to waste twenty minutes chasing the wrong layer.
Logs: centralizing the search, not just reading files
tail -f and grep are fine for a single server, but the moment you have more than one, that approach stops scaling — you end up SSHing into boxes one at a time hoping you land on the right one. journalctl centralizes systemd-managed service logs per-host reasonably well; for anything spanning multiple servers, a real log aggregation setup (however lightweight) pays for itself the first time an incident spans more than one machine. This is the same principle from DevOps Roadmap 2026's observability stage — centralized logging is usually the first piece worth building, before metrics or tracing.
Permissions: the part everyone half-understands
rwx for owner/group/other is the basic model, but the parts that actually trip people up in practice: the difference between a file permission and a directory permission (execute on a directory means "can list/traverse it," not "can run it"), chmod numeric notation actually mapping to those three permission groups (755 = owner rwx, group r-x, other r-x), and chown/chgrp for ownership. The mistake I see most often: reflexively running chmod 777 to make a permissions error go away, which fixes the symptom while creating a real security problem — take the extra thirty seconds to figure out which specific permission was actually missing.
Package management, by distro family
Debian/Ubuntu: apt. RHEL/CentOS/Rocky/AlmaLinux: dnf (or the older yum). Knowing which family you're on matters beyond just command syntax — package names, default configurations, and even filesystem layout conventions differ meaningfully between them. If you support both (common in hosting environments running a mix of client environments), keep a small mental map of the equivalent commands rather than guessing and hoping the syntax transfers.
Shell scripting: enough to actually be useful
You don't need to be a Bash wizard, but a few habits separate scripts that work reliably from ones that fail silently at 3am: set -euo pipefail at the top of every script (exit on error, treat unset variables as errors, fail a pipeline if any command in it fails — without this, a script can silently continue after a real failure and cause more damage). Quote your variables ("$var", not $var — unquoted variables break in exactly the situations you can least afford, like filenames with spaces). Check exit codes explicitly for anything that matters, rather than assuming success.
Cron and scheduled tasks, done safely
Crontab entries with no logging and no failure notification are a classic silent-failure trap — a backup job that's been failing for three weeks with nobody noticing, discovered only when you actually need that backup. At minimum: redirect output to a log file, and ideally alert on failure (even something as simple as a script that checks the previous run's exit code and sends a notification). crontab -l to review what's actually scheduled on a box you've inherited is always worth doing early — undocumented cron jobs are a recurring source of "why does this happen every night at 3am" mysteries.
SSH and remote access, the parts that matter for security
Key-based authentication over passwords, always — this connects directly to the RDP-equivalent concerns in Windows Server Hardening Checklist, just the Linux side of the same principle: don't expose password-based remote access to the internet. ~/.ssh/config for managing multiple hosts sanely (aliases, specific keys per host, jump-host configuration) instead of remembering long commands. Fail2ban or an equivalent for anything internet-facing, to blunt automated brute-force attempts the same way you would on a Windows RDP endpoint.
The habit that matters more than any single command
Reading man pages and --help output before reaching for a random Stack Overflow snippet builds a real, durable mental model over time, instead of a growing pile of memorized incantations you don't fully understand and can't adapt when the situation is slightly different from the one the snippet was written for. The commands above will change syntax slightly across distros and years; the underlying habit of actually understanding what you're running, and why, is what transfers.
Frequently asked questions
Which Linux distribution should I actually learn first? Ubuntu Server or Debian if you're not sure — the largest share of tutorials, Docker base images, and cloud provider defaults target Debian-family systems, so you'll hit less friction learning on one. Once comfortable, picking up RHEL-family differences (dnf instead of apt, SELinux instead of AppArmor, different default file layouts in places) is a much smaller jump than starting from zero on either.
Is it still worth learning traditional Linux administration if everything is containers now? Yes, and this trips people up — containers still run on a Linux kernel, and debugging a container that's misbehaving (a networking issue, a permissions problem, a resource limit being hit) draws directly on exactly the fundamentals in this article. "Everything is containerized" changes where you apply Linux knowledge, not whether you need it.
What's the fastest way to get comfortable with the command line if I'm coming from a GUI-only background? Force yourself to solve real, current problems on the command line instead of falling back to a GUI tool or a pre-written script you don't fully understand — the discomfort of looking up a command mid-task, repeatedly, for real problems you actually have, builds retention far faster than working through a generic tutorial's practice exercises.
Do I need to memorize all these commands, or is it fine to look them up each time? Looking up exact flags is completely normal and doesn't indicate a gap — even experienced engineers check man pages regularly. What matters is knowing which command solves which kind of problem (the troubleshooting sequence in this article, for instance) well enough that you're not starting from zero when something breaks. The specific flags are a lookup; the mental map of "networking problem → check these things in this order" is the actual skill.