Linux Roadmap
Linux runs most of the world's servers, cloud machines and containers, so back-end developers, DevOps and site reliability engineers, data engineers and security staff all work on it every day. Interviews for these roles often include Linux questions: what happens when you run a command, how permissions work, how to find what is filling a disk, or how to debug a service that will not start.
This roadmap takes you from your first terminal session to the skills of someone who can run and troubleshoot production servers. It covers the filesystem, text processing, users and permissions, processes, packages and systemd, storage, networking, scripting and a methodical approach to incidents. Each topic explains the idea, shows the commands and ends with an exercise. Core topics are expected of everyone; recommended ones of most working engineers; optional ones are good to know.
Practise on a virtual machine you are happy to break and rebuild.
- Level
- Beginner to advanced
- Time
- 10–14 weeks at about 6 hours a week
- Scope
- 59 topics in 9 stages
- Before you start
- A computer that can run a Linux virtual machine, WSL or a small cloud server; No programming experience needed, though basic scripting helps; the Shell and Bash Roadmap pairs well with this one
What you will be able to do
- Work comfortably in the terminal: navigate, manage files, edit configuration and read documentation.
- Process logs and text with pipes, grep, AWK, sed and the standard text tools.
- Manage users, groups, permissions and sudo access securely.
- Inspect and control processes, priorities and resource limits, and run applications as systemd services.
- Add and grow storage, and diagnose disk, memory and network problems.
- Debug a misbehaving server methodically and explain how containers are built from Linux features.
The roadmap at a glance
- Stage 1Getting Around the SystemBeginner · 1–2 weeks · 8 topics
- Stage 2Streams and Text ProcessingBeginner · 1–2 weeks · 8 topics
- Stage 3Users, Groups and PermissionsBeginner · 1 week · 4 topics
- Stage 4Processes and Resource LimitsIntermediate · 1–2 weeks · 7 topics
- Stage 5Packages, Boot and ServicesIntermediate · 1–2 weeks · 7 topics
- Stage 6Disks, Filesystems and MemoryIntermediate · 1–2 weeks · 5 topics
- Stage 7NetworkingIntermediate · 2 weeks · 10 topics
- Stage 8Shell Programming for AdministratorsIntermediate · 1–2 weeks · 5 topics
- Stage 9Troubleshooting, Containers and Server ReviewAdvanced · 2 weeks · 5 topics
Stage 1 Getting Around the System
Goal. Move around the filesystem, manage files and edit configuration from a terminal.
What Linux Is and How to Practise Core
Linux is a kernel, the core program that manages hardware, memory and processes. A distribution such as Ubuntu, Debian, Fedora, Rocky Linux or Alpine bundles that kernel with tools, a package manager and defaults. Most servers, containers, cloud machines and Android phones run Linux, so nearly every back-end, DevOps and data role touches it.
Practise on a real system: a virtual machine, WSL on Windows, a cheap cloud server or a container. Choose one Debian-family and one Red Hat-family distribution over time, because their package tools and some file locations differ. Everything in this roadmap runs in a terminal, so get used to working without a desktop.
Practice. Install Ubuntu in a virtual machine or WSL and log in to its terminal.
Shell Basics and Command Help Core
The shell, usually Bash, reads a command line, splits it into a command and arguments, and runs it. Options change behaviour: short ones like -l combine as -la, long ones look like --all.
Command help is always on the machine, so learn to use it instead of guessing.
man ls # full manual page; / searches, q quits
ls --help # quick summary
man -k partition # search manual descriptions
type cd # builtin, alias or file?
history | tail # recent commands; Ctrl+R searchesTab completion finishes names, the up arrow recalls commands, and Ctrl+C stops the running one. The Shell and Bash Roadmap covers the shell itself in depth.
Practice. Use man to find the ls option that sorts by modification time, without searching online.
Understanding Directory Hierarchy Core
Linux has a single tree starting at /, with no drive letters; disks are attached into the tree. The layout follows a shared standard, so you can find things on any distribution.
| Path | Holds |
|---|---|
/etc | System configuration |
/home, /root | User homes, the root user's home |
/var | Changing data: logs, caches, spools |
/usr | Installed programs and libraries |
/tmp | Temporary files, often cleared at boot |
/dev, /proc, /sys | Devices and kernel views as files |
/opt, /srv | Add-on software, served data |
On modern distributions /bin and /sbin are links into /usr.
Practice. Find where your system keeps SSH server configuration, its logs and the ssh binary.
Working with Files Core
Creating files, copying and renaming files, moving files and deleting them are daily work.
touch notes.txt # create empty file or update its time
mkdir -p app/config/dev # create nested directories
cp -r app app-backup # copy a directory recursively
cp -a src/ dest/ # keep permissions and times
mv draft.txt final.txt # rename
mv final.txt ~/docs/ # move
rm -r old-dir # delete, no recycle bin
rm -i *.log # ask before eachThere is no undo for rm. Check what a wildcard matches with ls before deleting, and be very careful with rm -rf as root. file name tells you what a file contains regardless of its extension.
Practice. Build a small project tree, copy it with attributes preserved, rename two files and remove the copy.
Inodes, Soft and Hard Links Core
An inode stores a file's metadata: owner, permissions, size, times and where its data blocks are. It does not store the name; directories map names to inode numbers. ls -i shows them, and df -i shows how many are free. A disk can run out of inodes with plenty of space left when millions of tiny files exist.
ln data.csv data-hard.csv # hard link: same inode
ln -s /opt/app/current app # soft (symbolic) link: a path
ls -liSoft and hard links differ: a hard link is a second name for the same inode, and the data survives until the last name is removed; it cannot cross filesystems or point to directories. A symbolic link stores a path, can point anywhere, and breaks if the target moves.
Practice. Create a hard link and a symlink to one file, delete the original, and explain what each link shows.
Editing Files Core
You will edit configuration on servers with no graphical editor, so learn one terminal editor well and the basics of another.
Nano: a file editing tool for beginners. Shortcuts appear at the bottom: Ctrl+O saves, Ctrl+X exits, Ctrl+W searches.
Vim: an essential tool for editing files, present on almost every server. It is modal: normal mode for moving and commands, insert mode for typing.
i insert before cursor Esc back to normal mode
:w save :q! quit without saving
:wq save and quit /err search forward
dd delete line u undo
:%s/old/new/g replace in whole file
Practice. Edit a copy of a config file in Vim: search, replace a value, delete a line and save, without the mouse.
Archiving and Compressing Core
Archiving bundles many files into one; compressing makes data smaller. tar archives and can compress in the same step.
tar -czf site.tar.gz site/ # create, gzip
tar -cJf logs.tar.xz /var/log/app # create, xz (smaller, slower)
tar -tzf site.tar.gz # list contents
tar -xzf site.tar.gz -C /srv # extract into /srv
gzip big.log; gunzip big.log.gz
zip -r site.zip site/; unzip site.zipRemember the flags as c for create, x for extract, t for list, f for the file name, and z, j or J for gzip, bzip2 or xz. Use zip when sharing with Windows users.
Practice. Archive and compress a directory with gzip and xz, compare sizes, then extract one file only.
Stage 2 Streams and Text Processing
Goal. Combine small tools with pipes and redirects to search, filter and summarise text and logs.
Stdout, Stdin, and Stderr Core
Every process starts with three open streams: standard input, file descriptor 0, where it reads; standard output, descriptor 1, for normal results; and standard error, descriptor 2, for errors and diagnostics. By default all three are connected to your terminal.
Keeping errors on a separate stream is deliberate: you can send results to a file or the next program while still seeing errors on screen. Well-behaved programs also return an exit status, 0 for success and anything else for failure, which scripts check with $?.
Practice. Run a command that prints both output and errors, and send each stream to a different file.
Redirects Core
Redirects connect streams to files.
ls /etc > list.txt # stdout to file (overwrite)
echo done >> list.txt # append
sort < names.txt # stdin from file
find / -name x 2> /dev/null # discard errors
cmd > all.log 2>&1 # stdout and stderr to one file
cmd &> all.log # Bash shorthand for the sameOrder matters: 2>&1 means "send stderr where stdout points now", so it must come after the stdout redirect. /dev/null swallows anything written to it. A here document, <<EOF, feeds several lines of text to a command's input.
Practice. Run a find over / as a normal user, saving results to one file and permission errors to another.
Pipe Commands and Tee Core
A pipe, |, connects one command's stdout to the next command's stdin, so small tools combine into a processing line. Commands in a pipeline run at the same time, streaming data, so even huge files use little memory.
ps aux | grep nginx | wc -l
cat access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head
make 2>&1 | tee build.log # see output and save it
echo "10.0.0.5 db" | sudo tee -a /etc/hostsTee copies its input to a file and to stdout, which is handy for logging. The last example shows a common trick: sudo echo x > file fails because the redirect runs as you, but piping into sudo tee writes as root.
Practice. Find the ten most frequent IP addresses in a web server access log with one pipeline.
Viewing Files: Head Command, Tail Command and Less Core
For text files, cat prints everything, less pages through large files with search, and the head command and tail command show the start or end.
head -n 20 app.log
tail -n 50 app.log
tail -f /var/log/nginx/error.log # follow new lines live
tail -F app.log # keep following after rotation
less +G app.log # open at the end; / to searchtail -f is the classic way to watch a log while you reproduce a problem. In less, Shift+F follows the file too, and you can stop following to scroll back.
Practice. Follow a log with tail -F while generating entries in another terminal, then search it in less.
Text Processing Tools Core
Linux ships many small text processing tools. Know what each does so you reach for the right one.
- Cut command: extract fields,
cut -d: -f1 /etc/passwd. - Paste: join lines of files side by side.
- Sort: order lines,
-nnumeric,-k2by field,-rreverse. - Uniq: collapse adjacent duplicates,
-ccounts; sort first. - WC - text processing counts:
wc -llines,-wwords. - Tr-command: translate or delete characters,
tr a-z A-Z. - NL (number lines): number the lines of a file.
- Expand and unexpand: convert tabs to spaces and back.
- Join command: merge two sorted files on a common field, like a database join.
- Split command: break a big file into pieces,
split -l 100000 big.csv part_.
Practice. Using only these tools, produce a count of users per login shell from /etc/passwd.
GREP Core
grep prints lines matching a pattern, and is the tool you will use most for searching logs and code.
grep -i "error" app.log # ignore case
grep -rn "TODO" src/ # recursive, with line numbers
grep -v "healthcheck" access.log # invert match
grep -E "5[0-9]{2} " access.log # extended regex: 5xx codes
grep -c "timeout" app.log # count matches
grep -A3 -B2 "Traceback" app.log # lines after and beforeBasic patterns use . for any character, * for repeats, ^ and $ for line start and end, and brackets for character sets. Quote patterns so the shell does not expand them. Tools such as ripgrep are faster for code, but grep is everywhere.
Practice. Show every 5xx response from an access log with two lines of context, excluding health checks.
AWK and sed Recommended
AWK is a small language for field-based text. It splits each line into fields $1, $2 and so on, and runs actions for lines that match a pattern.
awk '{print $1, $9}' access.log # IP and status
awk -F: '$3 >= 1000 {print $1}' /etc/passwd # real users
awk '{sum += $10} END {print sum/NR}' access.log
sed -n '10,20p' app.log # print lines 10-20
sed -i 's/debug=true/debug=false/' app.conf # edit in placesed, the stream editor, is best for substitutions and line ranges; AWK for columns, sums and simple reports. Keep a backup or use sed -i.bak when editing files in place.
Practice. Compute the average response size per status code from an access log with AWK.
Environment Variables and the Command Path in Shell Core
Environment variables are name-value pairs passed from a process to its children. Programs read them for configuration such as HOME, USER, LANG or an application's database URL.
echo "$PATH"
export APP_ENV=staging # visible to child processes
env | sort # list environment
which python3; type -a python3
export PATH="$HOME/.local/bin:$PATH"The command path in shell lookup works through PATH, a colon-separated list of directories searched left to right for a command name. If the wrong version runs, check type -a. Make settings permanent in ~/.bashrc or ~/.profile; system-wide ones go in /etc/environment or /etc/profile.d/.
Practice. Install a script into ~/.local/bin, add it to PATH permanently and confirm which copy runs.
Stage 3 Users, Groups and Permissions
Goal. Manage accounts and control who can read, change and run each file.
Users and Groups Core
Every process runs as a user, and every file is owned by a user and a group. Users have a numeric ID; root is UID 0 and can do anything. System accounts such as www-data or postgres run services with limited rights.
id # your UID, GID and groups
whoami
getent passwd asha # account entry
groups ashaAccounts are listed in /etc/passwd, password hashes in /etc/shadow, readable only by root, and groups in /etc/group. A user has one primary group plus supplementary groups, which is how you share access: put people in a group and give the group rights.
Practice. List all human accounts on your system and the groups each belongs to.
Create, Update, and Delete Users Core
User management uses a small set of commands, run as root or with sudo.
sudo useradd -m -s /bin/bash -G developers asha # create with home
sudo passwd asha
sudo usermod -aG docker asha # add group; -a is vital
sudo usermod -L asha # lock account
sudo userdel -r olduser # delete with home
sudo groupadd developers
sudo chage -l asha # password ageingWithout -a, usermod -G replaces every supplementary group, a classic mistake. Debian-family systems also offer the friendlier adduser. Group changes take effect at the next login.
Practice. Create a developers group and two users in it, lock one account, then delete it with its home.
File Permissions Core
Each file has permissions for three classes: owner, group and others. Each class has read, write and execute bits. On directories, read lists names, write creates and deletes entries, and execute allows entering it.
ls -l deploy.sh # -rwxr-x--- 1 asha devs ...
chmod 750 deploy.sh # rwx r-x ---
chmod u+x,g-w script.sh
chown asha:devs deploy.sh
chmod -R g+rX shared/ # X: execute only for dirs
umask # default bits removed, often 022In octal, read is 4, write 2 and execute 1, summed per class. Special bits exist too: setuid runs a program as its owner, setgid on a directory makes new files inherit the group, and the sticky bit on /tmp stops users deleting each other's files.
Practice. Set up a shared directory where a group can create files that other members can edit but outsiders cannot read.
Super User Core
The super user, root, bypasses permission checks. Logging in as root is risky because one typo can damage the whole system, so administrators use sudo to run individual commands with elevated rights and leave an audit trail in the logs.
sudo systemctl restart nginx
sudo -i # root shell, use sparingly
sudo -l # what am I allowed to run?
sudo visudo # edit /etc/sudoers safelyWho may use sudo is set in /etc/sudoers and files under /etc/sudoers.d/, usually by membership of the sudo or wheel group. Always edit with visudo, which checks syntax; a broken sudoers file can lock you out of admin access.
Practice. Give a user permission to restart one specific service with sudo and nothing else.
Stage 4 Processes and Resource Limits
Goal. Inspect, control and prioritise running programs and limit what they can consume.
Process Management Basics and Process Forking Core
A process is a running program with its own memory, a process ID (PID), a parent, an owner and open files. New processes are created by process forking: a parent calls fork to copy itself, and the child usually calls exec to replace itself with a new program. This is how your shell starts every command.
PID 1, normally systemd, is the ancestor of everything and adopts orphans. When a child exits, its parent must collect its exit status; until then it is a zombie, which uses no memory but holds a PID. Many zombies point to a buggy parent. Threads are scheduled units inside a process that share its memory.
Practice. Use pstree to draw the process tree from PID 1 to your current shell.
Listing and Finding Processes Core
ps aux # all processes, user format
ps -ef --forest # with parent relationships
ps -o pid,ppid,%cpu,%mem,cmd -p 1234
pgrep -a nginx # find by name
top # live view; P cpu, M memory
htop # friendlier, if installed
ls /proc/1234/ # the kernel's view of one processIn ps output, the STAT column matters: R running, S sleeping, D uninterruptible sleep, usually waiting for disk or network storage, Z zombie and T stopped. Many processes stuck in D state often mean an I/O problem. /proc exposes each process's command line, environment, open files and limits as files.
Practice. Find the process using the most memory, its parent, and the command line that started it.
Background and Foreground Processes Core
A command normally runs in the foreground and holds your terminal. Add & to start it in the background, or stop a running job with Ctrl+Z and resume it elsewhere.
./long-task.sh &
jobs # list this shell's jobs
fg %1 # bring job 1 to the foreground
bg %1 # continue a stopped job in background
nohup ./task.sh > task.log 2>&1 & # survive logout
disown %1Jobs belong to your shell session and usually die when you log out. nohup or disown keep them alive, and tmux or screen keep whole sessions you can reattach to. Anything that must run permanently should be a service instead.
Practice. Start a long command, suspend it, move it to the background, then log out and confirm whether it survived with and without nohup.
Process Signals and Kill Processes Core
Signals are short messages the kernel delivers to a process. Common process signals: SIGTERM (15) politely asks a program to exit, SIGKILL (9) ends it at once and cannot be caught, SIGINT (2) is Ctrl+C, SIGHUP (1) often means reload configuration, and SIGSTOP and SIGCONT pause and resume.
kill 1234 # SIGTERM
kill -HUP 1234 # reload
kill -9 1234 # last resort
pkill -f "worker.py"
killall nginxTo kill processes, always try SIGTERM first so the program can flush data and remove lock files; SIGKILL skips all clean-up. A process in D state may ignore even SIGKILL until its I/O finishes.
Practice. Write a script that traps SIGTERM to print a message before exiting, then stop it with kill and with kill -9.
Process Priorities Recommended
The scheduler shares CPU time between runnable processes. Process priorities are adjusted with a niceness from -20, highest priority, to 19, lowest. Ordinary users can only make their processes nicer; lowering niceness needs root.
nice -n 10 ./backup.sh # start with lower priority
renice -n 5 -p 1234 # change a running process
ionice -c3 tar -czf b.tgz /data # idle I/O priorityUse these for batch jobs such as backups and reports, so they do not slow interactive services. The NI column in top shows the value. For hard limits on CPU share rather than priority, use cgroups.
Practice. Run two CPU-heavy loops at different nice values and compare their CPU share in top.
Ulimits Recommended
Ulimits are per-process resource limits set by the shell or service manager: open files, number of processes, core dump size, stack size and more. Each has a soft limit, the current value, and a hard limit, the ceiling a user can raise it to.
ulimit -a # show all
ulimit -n # open files, often 1024
ulimit -n 65535 # raise soft limit for this shell
cat /proc/1234/limits"Too many open files" errors on busy databases or web servers mean the open-file limit is too low. Set permanent limits in /etc/security/limits.conf for login sessions, or with LimitNOFILE= in a systemd unit for services, since services do not read limits.conf.
Practice. Check the open-file limit of a running service via /proc and raise it in its systemd unit.
Cgroups Recommended
Control groups, cgroups, are a kernel feature that groups processes and limits, accounts for and isolates their use of CPU, memory, I/O and process count. Modern systems use cgroup v2, a single unified hierarchy under /sys/fs/cgroup.
systemd places every service in its own cgroup, so you can limit a service with directives such as MemoryMax= and CPUQuota=, and see usage with systemd-cgtop. Containers use cgroups for their memory and CPU limits; when a container exceeds its memory limit, the kernel's out-of-memory killer ends a process inside it.
systemd-run --scope -p MemoryMax=200M ./hungry-app
cat /sys/fs/cgroup/system.slice/nginx.service/memory.current
Practice. Run a memory-hungry program under a 200 MB limit with systemd-run and observe it being killed.
Stage 5 Packages, Boot and Services
Goal. Install software safely, understand the boot process and run, inspect and create services with systemd.
Package Management and Repositories Core
Package management installs software with its dependencies, verifies signatures and handles upgrades and removal. Packages come from repositories, signed servers listed in your system's configuration.
| Task | Debian, Ubuntu | Fedora, RHEL |
|---|---|---|
| Refresh index | apt update | dnf makecache |
| Install | apt install nginx | dnf install nginx |
| Remove | apt remove nginx | dnf remove nginx |
| Upgrade all | apt upgrade | dnf upgrade |
| Search | apt search | dnf search |
Repositories live in /etc/apt/sources.list.d/ or /etc/yum.repos.d/. Only add third-party repositories you trust, with their signing key. yum is the older name for dnf.
Practice. Add a vendor repository with its signing key on a test machine and install a package from it.
Finding, Installing and Listing Installed Packages Core
Finding and installing packages starts with search and inspection before you install.
apt search ripgrep
apt show ripgrep # version, size, dependencies
apt list --installed | grep ssl # listing installed packages
dpkg -L openssh-server # files a package installed
dpkg -S /usr/sbin/sshd # which package owns a file
rpm -qa | sort # list on RHEL family
rpm -qf /usr/sbin/sshdTo install, remove, and upgrade packages safely on servers, read what an upgrade will change, prefer the distribution's packages for system tools, and pin versions where an upgrade could break an application. apt autoremove cleans up dependencies no longer needed.
Practice. Find which package owns the curl binary, list its files and check what upgrading it would change.
Snap and Other Universal Formats Optional
Snap, Flatpak and AppImage package an application with its own dependencies, so one build runs on many distributions. Snap is developed by Canonical and is built into Ubuntu, where some programs are installed as snaps by default; Flatpak is common for desktop apps elsewhere.
snap find postman
sudo snap install postman
snap list
sudo snap refreshThe trade-off: newer versions and isolation, against bigger downloads, slower start-up and automatic updates you control less. On servers, most teams prefer distribution packages or containers.
Practice. Install one tool as a snap and as a distribution package, and compare size and version.
Booting Linux and Boot Loaders Recommended
Booting Linux goes through several stages. Firmware, UEFI on modern machines, initialises hardware and starts a boot loader. Boot loaders such as GRUB let you choose a kernel and pass it options, then load the kernel and an initial RAM filesystem, initramfs, which contains drivers needed to mount the real root filesystem. The kernel then starts PID 1, usually systemd, which brings up services in dependency order until it reaches its target, such as a multi-user server or graphical desktop.
systemd-analyze blame # slowest units at boot
journalctl -b -1 -p err # errors from the previous boot
cat /proc/cmdline # kernel parametersKnowing the stages tells you where to look when a machine will not boot.
Practice. Find the three slowest units at boot on your system and the kernel parameters it booted with.
Service Management with systemd Core
Service management on almost all current distributions uses systemd. A unit describes something systemd manages, most often a service. Running services, checking service status and starting/stopping services all go through systemctl.
systemctl status nginx
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # re-read config, no downtime
sudo systemctl enable --now nginx # start now and at boot
systemctl list-units --type=service --state=failed
systemctl is-active nginxEnable controls boot behaviour; start controls now. Status shows whether the service is running, its main PID, cgroup and the last log lines, which is usually the first place to look when something is down.
Practice. Stop, start and disable a service, reboot, and confirm its state after boot.
Creating Services Core
Creating services means writing a unit file so systemd starts your program at boot, restarts it on failure and logs its output.
# /etc/systemd/system/api.service
[Unit]
Description=Orders API
After=network-online.target
[Service]
User=api
WorkingDirectory=/srv/api
EnvironmentFile=/etc/api.env
ExecStart=/srv/api/bin/server --port 8080
Restart=on-failure
[Install]
WantedBy=multi-user.targetAfter editing, run systemctl daemon-reload, then enable --now. Run as a dedicated non-root user. Use systemctl edit to add overrides to packaged units instead of editing them. systemd timers can replace cron jobs, with logging included.
Practice. Turn a small web server script into a systemd service that restarts on failure and survives reboot.
System Logs Core
Systemd's journal collects logs from the kernel, services and boot. Many systems also write classic text system logs under /var/log, such as syslog or messages.
journalctl -u nginx --since "1 hour ago" # checking service logs
journalctl -u api -f # follow
journalctl -p err -b # errors this boot
journalctl -k # kernel messages
dmesg -T | tail # kernel ring bufferAuthentication logs record logins, sudo use and SSH attempts, in /var/log/auth.log on Debian-family systems and /var/log/secure on Red Hat-family ones, or journalctl -u ssh. Log rotation with logrotate stops log files filling the disk.
Practice. Find all failed SSH login attempts on a server in the last day and the IP addresses they came from.
Stage 6 Disks, Filesystems and Memory
Goal. Add and mount storage, grow volumes and diagnose space and memory problems.
Disks and Filesystems Core
A disk is divided into partitions, each formatted with a filesystem that organises files and metadata. Common filesystems are ext4, the long-standing default; XFS, the default on Red Hat-family systems and good for large files; and Btrfs, with snapshots and checksums. Disks appear as device files such as /dev/sda or /dev/nvme0n1.
lsblk -f # disks, partitions, filesystems, mounts
blkid # UUIDs and types
sudo fdisk -l
findmntRefer to filesystems by UUID in configuration, because device names can change between boots.
Practice. Map every disk, partition and mount point on your machine with lsblk -f.
Mounts and Adding Disks Core
Mounts attach a filesystem to a directory in the tree. Adding disks to a server, such as a new cloud volume, follows the same steps each time.
sudo parted /dev/sdb mklabel gpt mkpart data ext4 0% 100%
sudo mkfs.ext4 /dev/sdb1
sudo mkdir /data && sudo mount /dev/sdb1 /data
# make it permanent in /etc/fstab:
UUID=3f2a... /data ext4 defaults,nofail 0 2
sudo mount -a # test fstab before rebootingA mistake in /etc/fstab can stop a machine booting, so test with mount -a and use nofail for non-essential disks. umount fails with "target is busy" while a process uses the mount; lsof +D /data finds it.
Practice. Attach a second virtual disk, partition, format and mount it permanently by UUID.
LVM (Logical Volume Manager) Recommended
LVM adds a flexible layer between disks and filesystems. Physical volumes, disks or partitions, are pooled into a volume group, from which you carve logical volumes that act like partitions but can grow, span disks and take snapshots.
sudo pvcreate /dev/sdc
sudo vgextend vg_data /dev/sdc
sudo lvextend -r -L +50G /dev/vg_data/lv_app # -r grows the filesystem too
sudo pvs; sudo vgs; sudo lvsThis is why LVM is popular on servers: when a volume fills, you add a disk and grow it online. ext4 and XFS can grow while mounted; XFS cannot shrink.
Practice. Create a volume group from two virtual disks, a logical volume on it, and grow it while mounted.
Available Memory and Disk Core
Checking available memory and disk is the first step in many incidents.
df -h # space per filesystem
df -i # inodes per filesystem
du -sh /var/* | sort -h | tail # biggest directories
free -h # memory and swap
vmstat 1 5 # memory, swap, I/O, CPU each secondIn free, look at the available column, not free. Linux uses spare memory as page cache to speed up disk access and gives it back when programs need it, so low free memory is normal. If df says a disk is full but du finds less, a deleted file is probably still held open; lsof +L1 lists such files.
Practice. Fill a test filesystem, find what used the space, and reproduce the deleted-but-open file case.
Swap Space Recommended
Swap space is disk used as overflow when RAM is full. The kernel moves rarely used memory pages there, freeing RAM for active work. It prevents sudden out-of-memory kills but is far slower than RAM, so heavy swapping makes a system crawl.
swapon --show
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
cat /proc/sys/vm/swappinessSwappiness controls how eagerly the kernel swaps. Watch the si and so columns in vmstat: constant swap activity means you need more memory or a smaller workload. Kubernetes nodes traditionally run without swap.
Practice. Add a 1 GB swap file, make it permanent, and watch vmstat while a program uses more memory than the RAM.
Stage 7 Networking
Goal. Configure and debug network connections, from addresses and routes to DNS, ports, firewalls and packets.
TCP/IP Basics Core
Networking on Linux follows the TCP/IP model. The link layer moves frames on the local network. IP gives each host an address and routes packets between networks. TCP adds reliable, ordered connections with a three-way handshake, and UDP sends independent datagrams with no delivery guarantee. Applications such as HTTP, DNS and SSH sit on top, identified by port numbers.
ip addr # interfaces and addresses
ip link # link state
ip -br a # brief viewThe older ifconfig from net-tools is deprecated on most distributions; learn the ip command.
Practice. List your interfaces, their IPv4 and IPv6 addresses and which one carries your default route.
Ethernet, ARP and RARP Recommended
On a local network, frames are delivered by MAC address, a hardware address on each network interface. Ethernet is the common link layer for wired networks, and Wi-Fi behaves similarly.
ARP, the Address Resolution Protocol, finds the MAC address that owns an IPv4 address on the same network: a host broadcasts "who has 10.0.0.1?" and the owner replies. Results are cached in the neighbour table. RARP did the reverse, mapping a MAC address to an IP address for diskless machines, and has long been replaced by DHCP. IPv6 uses Neighbour Discovery instead of ARP.
ip neigh # ARP and neighbour cache
Practice. Ping your gateway, then show its MAC address in the neighbour table.
Subnetting and IP Routing Core
An address such as 192.168.10.25/24 has a prefix length: the first 24 bits name the network and the rest the host. A /24 holds 256 addresses, 254 usable; a /26 holds 64. Subnetting divides a block into smaller networks. Private ranges are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
IP routing decides where each packet goes: hosts on the same subnet are reached directly, and everything else goes to the matching route, usually the default gateway.
ip route
# default via 192.168.10.1 dev eth0
ip route get 8.8.8.8 # which route a destination uses
sudo ip route add 10.20.0.0/16 via 192.168.10.254
Practice. Split 10.0.0.0/24 into four subnets by hand, then check which route your machine uses for an outside address.
DHCP Recommended
DHCP gives a machine its network settings automatically when it joins a network: an IP address with a lease time, subnet mask, default gateway and DNS servers. The client broadcasts a request, a server offers an address, the client asks for it and the server acknowledges.
Servers usually have static addresses or DHCP reservations so their address never changes. On modern systems, network configuration is managed by NetworkManager (nmcli), systemd-networkd or, on Ubuntu servers, netplan YAML files that generate their configuration.
nmcli device show eth0
cat /etc/netplan/*.yaml
Practice. Find your current lease's DNS servers and gateway, then configure a static address on a test VM.
DNS Resolution Core
DNS resolution turns names into addresses. On Linux, the order is set in /etc/nsswitch.conf: usually /etc/hosts first, then DNS servers listed in /etc/resolv.conf, which on many systems points to the local systemd-resolved stub.
dig example.com +short
dig example.com MX
dig @1.1.1.1 example.com # ask a specific server
getent hosts example.com # what applications will see
resolvectl statusWhen "the site is down" but the IP answers, suspect DNS: compare dig with getent, check caching and TTLs, and look for stale entries in /etc/hosts.
Practice. Override a name in /etc/hosts and show that getent and dig now disagree, and explain why.
ICMP, Ping and Traceroute Core
ICMP carries network control messages such as echo requests, "destination unreachable" and "time exceeded". Ping sends echo requests to test reachability and measure round-trip time and packet loss.
ping -c 4 10.0.0.1
traceroute example.com # hop-by-hop path
mtr example.com # combined, continuous view
tracepath example.comTraceroute sends packets with increasing time-to-live values; each router that drops one returns a time exceeded message, revealing the path. Many networks block or rate-limit ICMP, so a failed ping does not prove a host is down; test the real port with nc -zv host 443 or curl.
Practice. Trace the path to a distant site and identify where most of the latency is added.
Netstat, ss and Open Ports Core
You often need to know which program listens on a port and which connections exist. netstat from net-tools did this for years; it is deprecated, and ss is the modern replacement with similar options.
sudo ss -tulpn # listening TCP/UDP sockets with processes
ss -tan state established # current TCP connections
sudo lsof -i :8080 # who uses port 8080
nc -zv db.internal 5432 # can I reach a remote port?An application that listens on 127.0.0.1 is reachable only from the same machine; 0.0.0.0 means all interfaces. That difference explains many "works locally, not from outside" problems.
Practice. Start a small web server, find it with ss, then make it reachable from another machine.
SSH and File Transfer Core
SSH gives you an encrypted shell on a remote machine and is how most servers are managed. Use key-based logins and disable password logins on servers.
ssh-keygen -t ed25519
ssh-copy-id deploy@web1
ssh -J bastion deploy@web1 # jump through a bastion
ssh -L 5433:db.internal:5432 web1 # local port forward
scp app.tar.gz deploy@web1:/tmp/
rsync -avz --delete site/ deploy@web1:/srv/site/For file transfer, scp is fine for single files, and rsync copies only differences, resumes and mirrors directories. sftp gives an interactive session. Keep host aliases in ~/.ssh/config, and harden /etc/ssh/sshd_config with PermitRootLogin no and PasswordAuthentication no.
Practice. Set up key-only SSH to a VM with an alias in ~/.ssh/config and sync a folder with rsync.
Netfilter and Firewalls Recommended
Netfilter is the kernel framework that filters, changes and forwards packets. You manage it through nftables, the modern tool, or iptables, its older interface still found everywhere. Most admins use a front end: ufw on Ubuntu or firewalld on Red Hat-family systems.
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw allow from 10.0.0.0/8 to any port 5432
sudo ufw enable
sudo nft list rulesetDefault deny for incoming traffic, then allow only what the server needs. On a remote machine, allow SSH before enabling the firewall or you lock yourself out. Netfilter also does NAT, which Docker uses for container networking.
Practice. Configure a firewall on a VM that allows SSH from anywhere and PostgreSQL only from one subnet.
Packet Analysis Optional
When logs and status commands are not enough, packet analysis shows what is really on the wire. tcpdump captures packets matching a filter; Wireshark opens the capture with protocol decoding.
sudo tcpdump -i eth0 port 53 # DNS traffic
sudo tcpdump -i any host 10.0.0.7 and port 443 -n
sudo tcpdump -w capture.pcap -c 1000 # save for WiresharkUse it to answer questions such as: does the request leave this machine, does a reply arrive, and is a TCP reset coming from the server or a firewall? Captures can contain sensitive data, so handle the files carefully.
Practice. Capture a DNS lookup and an HTTP request with tcpdump and identify the handshake packets.
Stage 8 Shell Programming for Administrators
Goal. Automate routine administration tasks with safe, readable Bash scripts.
Shell Programming Basics Core
Shell programming turns the commands you type into repeatable scripts. A script starts with a shebang naming its interpreter and needs execute permission.
#!/usr/bin/env bash
set -euo pipefail
backup_dir="/backups/$(date +%F)"
mkdir -p "$backup_dir"
tar -czf "$backup_dir/etc.tar.gz" /etc
echo "Saved to $backup_dir"set -euo pipefail makes the script stop on errors, unset variables and failures inside pipelines, which prevents many silent disasters. Run shellcheck on every script.
Practice. Write a script that backs up /etc to a dated folder and exits non-zero if anything fails.
Literals and Variables Core
Literals are fixed values written directly in a script. Quoting decides how the shell treats them: single quotes keep text exactly, double quotes still expand variables and command substitutions, and unquoted text is split on spaces and expanded as wildcards.
name="web server" # no spaces around =
echo "Host: $name" # Host: web server
echo 'Host: $name' # Host: $name
count=$(ls /etc | wc -l) # command substitution
echo "${name}-01" # braces separate the nameVariables are strings by default. Always double-quote variable expansions, "$file", so names containing spaces do not break your script. Use lowercase for script variables and uppercase for exported environment variables.
Practice. Write a script that prints a greeting with quoted and unquoted variables and explain each output.
Conditionals Core
Conditionals run code depending on a test or a command's exit status. In Bash, if runs a command and checks whether it succeeded; [[ ]] is the test command for strings, numbers and files.
if [[ -f /etc/nginx/nginx.conf ]]; then echo "config found"; fi
if [[ $(id -u) -ne 0 ]]; then echo "run as root" >&2; exit 1; fi
if systemctl is-active --quiet nginx; then echo up; else echo down; fi
case "$1" in
start|stop) systemctl "$1" app ;;
*) echo "usage: $0 start|stop" ;;
esacUseful file tests are -f file, -d directory, -x executable and -s non-empty. Number comparisons use -eq, -lt and friends.
Practice. Write a script that refuses to run as non-root and restarts a service only if its config file exists.
Loops Core
Loops repeat work across files, hosts or lines of input.
for host in web1 web2 web3; do
ssh "$host" uptime
done
for f in /var/log/app/*.log; do gzip "$f"; done
while read -r user shell; do
echo "$user uses $shell"
done < <(awk -F: '{print $1, $7}' /etc/passwd)
until curl -fs localhost:8080/health; do sleep 2; doneUse while read -r to process lines safely, not for line in $(cat file), which splits on spaces. until is handy for waiting on a service to come up.
Practice. Write a loop that checks disk usage on three hosts over SSH and prints any filesystem above 80 per cent.
Debugging Scripts Core
Debugging a shell script starts with tracing. bash -x script.sh or set -x inside the script prints each command after expansion, so you see exactly what ran.
bash -n script.sh # syntax check only
bash -x script.sh # trace
PS4='+${LINENO}: ' bash -x script.sh # with line numbers
shellcheck script.sh # static analysisCommon bugs are missing quotes, spaces around =, using [ without spaces, and scripts written on Windows with CRLF line endings, which give confusing "bad interpreter" errors. Cron runs scripts with a minimal environment, so use full paths and log output to a file.
Practice. Take a broken script with three bugs and find each using bash -x and shellcheck.
Stage 9 Troubleshooting, Containers and Server Review
Goal. Diagnose a misbehaving server methodically and understand how containers are built from Linux features.
Uptime and Load Core
uptime shows how long the system has run and the load averages for the last 1, 5 and 15 minutes. Load is the average number of processes that are runnable or in uninterruptible sleep, waiting for I/O on Linux.
uptime
# 14:02:11 up 12 days, load average: 7.92, 4.10, 2.05
nproc # CPU count to compare againstCompare load with the CPU count: a load of 8 on 16 cores is fine, on 2 cores it means a queue. A rising 1-minute value against lower longer values means things are getting worse now. High load with low CPU use usually points to processes stuck on disk or network I/O.
Practice. Generate CPU load and then I/O load on a VM and compare uptime, top and vmstat in each case.
Server Review Core
When you log into an unfamiliar or struggling server, run a quick, fixed review before changing anything.
uptime # load trend
dmesg -T | tail # kernel errors, OOM kills
vmstat 1 5 # run queue, swap, I/O wait
free -h; df -h; df -i # memory, space, inodes
top # top consumers
iostat -xz 1 3 # disk saturation
ss -s; ss -tulpn # sockets and listeners
systemctl --failed; journalctl -p err -S -1hThis first-minute check covers CPU, memory, disk, network and services, and points you at the resource that is saturated. Write down what you see before acting, so you can compare after a fix.
Practice. Turn this server review into a script that prints a one-page health summary.
Troubleshooting Method Core
Troubleshooting is a method more than a set of commands. Define the symptom precisely, such as "HTTPS requests to api time out from the office since 10:00". Check what changed: deploys, config, certificates, disk filling up. Then work through layers: is the process running, is it listening, can you reach it locally, through the firewall, by name? Check logs at each step.
Change one thing at a time and confirm the effect. Use strace -p PID to see the system calls a stuck process is making, and lsof -p PID to list its open files and sockets. Afterwards, write a short note on cause, fix and prevention.
Practice. Have a friend break a VM in three ways, such as a full disk, a stopped service and a firewall rule, and fix them using this method.
Containerization Recommended
Containerization packages an application with its dependencies and runs it isolated on a shared kernel. A container is not a virtual machine: it is a normal Linux process with restricted views and limits.
- Namespaces isolate what a process sees: its own PIDs, network stack, mounts, hostname and users.
- Cgroups limit what it can use: CPU, memory, I/O and process count.
- Layered filesystems such as OverlayFS give each container an image plus a thin writable layer.
- Capabilities and seccomp reduce what even root inside the container may do.
Because containers share the host kernel, a kernel exploit can affect every container, which is why untrusted workloads sometimes use lightweight VMs instead.
Practice. Use unshare to start a shell in new PID and network namespaces and observe what ps and ip show.
Container Runtime and Docker Recommended
A container runtime creates and runs containers from images. Low-level runtimes such as runc set up the namespaces and cgroups; higher-level ones such as containerd and CRI-O pull images and manage lifecycles. Kubernetes talks to containerd or CRI-O directly.
Docker is the developer tool most people start with: it builds images from a Dockerfile, runs containers and manages networks and volumes, using containerd underneath. Podman offers a compatible command line without a central daemon and runs rootless by default.
docker run -d --name web -p 8080:80 --memory 256m nginx
docker exec -it web sh
docker logs -f web
docker inspect web | grep -i pidThe Docker Roadmap covers images and Compose in depth.
Practice. Run nginx in Docker with a memory limit, find its host PID and its cgroup memory file.
Projects to build
Build these in order. Each one should end up in a public repository with a short README that explains your decisions.
- Log analysis toolkitBeginner
Download or generate a web server access log and answer questions with pipelines only: top IPs, error rates per hour, slowest endpoints and most common user agents. Save each pipeline in a script with comments.
Pipes · GREP · AWK · Sort and uniq · Redirects
- Harden a fresh serverIntermediate
Take a new VM and make it production-ready: a sudo user with key-only SSH, root login disabled, a default-deny firewall, automatic security updates, time sync and log rotation. Document every step so you could repeat it.
SSH · User management · Super user · Firewalls · Package management
- Self-hosted web applicationIntermediate
Deploy a small web app as a systemd service behind nginx on a dedicated data volume. It should run as its own user, restart on failure, log to the journal and survive a reboot. Add a nightly backup with a timer.
Creating services · Mounts · Permissions · System logs · Shell programming
- Server health report scriptAdvanced
Write a Bash script that collects load, memory, swap, disk, inode, failed services, recent errors and listening ports from several hosts over SSH and prints a summary with warnings. Make it pass shellcheck and run it from a timer.
Server review · SSH · Loops · Conditionals · Troubleshooting
- Containers from scratchAdvanced
Use unshare, a cgroup and a minimal root filesystem to start an isolated shell with its own PID and network namespace and a memory limit. Compare what you built with what Docker does for the same image.
Namespaces · Cgroups · Containerization · Container runtime · Filesystems
Interview questions
Try to answer each question out loud before you open the answer.
What happens when you type ls -l in a shell and press Enter?Mid
The shell reads the line, expands aliases and wildcards, and splits it into the command and arguments. It finds ls by searching the directories in PATH. It forks a child process, which calls exec to replace itself with the ls program, inheriting the shell's environment and its stdin, stdout and stderr. ls asks the kernel for the directory entries and each file's metadata, writes the formatted output to stdout, and exits. The shell waits, stores the exit status in $? and prints the prompt.
Explain Linux file permissions and what chmod 750 means.Junior
Every file has an owner and a group, and three sets of read, write and execute bits: for the owner, the group and everyone else. In octal, read is 4, write 2 and execute 1. So 750 means the owner can read, write and execute; the group can read and execute; others have no access. On directories, execute means you can enter the directory and read means you can list it. Root bypasses these checks.
What is the difference between a hard link and a symbolic link?Junior
A hard link is another directory entry pointing to the same inode, so both names are equal and the data stays until the last link is removed. Hard links cannot span filesystems or point to directories. A symbolic link is a small file containing a path to the target. It can cross filesystems and point to directories, but it breaks if the target is moved or deleted.
The disk is full. How do you find out why?Mid
I run df -h to see which filesystem is full and df -i in case it is inodes, not space. Then du -xsh /path/* | sort -h to drill down to the largest directories; logs, caches and core dumps are common culprits. If df and du disagree, a deleted file is still held open by a process, which lsof +L1 shows; restarting that process frees it. After clearing space I fix the cause, for example log rotation.
What is the difference between SIGTERM and SIGKILL?Junior
SIGTERM asks a process to terminate. The process can catch it, finish current work, flush data and clean up, which is why kill sends it by default and service managers use it first. SIGKILL cannot be caught or ignored; the kernel removes the process immediately, with no clean-up, which can leave corrupted files or stale locks. I send SIGTERM, wait, and use SIGKILL only if the process does not exit.
What does load average mean, and is a load of 10 bad?Mid
Load average is the average number of processes running, waiting for CPU, or, on Linux, in uninterruptible sleep, usually waiting for I/O, over 1, 5 and 15 minutes. Whether 10 is bad depends on CPU count: on a 32-core machine it is light, on 4 cores processes are queueing. If load is high but CPU is idle, I look at I/O wait and processes in D state with vmstat and iostat.
A service will not start. How do you debug it?Mid
I run systemctl status app for the state, exit code and last log lines, then journalctl -u app -n 100 for the full error. Common causes are a config syntax error, a missing file or directory, wrong permissions for the service user, a port already in use, which ss -tulpn shows, or a missing environment variable. I try the ExecStart command by hand as the service user. After editing the unit I remember systemctl daemon-reload.
What is a zombie process and how do you get rid of one?Mid
A zombie is a process that has exited but whose parent has not yet collected its exit status with wait. It uses no memory or CPU, only a process table entry. You cannot kill a zombie because it is already dead. You fix the parent: signal it to reap children, or restart or kill it, at which point PID 1 adopts and reaps the zombies. Many zombies indicate a bug in the parent program.
Why does free show almost no free memory on a healthy server?Junior
Linux uses otherwise idle RAM as page cache for file data, which speeds up disk reads. That memory is counted as used by cache but is released immediately when programs need it. The column that matters is available, which estimates memory that can be given to new work without swapping. Real memory pressure shows as low available memory, swap activity in vmstat or out-of-memory kills in dmesg.
How would you check whether a remote service is reachable, step by step?Mid
I start with name resolution: dig or getent hosts to confirm the name gives the right address. Then routing and reachability with ping or traceroute, keeping in mind ICMP may be blocked. Then the actual port with nc -zv host 443 or curl -v, which also shows TLS and HTTP errors. On the server side I check the process is listening on the right interface with ss -tulpn and that firewalls allow it. If needed I capture traffic with tcpdump.
What are cgroups and namespaces, and how do containers use them?Senior
Namespaces control what a process can see: separate PID trees, network stacks, mount tables, hostnames and user IDs. Cgroups control what it can use: CPU, memory, I/O and number of processes, with accounting. A container is a process started by a runtime such as runc with new namespaces, a cgroup with limits, and a root filesystem from an image, usually on OverlayFS. Since all containers share the host kernel, isolation is weaker than with virtual machines.
Explain what happens when a Linux machine boots.Senior
Firmware, normally UEFI, initialises hardware and loads a boot loader such as GRUB from the EFI partition. GRUB loads the selected kernel and the initramfs, passing kernel parameters. The kernel initialises drivers, unpacks the initramfs, which loads the modules needed to find and mount the real root filesystem, then switches to it and starts PID 1, usually systemd. Systemd starts units in parallel according to dependencies until it reaches the default target, then presents a login.
How do you securely configure SSH access to a server?Mid
I use key-based authentication with ed25519 keys, disable password logins and direct root login in sshd_config, and give each person their own account with sudo where needed. I restrict access with a firewall or security groups, often through a bastion or VPN, and consider rate limiting with tools such as fail2ban. I keep OpenSSH patched, review auth.log or secure for failed attempts, and remove keys when people leave.
What is swap and should production servers use it?Senior
Swap is disk space the kernel uses to page out rarely used memory when RAM is under pressure. A small amount gives a buffer against sudden out-of-memory kills and lets idle pages leave RAM. But swap is much slower than memory, so a latency-sensitive service that swaps heavily performs badly. Many teams keep modest swap with low swappiness and alert on swap activity; Kubernetes nodes traditionally disable it so memory limits behave predictably.
How would you find which process is listening on port 8080?Junior
I run sudo ss -tulpn | grep 8080, which shows the listening socket, the address it is bound to and the process name and PID; sudo is needed to see other users' processes. sudo lsof -i :8080 works too. The bound address matters: 127.0.0.1 is local only, 0.0.0.0 is all interfaces. On older systems netstat -tulpn gives the same information.
Common mistakes
- Running everything as root; use a normal account and sudo for individual commands.
- Fixing permission errors with
chmod 777; work out which user needs which access and grant only that. - Running
rm -rfwith an unchecked variable or wildcard; list what matches first and useset -uin scripts. - Reaching for
kill -9first; send SIGTERM and give the process time to clean up. - Editing
/etc/fstabor the firewall on a remote server without a test; runmount -aand allow SSH before enabling rules. - Starting long jobs in a plain SSH session that dies on disconnect; use tmux, nohup or a systemd service.
- Panicking at low free memory; read the available column and look for swapping or OOM kills instead.
- Restarting services before reading their logs; check
systemctl statusandjournalctlfirst so you learn the cause.
Ready-for-interview checklist
- I can navigate the filesystem and explain what lives in /etc, /var, /usr, /proc and /dev.
- I can answer log questions with pipelines using grep, cut, sort, uniq, AWK and sed.
- I can explain stdin, stdout, stderr and redirect each correctly.
- I can create users and groups and set permissions for a shared directory.
- I can explain inodes and the difference between hard and symbolic links.
- I can find, prioritise and stop processes and explain common signals.
- I can install, inspect and upgrade packages on Debian and Red Hat family systems.
- I can write a systemd service, enable it and read its logs.
- I can add a disk, mount it permanently and grow an LVM volume.
- I can explain IP addressing, subnets, routing and DNS resolution on a Linux host.
- I can debug connectivity with ping, traceroute, dig, ss, curl and tcpdump.
- I can write a safe Bash script with error handling and shellcheck it.
- I can run a first-minute server review and explain what each command tells me.
- I can explain how namespaces and cgroups make containers work.
Related roadmaps
- Shell and Bash RoadmapPipelines, text processing, scripting and automation.
- Git and GitHub RoadmapCommits, branches, rebasing, pull requests, Actions and recovery.
- Docker RoadmapImages, containers, networking, volumes, Compose and security.
- Kubernetes RoadmapPods, deployments, services, config, scaling and operations.
- AWS RoadmapCore services: IAM, EC2, S3, VPC, RDS, Lambda and more.
- Computer Science RoadmapTheory every engineer leans on: complexity, memory, OS, networks, compilers.
FAQ
How long does it take to learn Linux?
The everyday command line takes two to three weeks of regular use. Being comfortable administering a server, including services, storage, networking and troubleshooting, takes around three months at a few hours a week. Using Linux as your daily environment speeds this up a lot.
Which Linux distribution should I learn first?
Ubuntu is a good first choice because it is common on servers and in the cloud and has lots of documentation. Later, spend time on a Red Hat-family system such as Rocky Linux or Fedora, since many companies use them and package tools differ. The concepts are the same across all of them.
Do developers really need Linux skills?
Yes, for most back-end, data and infrastructure work. Your code runs in Linux containers or servers even if you write it on macOS or Windows, and debugging production means reading logs, checking processes and testing connections on Linux. Front-end developers need less, but basic terminal skills help everyone.
Should I learn Linux or Bash scripting first?
Start with Linux basics: navigation, files, permissions and pipes. Scripting builds on those commands. Once you repeat a task more than twice, move on to the Shell and Bash Roadmap and automate it.
Is a Linux certification worth it?
Certifications can help when you have no work experience to show, and some employers in operations roles value them. Practical ability matters more in interviews: being able to explain and demonstrate how you would debug a server counts for more than a certificate on its own.