Linux has one directory tree starting at /. Disks, USB sticks and network shares are mounted into that tree instead of getting drive letters. Knowing the map lets you answer most first questions on an unfamiliar server: where is the config, where are the logs, what is full.
Versions in use on this date. Ubuntu 18.04.2 LTS (released 7 February 2019, kernel 4.15 in the stock install) and CentOS 7.6 (December 2018, kernel 3.10 with Red Hat backports). Both follow the Filesystem Hierarchy Standard, so the layout below is the same on each, with small differences noted.
The map
flowchart TB
R[Root /] --> E[etc<br/>configuration]
R --> V[var<br/>logs spool caches]
R --> U[usr<br/>programs and libraries]
R --> H[home and root<br/>user data]
R --> P[proc and sys<br/>live kernel views]
R --> D[dev<br/>device files]
R --> T[tmp and run<br/>temporary and runtime]
R --> M[mnt and media<br/>mount points]
R --> O[opt and srv<br/>add-on software and service data]
V --> VL[var/log]
V --> VLIB[var/lib<br/>databases and package state]
| Directory | Holds | Notes |
|---|---|---|
/etc |
System-wide configuration, plain text | Back this up; most changes you make land here |
/var/log |
Logs: syslog, auth.log (Ubuntu), messages, secure (CentOS) |
Grows over time; see the logrotate post later |
/var/lib |
Application state: MySQL data, package databases, Docker data | Often the biggest directory on a server |
/usr/bin, /usr/sbin |
Installed commands | On 18.04 /bin and /sbin are separate; CentOS 7 symlinks them into /usr |
/home, /root |
User files and the root user’s home | Often on its own disk or partition |
/proc, /sys |
Kernel and hardware information; not real files | cat /proc/meminfo costs nothing |
/dev |
Device nodes such as /dev/sda, /dev/null |
Created by the kernel and udev |
/tmp, /run |
Temporary files; runtime state and PID files | /run is memory-backed and empty after reboot |
/opt |
Self-contained third-party software | Common for vendor tarballs |
/srv |
Data served by this machine (sometimes web or FTP roots) | Rarely used by default |
Mounts: how disks join the tree
A mount attaches a filesystem to a directory. The same server may have / on one disk, /var on another and /home on a network share, and from the shell it all looks like one tree.
df -hT # filesystems, type, size, used, mount point
findmnt # the mount tree
lsblk # block devices and where they are mounted
mount | grep ' / ' # how the root filesystem is mounted
Splitting /var or /home onto separate volumes limits the damage when logs or users fill a disk, which is why production servers are often partitioned this way.
Finding what is using space
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail
sudo du -sh /var/log /var/lib /home /tmp
df -i # inodes: a disk can be "full" with free space left
-x keeps du on one filesystem, so it does not count /proc or other mounts. A full disk is usually /var/log (runaway log), /var/lib (database or Docker images) or /tmp.
Finding a file or a command
which nginx # path of the command in $PATH
type -a python3 # all matches, aliases first
dpkg -S /usr/sbin/nginx # Ubuntu: which package owns this file
rpm -qf /usr/sbin/nginx # CentOS: same question
sudo find /etc -name '*.conf' -mtime -1 # config changed in the last day
Habits worth building early
- Change config in
/etc, never in/usr; package upgrades overwrite files under/usr. - Put your own scripts in
/usr/local/bin, which is on the default$PATHand left alone by the package manager. - Treat
/procand/sysas read-only views unless a guide tells you to tune a value. - Keep
/tmpout of anything that must survive a reboot or hold sensitive data. - Know your layout before an outage: run
lsblkanddf -hTon each new server and save the output with your notes.