Docker Deep Dive · Reference

Linux & Shell Cheatsheet

Everything phase 0 (P1–P7) teaches, in the shape you'll reach for it. The Docker CLI gets its own cheatsheet as those lessons arrive; this page is the Linux underneath every Docker command.

Your Linux playground

Real Linux practice happens inside a disposable container — identical on macOS, Windows, and Linux. One command in, exit out, nothing on your Mac can break:

docker run -it --rm ubuntu:24.04 bash

Move around, look around · P1

command -f --long-flag argument1 argument2
commanddoesremember
pwdprint working directory — "where am I?"prompt ≠ location; trust pwd
ls -lahlist: long form, hidden files, human sizes-l rows are P2's mode strings
cd pathchange directorycd alone → home, cd - → back
mkdir -p a/b/cmake directories, parents includedno -p: parents must exist
touch fcreate empty file (or bump its date)
cp -r src dstcopy (-r for directories)silently overwrites — -i asks
mv old newmove and rename (same command)
rm -r dirdelete forever — no trash, no undoread the line twice before Enter
cat f / less fdump file / page through itin less: space, /find, q
head -n 20 f / tail -n 20 ffirst / last linestail -f = follow live (→ docker logs -f)
keyeffect
Tabcomplete the path/command — if it won't complete, it doesn't exist (your best typo detector)
↑ / ↓walk command history
Ctrl-Rsearch history as you type
Ctrl-Cinterrupt the foreground process (sends SIGINT — see P4)
Ctrl-Lclear screen (history stays)
/etc/nginx/nginx.conf   # absolute: starts at the root /
../logs/app.log         # relative: from where you are (.. = up one)
~/projects              # ~ = your home directory
ls --help        # quick flags list — works in containers
man ls           # full manual — on your Mac (container images strip docs)
type ls          # what IS this command — binary, builtin, or alias?

Files, permissions, root · P2

-  rwx  r-x  r--   1  app  staff  4096  Jul 17  deploy.sh
│   │    │    │       └owner └group
│   │    │    └─ everyone else: read only
│   │    └────── group "staff": read + execute
│   └─────────── owner "app": read + write + execute
└─ type: - file · d directory · l symlink
octaltriadtypical use
7 = rwxread+write+executeowner of a script/dir
6 = rw-read+writeowner of a data file
5 = r-xread+executegroup/others on dirs
4 = r--read onlyconfig for others
0 = ---nothingsecrets for others
chmod +x deploy.sh          # make executable
chmod 644 app.conf          # rw-r--r-- : owner edits, world reads
chmod 600 secret.env        # rw------- : owner only
chmod 755 bin/              # rwxr-xr-x : dirs need x to be entered
chown -R app:app /data      # give a tree to user:group (root only)
id                          # who am I — uid, gid, groups
su - dev                    # become user dev (fresh login shell)

Directory triads read differently: r = list names, w = create/delete entries, x = enter/traverse. Containers run as root by default — the whole point of lesson 11's USER.

Streams, pipes, text · P3

fdstreamdefault
0stdin — what the process readsyour keyboard
1stdout — its resultsyour screen
2stderr — its complaintsyour screen (separately!)
cmd > out.txt        # stdout → file (TRUNCATES first)
cmd >> out.txt       # append instead
cmd 2> err.txt       # stderr → file
cmd > all.txt 2>&1   # both → one file (order matters)
cmd 2> /dev/null     # discard complaints
cmd < input.txt      # stdin ← file
grep " 500 " access.log | cut -d' ' -f7 | sort | uniq -c | sort -rn | head -3
# filter → extract field → group (sort THEN uniq) → rank → top 3
tooldoesflags that matter
grep PATTERN fkeep matching lines-i case-blind · -v invert · -rn recurse+numbers · -c count
wc -lcount lines
sortorder lines-n numeric · -r reverse · -u unique
uniq -ccollapse+count adjacent dupesalways sort first
cut -d' ' -f7take field 7, space-delimited
find DIR -name '*.conf'walk tree, filter-type f/d · -mtime -1 · -size +1M
xargs CMDstdin lines → CMD argumentsdocker ps -q | xargs docker stop
docker rm $(docker ps -aq)   # $( ) = run inner command, paste its output here

Processes, environment, signals · P4

ps aux                  # every process: PID, CPU, MEM, command
ps -ef --forest         # parent→child tree (who started whom)
sleep 500 &             # & = run in background, prints its PID
jobs                    # this shell's background jobs
kill PID                # polite: SIGTERM — "please clean up and exit"
kill -9 PID             # brutal: SIGKILL — unignorable, no cleanup
echo $?                 # exit code of the last command
signalnmeaningcatchable?
SIGINT2Ctrl-C from the keyboardyes
SIGTERM15"please exit" — kill's and docker stop's defaultyes — graceful shutdown lives here
SIGKILL9kernel removes the process, no appealnever
SIGHUP1terminal closed / "reload config" by conventionyes
exit codemeans
0success — the only success
1–125program-defined failure
126 / 127found but not executable / command not found
128+Nkilled by signal N → 137 = SIGKILL (OOM!, lesson 10) · 143 = SIGTERM
NAME=harbor             # shell variable — this shell only
export NAME=harbor      # environment variable — inherited by children
NAME=harbor cmd         # one-shot: set only for that command
echo "$NAME"            # read (quote it — always)
echo "${PORT:-8000}"    # read with default if unset (entrypoint gold)
env | sort              # everything this process will pass down
echo "$PATH"            # where the shell hunts for commands, left→right

