Home / Knowledge Base / Linux & Server Basics / Understanding Linux File Permissions and Ownership on a Web Server (Without Locking Yourself Out)
  1. Home
  2. »
  3. Knowledge Base
  4. »
  5. Linux & Server Basics
  6. »
  7. Understanding Linux File Permissions and…

Understanding Linux File Permissions and Ownership on a Web Server (Without Locking Yourself Out)

Table of Contents

Understanding Linux File Permissions and Ownership on a Web Server (Without Locking Yourself Out)

Who This Guide Is For (And How It Stops You Locking Yourself Out)

File permissions on Linux can feel mysterious until something breaks. Perhaps a WordPress update fails, an upload directory stops working, or you run a command from a forum and suddenly your site shows “403 Forbidden”. This guide is here to make sense of what is happening, and to help you change permissions and ownership without locking yourself out of your own server.

Typical situations: from shared hosting to your own VPS

This article is useful if you are:

  • On shared or control panel based hosting, and keep seeing “permission denied” errors.
  • Running a small VPS with a LAMP or LEMP stack and want to understand how Apache, Nginx and PHP-FPM interact with files.
  • Hosting WordPress or WooCommerce and struggling with plugin or media upload problems.
  • Moving from managed hosting to an unmanaged server and want to understand what you are taking responsibility for.

If you are completely new to SSH or logging in to a server, it may help to read SSH Access for Beginners alongside this article.

What you will be able to do by the end

By the end of this guide, you should be able to:

  • Read Linux permissions with ls -l and understand what they mean.
  • Explain the difference between user, group and others on a file.
  • Use chown, chgrp and chmod safely on a web root.
  • Set sensible default permissions for a typical WordPress or PHP site.
  • Avoid the classic mistakes such as chmod -R 777 or running recursive commands in the wrong place.

When to fix it yourself and when managed hosting is safer

On an unmanaged VPS or virtual dedicated server, you are responsible for:

  • Permissions and ownership across your web roots.
  • System updates and security patches.
  • Hardening and monitoring, alongside capacity and performance planning.

For many people running one or two business sites, regularly tuning permissions, dealing with odd plugin behaviour and tracking down permission related errors can become more work than expected. In that case, Managed WordPress hosting or managed VDS can offload much of this day to day operational risk, so you focus on the site rather than the server.

For now, we will assume you want to understand what is happening, even if you later decide to hand some of it over.

The Basics: Users, Groups, Files and Processes

What a Linux user and group actually are (in plain language)

On Linux, a user is simply an account that can own files and run processes. Human users such as alice or john are one type. System and service accounts such as www-data or nginx are another.

A group is a named collection of users. Every file has one owner user and one owner group. Groups are a convenient way to allow several users to work on the same files without giving everything to everyone.

Two important files store this information:

  • /etc/passwd lists users.
  • /etc/group lists groups.

You will rarely edit these directly on a web server, but it helps to know they exist.

How web server processes run: apache, nginx, php-fpm users

Your web server software does not run as “you”. It runs as its own user, for example:

  • www-data on Debian / Ubuntu for Apache or Nginx plus PHP-FPM.
  • apache or nginx on CentOS / AlmaLinux / Rocky Linux.

When a visitor loads your site, the request is handled by:

  1. Apache or Nginx, running as a specific user.
  2. Often PHP-FPM, running pool processes as a user configured for that site or pool.
  3. These processes read and, sometimes, write files from your web root.

This means permissions must allow the web server user (or its group) to read PHP files and assets, and to write only where necessary, such as uploads or caches.

Why ownership matters for a WordPress or WooCommerce site

WordPress and WooCommerce need to:

  • Read your PHP files and themes.
  • Write uploaded media into wp-content/uploads.
  • Create or modify files during plugin, theme and core updates.

If your site files are owned by your SSH user but the web server user has no write permissions where needed, updates and uploads will fail. If the web server user owns everything and is too powerful, a vulnerable plugin could write to more than it should.

Ownership and groups are how you strike a balance between convenience and safety.

Reading File Permissions Safely: ls -l Explained

A simple visual breakdown of an ls -l line showing the permission bits, owner, group and filename, helping beginners map the text output to the concepts explained.

Using ls -l to inspect a directory

The safest first step when something looks wrong is to inspect, not change. To list files with detailed information, including permissions, run:

ls -l /var/www

