Linux Storage — From Disk to WordPress Files
We now go one level deeper.
You know:
Internet
↓
DNS
↓
IP
↓
TCP
↓
TLS
↓
HTTP
↓
Nginx
↓
PHP-FPM
↓
WordPress
↓
MySQL
You also learned that running programs use:
CPU
RAM
Now we need to understand the third major resource:
STORAGE
1. What Is Storage?
Storage is where data remains after a process stops or the server reboots.
Examples:
WordPress files
Images
Plugins
Themes
Database files
Logs
Backups
SSL certificates
Configuration files
2. RAM vs Storage
Remember:
RAM
=
temporary working memory
Storage
=
persistent data
For example:
WordPress
↓
stored on disk
WordPress process
↓
uses RAM while running
3. Physical Storage
Your VPS ultimately uses some form of physical storage behind the virtualization layer.
It may be backed by:
SSD
NVMe
network-attached block storage
cloud storage
You don’t necessarily see the underlying physical device directly.
4. Device
Linux represents storage devices using device files.
For example:
/dev/sda
or:
/dev/vda
or:
/dev/nvme0n1
The exact name depends on the virtual machine and storage configuration.
5. Check Your Disks
Run:
lsblk
You may see something like:
NAME SIZE TYPE
sda 100G disk
├─sda1 99G part
└─sda2 1G part
Your output will depend on your VPS.
6. Disk vs Partition
A physical/virtual disk can be divided into:
Partitions
Conceptually:
Disk
│
├── Partition 1
├── Partition 2
└── Partition 3
7. Why Partitions?
Partitions allow different portions of a disk to be managed separately.
For example:
Disk
↓
Partition
↓
Filesystem
A system might have:
/
/boot
/home
on separate filesystems or partitions, depending on configuration.
Modern Linux systems can also use LVM, ZFS, Btrfs, RAID, and other storage architectures.
8. Filesystem
A partition isn’t automatically a directory full of files.
You generally put a:
Filesystem
on a storage device/partition.
Common Linux filesystems include:
ext4
xfs
btrfs
Ubuntu installations commonly use:
ext4
though your particular server may differ.
9. Filesystem Job
The filesystem organizes:
Files
Directories
Metadata
Permissions
Ownership
Inodes
Data blocks
Conceptually:
Disk
↓
Partition
↓
Filesystem
↓
Files
10. Mounting
Linux makes a filesystem accessible through a:
Mount Point
For example:
/dev/sda1
↓
/
The filesystem becomes accessible through:
/
11. Root Filesystem
Linux has one main filesystem tree beginning at:
/
This is called:
Root directory
Everything appears underneath it.
12. Linux Does Not Use Windows-Style Drive Letters
Windows commonly uses:
C:\
D:\
Linux instead uses:
/
and mounts additional filesystems into directories.
13. Linux Directory Tree
A simplified Linux filesystem looks like:
/
├── bin
├── boot
├── dev
├── etc
├── home
├── lib
├── opt
├── proc
├── root
├── run
├── srv
├── storage
├── sys
├── tmp
├── usr
└── var
14. /etc
Usually contains system and application configuration.
Examples:
/etc/nginx/
/etc/mysql/
/etc/php/
This is where much of your hosting configuration lives.
15. /var
Contains variable data.
Examples:
/var/log/
/var/lib/
/var/cache/
You may find:
/var/log/nginx/
and:
/var/log/mysql/
depending on configuration.
16. /usr
Contains many installed programs and supporting files.
For example:
/usr/bin/
/usr/sbin/
/usr/lib/
You may find executable programs such as Nginx-related binaries here depending on the package.
17. /home
Often contains normal users’ home directories.
For example:
/home/user/
But web hosting files don’t have to live under /home.
18. /root
This is the home directory of the root user:
/root
It is not the same thing as:
/
This distinction is important.
19. /tmp
Temporary files are commonly stored here.
/tmp
Do not assume everything in /tmp is permanent.
20. /run
Contains runtime state created during boot and while services run.
Examples include:
PID files
Unix sockets
runtime information
You previously saw a PHP-FPM socket such as:
/run/php/php8.3-fpm.sock
21. /dev
Contains device interfaces.
For example:
/dev/sda
/dev/null
/dev/random
These are not ordinary files in the usual sense.
22. /proc
You already encountered:
/proc
It exposes kernel/process information through a virtual filesystem.
It does not represent ordinary persistent disk storage.
23. /sys
Similarly:
/sys
exposes information and interfaces related to devices and the kernel.
24. Your Hosting Directory
You have been using a structure similar to:
/storage/websites/
For example:
/storage/websites/learn.cresignsys.com/public/
This is simply a directory in the Linux filesystem.
The important question is:
What filesystem is mounted underneath
/storage?
25. Check Mounts
Run:
df -h
This shows filesystem usage and mount points.
26. Example df -h
You might see:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 100G 40G 60G 40% /
Meaning roughly:
100 GB total
40 GB used
60 GB available
27. Why df Is Important
Suppose WordPress reports:
No space left on device
You should check:
df -h
before assuming the WordPress installation is broken.
28. But Disk Space Is Not the Only Problem
A filesystem can have:
free storage
but still be unable to create a new file because it has:
no free inodes
This is a deeper Linux storage concept.
29. Inode
An:
inode
stores filesystem metadata about a file.
Conceptually:
File
↓
inode
↓
metadata + pointers to data
Metadata can include things such as:
owner
group
permissions
timestamps
file type
size
data block references
30. Filename vs Inode
A directory entry associates:
filename
↓
inode
The inode represents the underlying file metadata.
This is a very important Linux filesystem concept.
31. Example
Suppose you have:
hello.txt
The filename is not the entire file identity.
Conceptually:
Directory
│
└── hello.txt
↓
inode 12345
↓
file data
32. Why Inodes Matter for Hosting
Imagine a hosting server containing:
millions of tiny files
The server may have plenty of gigabytes available but run out of inodes.
Then creating new files can fail.
33. Check Inodes
Run:
df -i
You may see:
Filesystem Inodes IUsed IFree IUse%
/dev/sda1 6.5M 2M 4.5M 31%
Exact values vary.
34. Two Different Storage Problems
Disk capacity
df -h
Inode capacity
df -i
Both matter.
35. WordPress Creates Many Files
A WordPress installation can contain:
core files
plugins
themes
uploads
cache
logs
temporary files
A hosting platform with hundreds of sites can accumulate a very large number of files.
36. Disk Usage by Directory
Use:
du -sh /storage/*
This gives a high-level size for each directory.
37. Find Large Directories
For example:
sudo du -h --max-depth=1 /storage | sort -h
This helps identify which directories consume storage.
38. Find Large Websites
If you have:
/storage/websites/
you can inspect:
sudo du -sh /storage/websites/*
You might discover:
site1.com 500M
site2.com 2.1G
site3.com 12G
39. Why One Website Can Become Huge
WordPress storage can grow through:
uploads
backups
cache
logs
old plugins
unused themes
database dumps
A site may start at:
500 MB
and eventually become:
20 GB
depending on content and backup strategy.
40. Uploads
A common large directory:
wp-content/uploads/
It contains images and other uploaded media.
For a photography website, this could become very large.
41. Backups
A common hosting mistake is storing many full backups on the same VPS.
For example:
backup-1.tar.gz
backup-2.tar.gz
backup-3.tar.gz
...
Eventually:
disk full
A production backup strategy should generally include off-server storage.
42. Logs
Logs can also grow.
Examples:
/var/log/nginx/
/var/log/mysql/
and application logs.
Linux uses mechanisms such as logrotate and journald to manage many logs, but configurations should still be monitored.
43. Log Rotation
Instead of:
access.log
growing forever, you can have:
access.log
access.log.1
access.log.2.gz
...
Old logs can be compressed or deleted according to policy.
44. File Permissions
Now we reach one of the most important hosting concepts:
Permissions
Every file and directory has access permissions.
Example:
-rw-r--r--
45. Three Permission Categories
Linux permissions traditionally distinguish:
user
group
others
For example:
-rwxr-xr--
means conceptually:
user
rwx
group
r-x
others
r--
46. Read
r
means:
Read
For a regular file:
Can read its contents.
47. Write
w
means:
Write
For a regular file:
Can modify its contents.
48. Execute
x
means:
Execute
For a regular file:
Can execute it as a program, subject to other requirements.
For a directory, x has a different but very important meaning: it allows traversal/search through that directory.
49. Directory Permissions
This is a common beginner trap.
For a directory:
r
means roughly:
Can list directory entries.
w
means:
Can create/delete/rename entries, subject to the directory’s other controls.
x
means:
Can traverse/access entries by name.
50. Example
A directory:
drwxr-xr-x
means:
d
=
directory
rwx
=
owner
r-x
=
group
r-x
=
others
51. Ownership
Every file has an owner and group.
Check with:
ls -l
You might see:
-rw-r--r-- 1 www-data www-data index.php
Meaning:
owner = www-data
group = www-data
52. Why www-data?
On Ubuntu/Debian-style systems, web services commonly run under a user such as:
www-data
depending on the service configuration.
This user may need access to website files.
53. Your WordPress Directory
For example:
/storage/websites/learn.cresignsys.com/public/
could have ownership:
www-data:www-data
depending on your hosting architecture.
But ownership should be chosen deliberately rather than blindly applied everywhere.
54. Permission Problem Example
Suppose WordPress needs to write:
wp-content/uploads/
but PHP-FPM runs as:
www-data
and that directory is not writable by the relevant user/group.
Then WordPress may fail to upload files.
55. Another Permission Problem
Suppose Nginx needs to serve:
index.php
but cannot traverse:
/storage/websites/
because a parent directory lacks appropriate execute permissions.
The file itself may be readable, but the path can still be inaccessible.
56. Path Permissions Matter
For:
/storage/websites/site/public/index.php
the process needs appropriate access through:
/storage
/storage/websites
/storage/websites/site
/storage/websites/site/public
not just permission on:
index.php
57. chmod
chmod changes permissions.
For example:
chmod 644 file.txt
means:
owner = rw-
group = r--
others = r--
58. Numeric Permissions
Common values:
4 = read
2 = write
1 = execute
Add them:
7 = rwx
6 = rw-
5 = r-x
4 = r--
59. Example 755
755
means:
7 = rwx
5 = r-x
5 = r-x
So:
owner: rwx
group: r-x
others: r-x
60. Example 644
644
means:
owner: rw-
group: r--
others: r--
This is commonly suitable for many regular web files, depending on your security model.
61. Don’t Blindly Use 777
You may see advice such as:
chmod -R 777 public/
Avoid this as a general solution.
It grants broad write access and can create serious security problems.
62. chown
chown changes ownership.
Example:
sudo chown www-data:www-data file.php
This sets:
owner = www-data
group = www-data
63. Recursive Ownership
You can use:
sudo chown -R www-data:www-data directory/
But be careful.
Recursive ownership changes can unintentionally affect:
configuration
private files
SSH-related files
deployment files
Always inspect before applying recursively.
64. ls -la
Use:
ls -la
to see:
permissions
owner
group
hidden files
This is one of the most useful Linux commands.
65. Symbolic Links
Linux also supports:
Symbolic links
or:
symlinks
Example:
current
↓
release-2026-08-13
The symlink points to another path.
66. Create Symlink
ln -s /path/to/target /path/to/link
Example:
ln -s /storage/websites/site/public /var/www/site
Now:
/var/www/site
points to:
/storage/websites/site/public
67. Why Hosting Systems Use Symlinks
A hosting platform might organize:
/storage/websites/site/releases/
/storage/websites/site/current
where:
current
points to the active release.
This can make deployments easier.
68. Symlink vs Copy
A symlink:
points to existing data
A copy:
duplicates data
So:
symlink
=
reference
not:
duplicate
69. Hard Link
Linux also supports:
Hard links
A hard link is another directory entry referring to the same inode.
Conceptually:
file1
↓
inode 123
↑
file2
Both names refer to the same underlying file data.
70. Symlink vs Hard Link
Symlink
name
↓
path
↓
target
Hard link
name1 ─┐
├→ same inode
name2 ─┘
This distinction becomes important in advanced filesystem administration.
71. Mount Point
Suppose you have:
/storage
and a separate filesystem is mounted there.
Then:
/storage
becomes the entry point to that filesystem.
72. Why This Matters for Your Server
You have used:
/storage/websites/
If /storage is a separate mounted disk:
root filesystem
+
storage filesystem
then your website data is separated from the root filesystem.
73. Check Mounts
Run:
findmnt
or:
df -h
You may discover:
/dev/sda1 → /
/dev/sdb1 → /storage
74. Separate Storage Advantage
Suppose:
/ = 50 GB
/storage = 500 GB
Then:
OS
configs
packages
can remain on:
/
while:
websites
uploads
live on:
/storage
75. But Mount Failure Can Be Serious
Imagine /storage normally contains:
/storage/websites/
But after a reboot, the storage filesystem isn’t mounted.
Then:
/storage
may still exist as an ordinary directory on the root filesystem.
Your scripts could accidentally write website data there.
This is a potentially dangerous failure mode.
76. Why This Is Dangerous
Suppose:
/storage
is normally a 500 GB filesystem.
After a mount failure:
/storage
might refer only to a directory on /.
A hosting script could continue:
creating websites
and fill the root filesystem instead.
77. Check Before Writing
A robust hosting platform should verify:
Is /storage actually mounted?
For example:
mountpoint /storage
If it returns that /storage is not a mountpoint, your automation should investigate before creating sites.
78. This Is Important for Your CHP
Your CresignSys Hosting Platform should eventually perform:
Create website
↓
Verify /storage mounted
↓
Create directory
↓
Create Nginx configuration
↓
Create database
Don’t assume storage is always mounted.
79. Filesystem Read-Only
Another possible failure:
filesystem
↓
read-only
Then applications may fail to create or modify files.
Check:
mount
or:
findmnt
for mount options.
80. “No Space Left on Device”
This error does not always mean:
df -h = 100%
It can also happen when:
inodes = exhausted
or in other filesystem/resource scenarios.
Therefore check both:
df -h
and:
df -i
81. Disk Usage vs Directory Size
This is another important distinction.
du
measures file/directory usage.
df
reports filesystem-level space usage.
They answer different questions.
82. Example
Suppose:
df -h
says:
100 GB used
but:
du -sh /*
doesn’t seem to add up.
Possible reasons include:
deleted files still held open by processes
other mounted filesystems
special filesystem accounting
83. Deleted but Still Open
This is an advanced but very useful Linux concept.
Suppose a process has:
large.log
open.
Someone deletes the filename:
rm large.log
The directory entry disappears.
But the process still has the file open.
The storage space may not be reclaimed until the process closes it.
84. Find Deleted Open Files
You can investigate with:
sudo lsof +L1
This can reveal open files whose directory links have been removed.
85. Why This Matters
You might see:
df -h
showing:
90 GB used
while:
du
shows only:
60 GB
A deleted-but-open log file could be part of the explanation.
86. WordPress Storage Structure
A typical WordPress installation:
public/
├── wp-admin/
├── wp-content/
│ ├── plugins/
│ ├── themes/
│ └── uploads/
├── wp-includes/
├── index.php
├── wp-config.php
└── ...
87. Which Part Usually Grows?
Often:
wp-content/uploads/
grows with media.
Also:
wp-content/cache/
may grow depending on caching software.
Plugins can also generate:
logs
backups
temporary files
88. Database Is Also Storage
WordPress’s database is not stored as normal PHP files.
MySQL stores its data in its own data directory and filesystem structures.
Commonly on Ubuntu this is under:
/var/lib/mysql/
depending on configuration.
89. So Your Website Uses Multiple Storage Areas
Conceptually:
/storage/websites/site/
│
├── WordPress files
└── uploads
/var/lib/mysql/
│
└── WordPress database
/var/log/
│
└── logs
/etc/
│
└── configuration
90. Backup Must Cover More Than Public Files
A complete WordPress backup usually needs:
WordPress files
+
database
For a hosting server, you may also need to consider:
Nginx configuration
SSL configuration/certificates as appropriate
DNS configuration
server configuration
depending on your recovery plan.
91. WordPress File Backup
You might back up:
/storage/websites/site/public/
But that alone does not contain the complete WordPress site state if the database is separate.
92. Database Backup
For MySQL, logical backups can be created using tools such as:
mysqldump
or newer MySQL dump tooling.
The exact command depends on your database configuration and authentication setup.
93. Full Hosting Backup
A more complete conceptual backup:
Website
│
├── Files
├── Database
├── Nginx config
├── SSL/ACME configuration
└── Metadata
Then store backups somewhere separate from the server.
94. Why Off-Server Backup?
If your VPS completely fails:
VPS
↓
disk lost
and your only backup is:
same VPS
then:
backup lost too
Therefore production backups should normally include an off-server copy.
95. Storage Performance
Storage isn’t only about capacity.
There is also:
IOPS
throughput
latency
96. IOPS
IOPS means:
Input/Output Operations Per Second
A storage device might handle many small operations per second.
This matters for workloads such as:
MySQL
WordPress
logs
many small files
97. Throughput
Throughput measures how much data can be transferred over time.
For example:
500 MB/s
is a throughput figure.
98. Latency
Storage latency is how long an individual operation takes.
For databases, low latency can be very important.
99. WordPress and Storage Performance
A busy WordPress server may perform many operations:
PHP
↓
read files
↓
MySQL
↓
read/write database pages
↓
logs
↓
cache
So storage performance can affect page response time.
100. Disk Space Is Not Enough
Two VPSs might both have:
100 GB storage
but perform differently because of:
IOPS
latency
throughput
storage architecture
101. Your Complete Storage Model
Memorize:
Physical/virtual storage
↓
device
↓
partition
↓
filesystem
↓
mount
↓
directories
↓
files
↓
inodes
↓
data blocks
And access is controlled by:
ownership
+
permissions
102. Your /storage Model
For your server, think:
/storage
│
└── websites
│
├── site1.com
│ └── public
│
├── site2.com
│ └── public
│
└── learn.cresignsys.com
└── public
Nginx then points each domain to its appropriate document root.
103. Nginx Connection
For example:
server {
server_name learn.cresignsys.com;
root /storage/websites/learn.cresignsys.com/public;
}
Now the chain becomes:
learn.cresignsys.com
↓
DNS
↓
VPS
↓
Nginx
↓
/storage/websites/learn.cresignsys.com/public
104. PHP-FPM Connection
Then:
Browser
↓
Nginx
↓
/storage/websites/learn.cresignsys.com/public
↓
PHP file
↓
PHP-FPM
The filesystem permissions must allow the appropriate processes to access what they need.
105. The Hosting Administrator’s Storage Checklist
When a website cannot write files:
1. Is filesystem mounted?
2. Is disk space available?
3. Are inodes available?
4. Is filesystem read-only?
5. Who owns the directory?
6. What permissions exist?
7. Can PHP-FPM access it?
8. Are parent directories traversable?
9. Is there a quota?
10. Is another filesystem involved?
106. Essential Commands
See disks
lsblk
See filesystem space
df -h
See inode usage
df -i
See mounts
findmnt
Check storage mount
mountpoint /storage
Directory size
du -sh /storage
Website sizes
du -sh /storage/websites/*
File ownership
ls -la
Change ownership
chown
Change permissions
chmod
Find open deleted files
sudo lsof +L1
107. The Four Major Server Resources
You now understand three very deeply:
CPU
RAM
STORAGE
And earlier:
NETWORK
So a server can be viewed as:
SERVER
│
┌─────────┼─────────┐
▼ ▼ ▼
CPU RAM STORAGE
│ │ │
└─────────┼─────────┘
▼
NETWORK
All four interact.
108. Example: Website Becomes Slow
Possible cause:
CPU high
or:
RAM pressure
or:
storage I/O slow
or:
network congestion
or:
MySQL slow
or:
PHP-FPM overloaded
This is why good server administration requires understanding the whole stack.
109. Complete CresignSys Hosting Stack
You now have:
USER
│
▼
DOMAIN
│
▼
DNS
│
▼
PUBLIC IP
│
▼
NETWORK
│
▼
UBUNTU
│
┌────────────┼────────────┐
▼ ▼ ▼
CPU RAM STORAGE
│ │ │
└────────────┼────────────┘
▼
NGINX PROCESS
│
▼
PHP-FPM PROCESS
│
▼
WORDPRESS
│
▼
MYSQL PROCESS
│
▼
INNODB
│
▼
DISK
Lesson 053 — Core Principle
The most important concept:
A Linux file is not simply “data on disk.” It exists inside a filesystem, is represented by metadata such as an inode, belongs to an owner/group, has permissions, and ultimately maps to storage blocks.
For your hosting platform:
Domain
↓
Nginx
↓
Document Root
↓
Filesystem
↓
WordPress files
and:
WordPress
↓
MySQL
↓
Database files
↓
Filesystem
↓
Storage
Next Lesson — 054
Linux Users, Groups & Permissions — The Security Foundation of Hosting
We will go deeper into:
root
↓
user
↓
group
↓
UID
↓
GID
↓
www-data
↓
file ownership
↓
directory traversal
↓
chmod
↓
chown
↓
umask
↓
setuid
↓
setgid
↓
sticky bit
Then we will apply it directly to your hosting structure:
/storage/websites/
↓
www-data
↓
Nginx
↓
PHP-FPM
↓
WordPress
and determine exactly who should own your website files and which permissions should be used without resorting to insecure 777 permissions.