Linux file system
The Linux file system is a single tree rooted at the slash / directory, and the Linux File System Standard (FHS) fixes the top-level layout so that every standard Linux distros build places the same kind of file in the same place.

From that root, 10 top-level directories hold the whole system: /bin, /boot, /dev, /etc, /home, /lib, /media, /opt, /proc, /root, /run, /sbin, /srv, /sys, /tmp, /usr, /var and /mnt. Because the whole machine is one tree, a path such as /etc/nginx/nginx.conf is absolute from the root, and there is no drive letter and no second root to learn. The web stack sits inside this same tree, which is the point of this page.
The layout is described by the FHS and implemented by the base package set, so the directories below are the same on Ubuntu, Debian and the many Linux distros people actually run, including Linux Mint and the server builds. Whether you are reading the tree on a desktop or on a machine running Linux for the LAMP stack, or checking what a small Linux Devices box stores under /var, the map holds. The sections that follow walk it top to bottom, then show where PHP and .NET live inside it.
Why there is one root and no drive letters
The Linux file system starts from a single root because the kernel exposes storage as a tree of inodes, not as labelled drives. Windows assigns letters, C: and D:, to volumes; Linux has no letters, so the FHS folds everything into the one / tree and uses directory names as the navigation instead. A hard disk is a partition, and a partition is a volume, but neither a partition nor a volume appears as a letter: it appears as a mount point. That single root is the defining property of the layout, and the rest of the page assumes it. The next section shows how volumes attach to it without breaking the tree.
The mount model: how volumes join the tree
The mount model is the mechanism that lets a second volume join the same tree, because Linux hides the difference between a file on the root disk and a file on a separate disk by mounting each volume at a directory. You see the list with mount, and you add one with mount /dev/sdb1 /data, after which every file written to /data lands on the second disk while the paths above and below it look identical to the root. The FHS reserves specific directories for these joins: /mnt is for a manual, temporary mount, /media is for removable media the system auto-mounts, and /media/cdrom or /media/sda1 are the directories that appear when a disk is inserted. Persistent mounts live in /etc/fstab, one line per volume, and are applied at boot in the order written. The practical consequence is that a web server can keep its growing data on a large disk mounted at /var/www while the operating system stays on the small boot disk, and the application sees one continuous tree. Keeping the mount model in mind is what makes the next section, the top-level directories, predictable.
The top-level directories, mapped
The top-level directories split the tree into static system files, changing system state, and user content, and each has a fixed job that the FHS spells out. The table below lists the standard first-level directories, what holds in each, and whether it changes on a running system.
| Directory | Holds | Changes at runtime |
|---|---|---|
/bin | Essential user commands, such as ls and cp | No, static |
/sbin | Essential system commands, such as mount and reboot | No, static |
/etc | Configuration files, one per service | No, edited by hand |
/home | One directory per user account | Yes, user data |
/boot | Kernel images and bootloader files | No, updated on kernel install |
/dev | Device files, one per device node | Yes, rebuilt on boot |
/tmp | Temporary scratch files | Yes, cleared on reboot |
/proc | Live process and kernel data, read from memory | Yes, always |
/sys | Kernel device tree, mirrors /dev | Yes, always |
/run | Runtime state, such as PID files and sockets | Yes, rebuilt on boot |
/usr | Read-only shared programs, libraries and docs | No, static |
/var | Variable data: logs, spool, caches, state | Yes, constantly |
The split between /usr and /var is the one that matters most for operations. /usr is meant to be read-only and safe to remount read-only, while /var is where the system writes. On older releases the essential commands lived under /bin and the shared ones under /usr/bin; modern Debian-based systems, the base for most Linux distros you will meet, merge them so /bin is a symbolic link to /usr/bin and a single copy of each command exists. The directories that follow are the two that a web server touches every day.
Where the web stack lives: /usr, /var and /etc
The web stack lives across three of those directories, because the software, its configuration and its data are stored separately by the FHS. On a machine running Linux for the LAMP stack the split is exact: the programs go in /usr, the configuration goes in /etc, and the ever-changing data goes in /var. A PHP application ships its binaries and libraries under /usr/bin/php and /usr/lib/php, its configuration under /etc/php, and its logs under /var/log/php. Nginx follows the same pattern, with the server binary in /usr/sbin/nginx, the configuration at /etc/nginx/nginx.conf, and access and error logs under /var/log/nginx. The document root is the one place where user content is written, and the FHS default for a multi-site server is /var/www, with a subdirectory per site such as /var/www/site1. ASP.NET Core applications on Linux keep the same discipline: the compiled .dll and its runtime sit in a project directory, usually under /opt for a standalone install or under /var/www when it is a web root, and its configuration files go in /etc or in the app folder. The reason the FHS separates these three is operational: you can back up the static software, the edited configuration and the growing data with three different schedules, and you can mount each on its own volume. That separation is the thread this page returns to in every section.
Why the data goes under /var and not next to the code
The data goes under /var and not beside the code so that the software stays read-only while the state it produces is allowed to grow without limit. If a site's uploads lived at /usr/share/site the FHS read-only expectation would be violated, and a runaway log could fill the boot disk instead of a dedicated data volume. Putting logs, spool and caches under /var means an administrator can mount /var on a large disk, set rotation there, and watch one place when storage fills. This is the same logic that puts the mount points for extra volumes in a predictable place, and it is why a Linux Mint desktop and a LAMP server both keep their growing files under /var.
Configuration under /etc and state under /var
The configuration under /etc is the set of files an administrator edits by hand, one per service, and the state under /var is what the service writes while it runs, so the two directories are the two sides of every daemon. /etc/hostname sets the machine name, /etc/resolv.conf holds the DNS servers, and /etc/fstab lists the volumes to mount, each in a fixed, well-documented format. A service's own file sits in a service subdirectory, such as /etc/nginx/ or /etc/php/8.2/, where the version is part of the name so two versions can coexist. The runtime state has its own home under /var: /var/log for logs, /var/spool for mail and cron queues, /var/cache for caches, and /var/lib for persistent state such as a database's files. A database is the clearest case: MySQL keeps its tables in /var/lib/mysql, so the FHS places the database files where all persistent state belongs rather than beside the server binary in /usr. This is the layout a small Linux Devices appliance uses too, which is why the same backup script works on a single-board box and on a rack server.
Reading the tree: paths, ownership and permissions
The tree is read with absolute paths, and every node carries an owner and a set of permissions that decide who may read, write or execute it, which is how the same file system stays safe with many users. The command ls -ld /var/www prints the owner, the group and the mode, and a mode such as 755 means the owner can read, write and execute while the group and everyone else can read and execute but not write. Ownership is what lets the web server write to /var/log/nginx while keeping /etc/nginx writable only by root, and it is why a site's document root is owned by a service account and not by a user who could also run shell commands. The three commands that cover most reading are ls -la to list a directory with its permissions, stat /path to see the inode, size and timestamps of one node, and df -h to see how full each mounted volume is, which pairs directly with the mount model from earlier. Because a path is absolute from the root, a script that writes /var/log/app.log behaves the same on any of the Linux distros that follow the FHS, and that predictability is the whole value of the layout.