Linux File Permissions Explained: chmod, chown and the Numbers

Read any ls -l line, understand 644 vs 755, fix "Permission denied" properly, and set the ownership a web server needs — without chmod 777.

Published
Reading time
3 min

Half of all "my site is broken" tickets that reach us are permissions. A plugin cannot write to uploads, a deploy script created files as root, or someone ran chmod -R 777 and now the server flags everything as a risk. Ten minutes with this guide and you will never need to guess again.

Reading an ls -l line

bash
ls -l /var/www/vhosts/example.com/httpdocs/
# -rw-r--r-- 1 example psacln  418 Sep 12 10:02 index.php
# drwxr-xr-x 5 example psacln 4096 Sep 12 10:02 wp-content

Take the first field apart:

Part Meaning
- or d regular file, or directory
rw- what the owner (example) can do: read, write, not execute
r-- what the group (psacln) can do: read only
r-- what everyone else can do: read only

Then example psacln is the owner and group. Every permission question is one of those three columns.

What the numbers mean

Each column is a number: read = 4, write = 2, execute = 1. Add them up.

Number Permissions Typical use
7 rwx owner of a directory
6 rw- owner of a file
5 r-x everyone else, on a directory
4 r-- everyone else, on a file
0 --- nothing

So 644 is owner read/write, everyone else read — the right default for files. 755 adds execute — the right default for directories (on a directory, "execute" means "may enter it"). 600/700 mean "only the owner", which is what wp-config.php and .env should be.

chmod: set permissions

bash
chmod 644 index.php          # one file
chmod 755 wp-content         # one directory
chmod 600 wp-config.php      # secrets: owner only

To fix an entire site in one go without giving files execute:

bash
cd /var/www/vhosts/example.com/httpdocs
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 600 wp-config.php

The symbolic form is handy for one change at a time — u owner, g group, o others, a all:

bash
chmod u+x deploy.sh      # let the owner run the script
chmod go-w config/       # remove write from group and others

chown: set the owner

Permissions are only half of it. If the web server runs as a different user than the one who owns the files, 644 still means "no write". On Plesk, PHP runs as the subscription's system user and the group is psacln:

bash
chown -R example:psacln /var/www/vhosts/example.com/httpdocs

On a plain Ubuntu box with Nginx and PHP-FPM, the user is usually www-data:

bash
chown -R www-data:www-data /var/www/example.com

Find out which user PHP actually runs as before you change anything:

bash
ps aux | grep -E 'php-fpm|httpd|apache2' | head

Why chmod 777 is never the fix

777 lets every account on the machine write to the file. On shared hosting, that is every other customer. On a VPS, it is any process that gets compromised — a vulnerable plugin can then rewrite your .htaccess, drop a web shell, and spread. Plesk and most malware scanners flag 777 for a reason. If something needs write access, give it to the right owner, not to the world.

Quick fixes for common errors

"Permission denied" when uploading in WordPress — the uploads directory is not owned by the PHP user:

bash
chown -R example:psacln wp-content/uploads
chmod 755 wp-content/uploads

"Failed to open stream: Permission denied" for a config file — the file is 600 and owned by someone else. Fix the owner, not the mode.

A script that "cannot be executed" — missing the x bit: chmod u+x script.sh.

Files created by root after a deploy — you ran git pull or composer install as root. Re-own the tree, and next time run deploys as the site user or with sudo -u example.

Directories deserve a second look

Two bits on directories confuse people:

  • Sticky bit (chmod +t /tmp) — anyone can create files, only the owner can delete their own. That is why /tmp shows as drwxrwxrwt.
  • setgid (chmod g+s dir) — new files inherit the directory's group. Useful on shared project folders so everything stays in psacln without re-running chown.

On VPSPioneer shared and reseller plans, ownership is set correctly at account creation and the File Manager shows the mode next to every file. On a managed VPS we set it up per site and put it right when a deploy breaks it — just open a ticket.

#linux#permissions#chmod#chown

Keep reading

More from Linux

All guides

Linux

Understanding Linux Load Average, top and htop

What the three load average numbers mean against your core count, what top and htop show, and how to tell CPU pressure from I/O wait and memory trouble.

3 min read →

Linux

How to Update a Linux Server Safely (and Automate Security Patches)

The right way to run updates on Ubuntu, Debian and AlmaLinux, what to check before and after, when to reboot, and how to automate security patches only.

3 min read →

Linux

Ubuntu vs Debian vs AlmaLinux vs Rocky: Which Linux for a Server?

The practical differences between the server distributions — release cycles, package freshness, support length, tooling — and which to pick for what.

3 min read →