This command:

  • Lists files in /var/www (a common web root path).
  • Shows one line per file, with permissions, owner, group, size and date.

If your web root is elsewhere, for example /home/myuser/public_html, replace the path accordingly. If you run this in the wrong directory, nothing breaks; you just see different files.

Breaking down the permission string (r, w, x for user, group, others)

A typical line from ls -l might look like this:

-rw-r--r-- 1 myuser www-data  1234 Dec  1 12:00 index.php

Read it from left to right:

  • - first character: type (- for file, d for directory).
  • rw-r--r-- next 9 characters: permissions.
  • myuser: owner user.
  • www-data: owner group.
  • Then size, date and filename.

The 9 permission characters are split into three groups of three:

  • First three: owner user permissions.
  • Next three: group permissions.
  • Last three: others (everyone else).

Within each group:

  • r means read.
  • w means write (change or delete).
  • x means execute (run) for files, or “enter / traverse” for directories.

So -rw-r--r-- means:

  • Owner: rw- can read and write.
  • Group: r-- can read only.
  • Others: r-- can read only.

Quick mental model: “who can read, who can change, who can run”

When you look at ls -l, train yourself to ask three questions:

  1. Who can read this file or directory?
  2. Who can change or delete it?
  3. Who can run it (if it is a script) or enter it (if it is a directory)?

This mental model works across all the examples in this article.

Exercise: checking your web root (e.g. /var/www)

To get a feel for your current situation, run:

cd /var/www
pwd
ls -l

This sequence:

  • cd /var/www changes directory to your web root (adjust if different).
  • pwd prints the current directory so you confirm where you are.
  • ls -l lists the files with details.

Nothing is modified by this. You can safely do this in production. You might want to copy and paste the output into a note for later, especially before you start changing anything.

Ownership: chown, chgrp and Common Web Server Patterns

An abstract diagram showing a web request flowing through nginx/Apache and PHP-FPM to the filesystem, with visual emphasis on which user account owns files and which user the web server runs as.

What owner and group mean on a web server

Every file has an owner and a group. On a web server, a common pattern is:

  • Files are owned by your SSH or SFTP user, so you can edit and deploy code.
  • Group is set to the web server group, so the web server can read and, where needed, write.

For example:

-rw-r--r-- 1 deploy www-data  1234 Dec  1 12:00 index.php

Here:

  • User deploy owns the file and has write access.
  • Group www-data can read the file.
  • Others can also read the file.

Typical ownership setups for WordPress

One-user model on small VPS (e.g. user: www-data group)

On a simple VPS, administrators sometimes run everything under one user, often www-data:

-rw-r--r-- 1 www-data www-data 1234 Dec  1 12:00 index.php

This is straightforward but means the web server user owns all files. You will usually connect over SSH as a different user and use sudo to edit or deploy files under www-data.

It keeps things simple but can blur the line between “code you deploy” and “data the web server writes”.

Panel based hosting (cPanel style account users)

On panel based hosting such as cPanel or Plesk, each site (or account) typically has its own user, like myaccount:

-rw-r--r-- 1 myaccount myaccount 1234 Dec  1 12:00 index.php

The web server is configured so it runs PHP as this user, not a shared user like www-data. This isolates sites from one another and simplifies ownership: everything is owned by the account user.

In this environment, using commands like chown is rarely needed and often handled by the control panel. If you find yourself running recursive chown via SSH frequently, it can be a sign that panel tools or managed hosting might be more comfortable.

How to safely use chown without breaking everything

chown changes the owner and optionally the group of files. Used carefully on the correct directory, it is very useful. Used at the root of the filesystem, it can break the server.

To change ownership of a single file:

sudo chown myuser:www-data index.php

This command:

  • Changes the owner of index.php to user myuser and group www-data.
  • Requires sudo if you are not already the owner.

To apply this recursively to a whole directory tree, you add -R. This is powerful and potentially destructive if used in the wrong place, so be deliberate:

cd /var/www/mysite
pwd
sudo chown -R myuser:www-data .

Here:

  • cd and pwd confirm you are in the correct web root.
  • sudo chown -R myuser:www-data . changes owner and group for everything under the current directory.

To “undo” an incorrect chown, you must run it again with the right users/groups, which is why keeping notes of your intended ownership is important.

Danger zone: recursive chown on / or system paths

This is one of the most dangerous mistakes on Linux:

