Ubuntu File System Structure Explained

On Ubuntu, every file has a specific place it belongs. When you know where configuration files, logs, binaries, and data are supposed to live, you stop guessing and start working faster. This structure comes from the Filesystem Hierarchy Standard (FHS), which every Linux distribution follows with minor variations.

The Filesystem Hierarchy Standard

The FHS defines what each top-level directory is for. Unlike Windows, where programs install themselves wherever they like, on Linux every type of file has a designated location. This makes the system predictable: you always know where to find a config file, where logs will be, and where binaries are installed.

/                        ← Root of the entire filesystem
├── bin/                 ← Essential user commands (ls, cp, bash)
├── boot/                ← Kernel, initramfs, GRUB bootloader
├── dev/                 ← Device files (disks, terminals, random)
├── etc/                 ← System-wide configuration files
├── home/                ← User home directories (/home/irfan)
├── lib/                 ← Shared libraries for /bin and /sbin
├── lib64/               ← 64-bit shared libraries
├── media/               ← Mount points for removable drives (USB, CD)
├── mnt/                 ← Manual mount points (temporary)
├── opt/                 ← Optional third-party software
├── proc/                ← Virtual filesystem: kernel and process info
├── root/                ← Home directory for the root user
├── run/                 ← Runtime data (PIDs, sockets) — cleared on boot
├── sbin/                ← System administration commands (fdisk, fsck)
├── snap/                ← Snap package mount points
├── srv/                 ← Data served by this system (web, FTP)
├── sys/                 ← Virtual filesystem: hardware and kernel state
├── tmp/                 ← Temporary files — cleared on reboot
├── usr/                 ← Most installed software lives here
│   ├── bin/             ← Non-essential user commands (python3, git)
│   ├── lib/             ← Libraries for /usr/bin
│   ├── local/           ← Manually installed software (not via apt)
│   │   ├── bin/
│   │   └── lib/
│   ├── sbin/            ← Non-essential system commands
│   └── share/           ← Architecture-independent data (docs, icons)
└── var/                 ← Variable data that changes while running
    ├── cache/           ← Application cache data
    ├── lib/             ← Persistent application state
    ├── log/             ← Log files
    ├── mail/            ← Mail spool
    ├── run/             ← (symlink to /run on modern Ubuntu)
    ├── spool/           ← Spool data (print, cron)
    └── tmp/             ← Temporary files (NOT cleared on reboot)

Top-level directories explained

# Explore the top of the filesystem
ls -la /