Kernel, /proc, namespaces · P5

uname -r                     # kernel version — same in EVERY container on this machine
ls /proc                     # one numbered dir per process (ps just reads these)
cat /proc/1/cmdline          # what PID 1 really is
cat /proc/meminfo            # live kernel memory accounting
ls -l /proc/$$/ns            # the namespaces THIS shell lives in
strace -c ls                       # count every syscall ls makes
strace -e trace=openat cat /etc/hostname   # watch just the file-opens
unshare --pid --fork --mount-proc bash   # new PID namespace: ps shows you as PID 1
namespaceisolatesyou met it in
pidwhich processes are visiblelesson 10's docker top vs exec ps
netinterfaces, IPs, portswhy -p exists (lesson 4)
mntthe filesystem viewimage layers (lessons 2–3)
utshostnamecontainer id as hostname (lesson 1)
useruid/gid mappingrootless mention (lesson 11)
cat /sys/fs/cgroup/memory.max        # this group's memory ceiling (bytes or "max")
cat /sys/fs/cgroup/cgroup.procs      # PIDs governed by this group

Ports, DNS, packages · P6

ip addr                 # interfaces: lo (127.0.0.1) + eth0
ss -tlnp                # tcp listeners: port, PID — the "is it up?" command
curl -v localhost:8000  # speak HTTP, show the whole conversation
getent hosts db         # resolve a name the way the OS does
cat /etc/hosts          # local name overrides (checked first)
cat /etc/resolv.conf    # who answers DNS (in Docker nets: 127.0.0.11)

The bind rule that explains half of all container bugs

A server that listens on 127.0.0.1 accepts connections only from inside its own network namespace — docker run -p can't reach it. Listen on 0.0.0.0 (all interfaces) and publishing works. Ports below 1024 need root or CAP_NET_BIND_SERVICE.

apt-get update                   # refresh the package index (a local cache!)
apt-get install -y curl          # install; -y for scripts/Dockerfiles
dpkg -L curl                     # what files did it put where (FHS in action)
rm -rf /var/lib/apt/lists/*      # drop the index cache — the lesson-8 slimming move
apk add --no-cache curl

Scripts & entrypoints · P7

#!/usr/bin/env bash
set -euo pipefail        # die on error, on unset vars, in broken pipes

name="${1:?usage: $0 NAME}"      # $1 = first argument, or die with usage
echo "deploying ${name} to ${ENV:-dev}"
testtrue when
[ -f p ] / [ -d p ]file / directory exists
[ -z "$v" ] / [ -n "$v" ]string empty / non-empty
[ "$a" = "$b" ]strings equal (spaces around =!)
if cmd; then…any command's exit code 0 is "true": if grep -q err log
#!/usr/bin/env bash
set -e
echo "preparing config from env…"       # setup work happens as a script
exec "$@"                               # then REPLACE the shell with the real app:
                                        # app becomes PID 1 → docker stop's SIGTERM reaches it
CMD ["python", "app.py"]     # exec form — python IS PID 1, signals arrive ✓
CMD python app.py            # shell form — sh -c wrapper eats SIGTERM ✗

Terms · phase 0 glossary

termin one line
terminalthe program drawing text on your screen; it hosts a shell
shellthe command interpreter (zsh, bash): parses your line, runs programs, reports exit codes
kernelthe one program that owns hardware, processes, files, and the network; everything else asks it
syscallthe only doorway from a program into the kernel (open, read, execve, …)
processa running program: PID + memory + open files + environment + one parent
PID 1the first process in a (namespace's) tree; special signal rules — your container's main process
signalan asynchronous one-byte message to a process (SIGTERM, SIGKILL…)
environment variableper-process key=value strings, copied to children at spawn — 12-factor config's carrier
namespacekernel feature limiting what a process can see (pids, mounts, network…)
cgroupkernel feature limiting what a process can use (memory, CPU)
socket / porta communication endpoint; TCP port = 16-bit number one listener may claim per address
DNSname → IP resolution; containers get a per-network resolver at 127.0.0.11
package managerinstalls software + its dependencies from an indexed repository (apt, apk)

Where each section was taught

P1 The Terminal & the Shell · P2 Files, Permissions & root · P3 Streams, Pipes & Text Tools (soon) · P4 Processes, Environments & Signals (soon) · P5 Kernel, Syscalls & Namespaces (soon) · P6 Ports, DNS & Packages (soon) · P7 Shell Scripts & Entrypoints (soon)