sudo chown -R myuser:myuser /

This will attempt to change ownership of every file on the system. Many system files must be owned by specific users such as root or service accounts. Changing them can make the system unbootable or stop services from starting.

Safer habits:

  • Never use chown -R with /, /etc, /var or similar as the path.
  • Use cd and pwd to position yourself inside the correct site directory, then run chown -R with . as the path.
  • Keep a record of your “correct” ownership scheme so you can restore it deliberately if something changes.

chmod Without Fear: What 644, 755 and 777 Actually Do

Symbolic vs numeric permissions (u/g/o, +x vs 755)

There are two common ways to set permissions:

  • Symbolic, such as chmod u+x script.sh, which says “add execute for the user”.
  • Numeric, such as chmod 755 script.sh, which sets all three permission groups in one go.

The numeric form uses three digits: owner, group and others. Each digit is the sum of:

  • 4 for read.
  • 2 for write.
  • 1 for execute.

So:

  • 7 means 4 + 2 + 1 = read, write, execute.
  • 6 means 4 + 2 = read, write.
  • 5 means 4 + 1 = read, execute.
  • 4 means read only.

Understanding common modes: 600, 644, 664, 700, 755, 775, 777

  • 600: owner can read/write, group and others have no access. Good for private config files or SSH keys.
  • 644: owner can read/write, everyone else can read. Typical for public web files (HTML, CSS, JS, most PHP files).
  • 664: owner and group can read/write, others can read. Useful where both owner and group need to modify files.
  • 700: owner can read/write/execute, no access for others. Good for private directories or scripts.
  • 755: owner can read/write/execute, others can read/execute. Standard for web directories and executable scripts that others can read but not modify.
  • 775: owner and group can read/write/execute, others can read/execute. Useful when a shared group maintains scripts or directories.
  • 777: everyone can read/write/execute. Convenient but usually too open, especially on shared servers.

Why “chmod -R 777” is almost always a bad idea

When a plugin refuses to update or WordPress cannot write to a directory, it is tempting to run:

chmod -R 777 wp-content

This makes the directory and all files world writable. It often “fixes” the symptom, because now any process can write there. However:

  • Any code executed by the web server can now modify files, which widens the impact if a plugin or theme is compromised.
  • On shared hosting, other users might be able to write to your files, depending on the underlying configuration.

It is usually better to adjust ownership and group membership or use 755/775 on directories and 644/664 on files than to rely on 777.

Examples: adjusting one file vs a whole directory tree

To change a single file to 644:

chmod 644 index.php

To change a directory to 755:

chmod 755 wp-content

To apply recursively, use -R, but note that directories and files usually need different permissions. We will look at safe patterns for that shortly.

If you “over tighten” permissions and something breaks, you can revert using your notes on default patterns or by mirroring the permissions from a known working site.

Safe Default Permissions for a Typical Web Root

General pattern: directories 755, files 644

For a typical PHP / WordPress site, a solid starting point is:

  • Directories: 755.
  • Files: 644.

This means:

  • Owner can read and write all files and directories.
  • Everyone can read files and traverse directories, which is required for normal web access.

Extra sensitive files: wp-config.php, .env and SSH keys

Some files should be more restricted:

  • wp-config.php contains database credentials and keys.
  • .env files often contain secrets for frameworks.
  • SSH keys under ~/.ssh must be private to function correctly.

For these kinds of files, 600 is often more appropriate:

chmod 600 wp-config.php

This allows only the owner to read and write. As long as the web server runs as the file owner (or reads through PHP which runs as that user), this will work.

Be careful not to over restrict. If you set 000 on a file, nothing can read it, including the web server.

Scripts that must be executable (cron scripts, shell tools)

Some scripts need the execute bit set:

  • Custom shell scripts called from cron.
  • Maintenance tools in your project.

If you have a script scripts/backup.sh, you might use:

chmod 700 scripts/backup.sh

This allows only the owner to run it. If multiple admins share a group that should run it, 750 or 770 may be appropriate, combined with suitable group ownership.

One-liner patterns to reset a broken tree (with explanations)

When permissions across a site have become inconsistent, you can reset them using find. These commands assume your site is at /var/www/mysite.

1. Reset directories to 755

cd /var/www/mysite
pwd
find . -type d -exec chmod 755 {} \;