# See the disk usage of each top-level directory
du -sh /* 2>/dev/null | sort -h
DirectoryContainsAdministrator relevance
/etcConfiguration filesMost of your time is spent here
/var/logLog filesFirst place to look when something breaks
/homeUser home directoriesUser files, bash history, SSH keys
/rootRoot user homeRoot’s bash history, keys
/tmpTemporary files cleared at rebootScript temp files; never store data here
/bootKernel and bootloaderFills up if old kernels are not removed
/procKernel process info (virtual)Read CPU info, running processes, kernel params
/sysHardware and kernel state (virtual)Read hardware info, tune kernel parameters
/devDevice filesDisks (/dev/sda), terminals, null, random
/optOptional third-party softwareSoftware installed outside apt (e.g., JetBrains)
/usr/localManually installed softwareBinaries compiled from source; survives OS upgrades

Where application data lives

Knowing where applications store their data prevents you from filling the root filesystem. Most application data goes under /var.

# MySQL / MariaDB data directory
ls /var/lib/mysql/

# PostgreSQL data directory
ls /var/lib/postgresql/

# Nginx web root (default)
ls /var/www/html/

# Docker container layers and volumes
ls /var/lib/docker/

# Snap package data
ls /var/snap/

The pattern is /var/lib/<service-name>/ for databases and stateful services. This is not a coincidence — it is the FHS standard, and every well-packaged application follows it.

Where logs live

# All system logs
ls /var/log/

# The systemd journal (binary, use journalctl to read)
ls /var/log/journal/

# Common logs you will read regularly
tail -f /var/log/syslog           # General system messages
tail -f /var/log/auth.log         # Login attempts, sudo usage, SSH
tail -f /var/log/kern.log         # Kernel messages
tail -f /var/log/dpkg.log         # Package install/remove history
tail -f /var/log/apt/history.log  # apt command history

# Nginx and Apache logs
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
tail -f /var/log/apache2/error.log

💡 TIP: /var/log filling up is one of the most common causes of sudden service failures on production servers. Set up log rotation (logrotate) and monitor disk usage of /var/log. If you have a separate /var partition, this protects the root filesystem from log-induced full-disk events.

Where configuration lives

Almost every service on Ubuntu stores its configuration under /etc. The naming pattern is predictable once you know it.

# Core system configuration
cat /etc/hostname                # Server hostname
cat /etc/hosts                   # Local DNS overrides
cat /etc/resolv.conf             # DNS server addresses
cat /etc/fstab                   # Disk mount configuration
cat /etc/os-release              # Ubuntu version info

# Network configuration (Ubuntu 18.04+)
ls /etc/netplan/                 # Netplan YAML config files

# Service configuration directories
ls /etc/nginx/                   # Nginx config
ls /etc/apache2/                 # Apache config
ls /etc/mysql/                   # MySQL config
ls /etc/ssh/                     # SSH server config
ls /etc/systemd/system/          # Custom systemd unit files

# User accounts and groups
cat /etc/passwd                  # User account list (not passwords)
cat /etc/group                   # Group definitions
cat /etc/sudoers                 # sudo rules (use visudo to edit)

📝 NOTE: Never edit /etc/sudoers directly with a text editor. Always use sudo visudo, which validates the syntax before saving. A syntax error in sudoers can lock all users out of sudo permanently.

Temporary files and runtime data

There are three places temporary data lives, and they behave differently:

LocationCleared when?Use for
/tmpOn reboot (or sooner, managed by systemd)Truly temporary files for scripts and tools
/var/tmpNot on reboot (by design)Temporary data that must survive a reboot
/runOn reboot (tmpfs, in memory)PID files, sockets, runtime state
# /tmp is typically a tmpfs (RAM-based) on Ubuntu 22.04+
mount | grep /tmp

# Check /run — contains socket files and PIDs for running services
ls /run/
ls /run/nginx.pid      # nginx PID file, if running
ls /run/sshd.pid       # sshd PID file

# Check tmpfs mounts (in-memory filesystems)
df -t tmpfs

Common mistakes with the filesystem

  • Storing application files in /tmp: Files in /tmp disappear on reboot. Use /var/lib/yourapp/ for data that must persist.
  • Installing software to /usr/bin manually: Manually placing binaries in /usr/bin will be overwritten by apt. Use /usr/local/bin for manually installed tools.
  • Putting everything on the root partition: When /var/log or /var/lib/mysql fills up on the same partition as /, the entire system can become unresponsive. Separate /var or at minimum monitor disk usage with df -h in a cron job.
  • Editing files under /proc or /sys directly: These are virtual filesystems — kernel parameters are set here at runtime using sysctl, not by editing files. Use /etc/sysctl.conf for persistent changes.

Conclusion

The Ubuntu filesystem is not random — every directory has a defined purpose. Configuration is always in /etc, logs are always in /var/log, service data is in /var/lib, and manually installed software goes in /usr/local. Learn this map and you will navigate any Ubuntu system confidently without having to search for files.

FAQ

Why should administrators understand Ubuntu File System Structure Explained?+

Because this topic affects planning decisions, server lifecycle, compatibility, support expectations, or how you reason about Ubuntu systems before making operational changes.

Do I need a lab for this topic?+

A lab is useful for checking commands and seeing the concept on a real Ubuntu machine, but the main value is understanding the decision, tradeoff, or system behavior clearly.

How should I use this knowledge in production?+

Use it to make better choices, document why those choices were made, and avoid rushed changes that ignore support windows, compatibility, stability, or operational risk.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Hire Me for Support