Explanation:

  • cd and pwd confirm you are in the correct directory.
  • find . -type d finds all directories under the current path.
  • -exec chmod 755 {} \; runs chmod 755 on each directory found.

2. Reset files to 644

find . -type f -exec chmod 644 {} \;

This sets all regular files to 644. If you have specific scripts that need execute permissions, you can reapply them afterwards.

These patterns are generally safe within your site directory. If you apply them at / or across system directories, they can cause serious problems, so always use cd and pwd to anchor yourself in the right place.

Making Permissions Work With PHP, WordPress and Plugin Updates

How PHP-FPM and web server users write to disk

When WordPress writes to disk, it usually does so through PHP. With PHP-FPM, each pool can run as a different user. Common patterns include:

  • PHP-FPM pool runs as www-data and owns or has group write access to specific directories like wp-content/uploads.
  • PHP-FPM pool runs as the site user (panel based setups) and therefore can write wherever that user can.

If PHP-FPM runs as www-data but your files are owned by deploy:deploy with 644/755 permissions, WordPress will not be able to write anywhere that does not grant www-data write access via group or others permissions.

Directories WordPress needs to write to (uploads, cache, updates)

WordPress typically needs write access to:

  • wp-content/uploads and its subdirectories.
  • wp-content/cache or similar, for caching plugins.
  • Temporarily, plugin and theme directories during updates.

On a small VPS where the site user is myuser and PHP-FPM runs as www-data, a common pattern is:

  • Ownership: myuser:www-data for the whole web root.
  • Directories: 755 or 775.
  • Files: 644 or 664.

To allow both myuser and www-data to write, you can use group write (664/775) and ensure your user is in the www-data group.

Using groups to allow both your SSH user and the web server to work safely

Suppose:

  • Your SSH user is deploy.
  • The web server user and group are www-data.

You can:

  1. Add deploy to the www-data group.
  2. Set the group of the web root to www-data.
  3. Use group write permissions where needed.

To add deploy to www-data (Debian/Ubuntu style):

sudo usermod -aG www-data deploy

This modifies the group membership of deploy. You will need to log out and back in for it to take effect. Used incorrectly on the wrong user, this will not usually break the system, but keep track of which users are added to powerful groups.

Then in the site directory:

cd /var/www/mysite
pwd
sudo chown -R deploy:www-data .
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;

This results in:

  • Owner: deploy has full control.
  • Group: www-data has read/write on all files and directories.
  • Others: read access only.

This pattern works well where WordPress needs to manage its own updates and file writes.

Common symptoms of wrong permissions in WordPress and WooCommerce

Symptoms that often point to permissions or ownership issues include:

  • “Could not create directory” during plugin or theme installation.
  • Media uploads fail with “Unable to create directory” errors.
  • White screen or 500 errors immediately after changing file or directory permissions.
  • WooCommerce unable to write logs or generate temporary files for exports.

When this happens, check:

Step-by-Step: Fixing a Broken Web Root Without Locking Yourself Out

A high level tree style graphic of a web root directory with folders and files, visually indicating different permission levels for directories, files and sensitive configuration files.

1. Stop, check backups and confirm you have console or provider support

Before large changes on a live site:

  • Make sure you have a recent backup or snapshot from your VPS or VDS provider.
  • Confirm you can reach a console (for example, via your provider’s control panel) in case SSH stops working.
  • Note down the current ownership and permissions for a few key paths (ls -l output) so you can reference them later.

If the site is very important and downtime is costly, this is where a managed environment or managed virtual dedicated server can be worth considering.

2. Identify the correct user and group for your site

Find out:

  • Which user owns most of the site files.
  • Which user the web server or PHP-FPM is running as.

In your web root directory:

cd /var/www/mysite
pwd
ls -ld .

This shows the ownership of the directory itself.

To see which user Apache is using on a Debian/Ubuntu system, you can run:

ps aux | grep -E 'apache2|httpd|nginx' | head

Look at the user column for the main processes. This command is read only and safe. It simply lists processes and filters the output.

3. Reset ownership safely for just the site directory

Once you know which user and group you want, set ownership at the site root. For example, if you decide:

  • Owner user: deploy.
  • Group: www-data.

Then:

cd /var/www/mysite
pwd
sudo chown -R deploy:www-data .

Check a few entries afterwards:

ls -l | head

This should now show deploy www-data for owner and group.

4. Reset directory and file permissions separately

Now set a sensible baseline:

cd /var/www/mysite
pwd

# Directories
find . -type d -exec chmod 755 {} \;

# Files
find . -type f -exec chmod 644 {} \;

If you want WordPress to manage updates and uploads more easily in a shared group model, use 775/664 instead of 755/644 and ensure the group is the web server group, as described earlier.

After resetting, tighten sensitive files such as wp-config.php:

chmod 600 wp-config.php

Check that the file remains owned by the correct user and group with ls -l wp-config.php.

5. Test carefully: SSH access, web access, WordPress updates

After changes, test in this order:

  1. SSH access: confirm you can still log in and cd into your site.
  2. Web access: load the homepage and a few internal pages anonymously.
  3. Admin actions: log into WordPress, try a media upload, and if appropriate, a small plugin update.

If something fails, note the exact error message, check permissions on the relevant directory, and review logs. Avoid immediately loosening everything to 777; instead, adjust ownership or group write on specific paths that need it.

Avoiding Common Permission Mistakes on a Live Server

Running chmod or chown from the wrong directory

One of the easiest mistakes is running a recursive command where you think you are in /var/www/mysite but are actually in /var/www or even your home directory.

Safer pattern for any destructive command (recursive or affecting many files):

cd /var/www/mysite
pwd
echo "About to change permissions in: $(pwd)"
# Now run your chmod/chown here

echo is harmless and forces you to look at the target path one more time.

Mixing up root and your normal user

Running commands as root or with sudo gives you the power to change anything, including things that should not be touched. Where possible:

  • Work as a normal user and only use sudo when necessary.
  • Prefer adjusting ownership so that your normal user can manage web files without constantly becoming root.

If you find you must run many commands as root to manage your site, it may be a sign that ownership is not set up well or that a managed environment could reduce friction.

Breaking log directories or tmp directories by accident

Log and temporary directories, such as /var/log and /tmp, have specific ownership and permissions. Changing them recursively with broad patterns like:

sudo chmod -R 755 /var

can stop services from writing logs or using temp space correctly.

Keep your changes scoped:

  • Limit chown and chmod to your web root directories.
  • Use patterns like cd /var/www/mysite and then work with ., not /var or /.

Practical safety habits: dry runs, echoing the directory, using sudo sparingly

Some practical habits that help:

  • Dry runs: For find, test the selection first:
    find . -type d | head

    Then run with -exec once you are sure the right items are listed.

  • Echo the directory: As shown earlier, use pwd and echo before any recursive command.
  • Record changes: Keep a simple log of commands you run when changing ownership and permissions, so you can reverse or repeat them reliably.

For broader safe operating habits on new servers, our article First 48 Hours on a New Linux VPS is a helpful companion.

When Managed Servers or Panel Hosting Are the Safer Option

Signs you should not be hand tuning permissions regularly

It may be time to consider a more managed approach if:

  • You find yourself repeatedly fixing permission errors after every update or plugin change.
  • You feel uneasy running commands like chown -R on a production server.
  • Your main work is content and business tasks, not server administration.
  • Downtime or mistakes have a direct financial impact and you want to reduce operational risk.

How managed VDS or managed WordPress hosting reduce permission headaches

A managed virtual dedicated server or Managed WordPress hosting can:

  • Provide a standard, well tested layout for users, groups and permissions.
  • Handle OS updates, security patches and many everyday configuration tasks.
  • Help diagnose and correct permission problems as part of support, rather than you having to debug everything yourself.

This is not necessary for everyone. Many people are comfortable managing an unmanaged VPS once they understand the basics, particularly if they have a test server to practise on and good backups. The important thing is to choose a level of responsibility that fits your time and comfort level.

Next steps and further reading

Permissions and ownership are one part of running a secure and reliable server. You may also find these topics helpful:

If you would rather not think about permissions and ownership on a daily basis, exploring G7Cloud virtual dedicated servers or Managed WordPress hosting is a natural next step. You keep control of your sites while letting a managed platform or team handle much of the underlying server complexity.

Table of Contents

G7 Acceleration Network

The G7 Acceleration Network boosts your website’s speed, security, and performance. With advanced full page caching, dynamic image optimization, and built-in PCI compliance, your site will load faster, handle more traffic, and stay secure. 

WordPress Hosting

Trusted by some of the worlds largest WooCommerce and WordPress sites, there’s a reason thousands of businesses are switching to G7

Related Articles