9. Set proper permissions for /var/www and its subdirectories

by Double Bastion - Updated January 27, 2022

First of all we’ll create the /var/www directory, where all the websites and web applications will have their files stored:

mkdir /var/www

All the websites and applications will have their directories located inside /var/www and not inside /var/www/html or elsewhere.

If you want to avoid getting errors or being asked for your FTP credentials when updating WordPress, when installing or updating themes and plugins or when uploading pictures to your websites, you will need to set some specific permissions and ownership on the /var/www directory and on all the websites’ directories located inside. The same ownership and permissions scheme will also apply to all the applications whose directories are located inside /var/www .

The official WordPress documentation suggests that the optimal ownership and permissions for a website’s directory are as follows: the website’s directory (of the form /var/www/example.com) and all its subdirectories and files should be user owned by a user different from the web server user (www-data). Also, it advices to give user www-data read permission to all the content of /var/www/example.com, but to give it write permission only where it is strictly necessary, namely, to some subdirectories of /var/www/example.com/wp-content. These subdirectories are not all mentioned, because they can differ from one installation to another.

Although more secure in principle, the ownership and permissions proposed by the WordPress documentation are exagerated. If you implement them, you will find that you may be able to update themes and plugins from within your WordPress dashboard, but you won’t be able to update WordPress from your dashboard, or to receive the automatic updates (for minor versions), that are enabled by default. WordPress updates will fail, because usually, during these updates, the web server user, www-data, needs to modify files in the root directory of WordPress (like wp-cron.php, wp-settings.php, wp-signup.php, etc.) and possibly in other directories different from wp-content, so, in principle, it needs write access to /var/www/example.com and all its content. The solution to this problem, in their opinion, would be to change permissions for www-data right before every WordPress update, so that www-data can have write access to /var/www/example.com and all the subdirectories and files inside, then, after the update is completed, restrict permissions again, so that the www-data user has write access only to some subdirectories of /var/www/example.com/wp-content. Another awkward solution proposed by other sysadmins would be to disable automatic updates and run updates using git or composer or WP CLI.

While many ownership and permissions schemes may be possible in theory, each with its supposed benefits, in practice, at least in the context described in this guide, where you have exclusive access to a remote server and you take all the common sense security measures (like installing only plugins and themes from wordpress.org or from other trusted third parties, keeping WordPress up-to-date, etc.) the best ownership and permissions strategy is the one that we recommend below (and implement in this guide). You can set the right ownership and permissions by running:

chown root:root /var/www
chmod 755 /var/www

chown -R www-data:www-data /var/www/example.com
find /var/www/example.com -type d -exec chmod 750 {} +
find /var/www/example.com -type f -exec chmod 640 {} +

where example.com is the domain of your WordPress website. Please note that these permissions are optimal for all WordPress websites that you will host, and also for all applications (Nextcloud, Dolibarr, Roundcube, Matomo, etc.) whose directories will be located inside /var/www. For web applications, the ownership/permissions discussion goes along the same lines as for WordPress. Some sysadmins suggest that making www-data the owner of the directories is not safe, etc., etc., but in practice and in the context described in this guide, if you follow their route and make a different user owner of the applications’ directories and give www-data only read permission to those directories and their content, you will always have problems when uploading pictures, when updating plugins, when updating the applications themselves or when performing other operations. The official Nextcloud documentation also recommends making www-data the owner of the web application’s directory and giving it write access to everything inside. This is a perfectly valid ownership/permissions scheme, if the application is well-built and you implement all the common sense security measures, at least in the context described in this guide, where you have exclusive access to the server.

With the ownership and permissions from above, you will be able to update WordPress from its dashboard, to receive automatic updates, to install new themes and plugins from the admin area, to update themes and plugins, to upload pictures to your media library, to do similar operations in your web applications, and all these without getting ‘permission denied’ or other types of errors and without being asked for FTP credentials.

We will mention again the ownership and permissions from above in the chapters that explain how to install WordPress or the web applications.

Using the ownership and permissions from above, if you want to log in to your remote server via FTP and make changes to the directories or files inside /var/www, you will first have to give your FTP user (we describe in the next chapter how to add a FTP user and group) write access to all the content of /var/www . You can do this easily by running:

chown -R ftpuser:www-data /var/www/*

Then, when you finish your work, you will have to revert to the previous ownership with:

chown -R www-data:www-data /var/www/*

9.1. Give other users access to subdirectories of /var/www

If you want to give a user, let’s say a developer, access to one of your websites’ directories, first add a new user, without shell access and without a home directory, with the name of that person, let’s say john:

adduser --shell /bin/false --no-create-home john

Add the user john to the FTP group ftpgroup (in the next chapter we explain how to install a FTP server and add a FTP group), in order to allow him to access the website directory via FTP, upload files and make changes:

adduser john ftpgroup

Next, change the ownership of the website directory to which you want to give access, like this:

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

Now, since he is the owner of everything inside the example.com directory, john can make any changes to the files and directories inside example.com. However, he will not be able to make any changes to other subdirectories of /var/www, since he is not their owner and is not a member of a group with write access to those directories.

Then, after the developer has done his work, you can change the ownership and permissions for the website directory to their initial state:

chown -R www-data:www-data /var/www/example.com
find /var/www/example.com -type d -exec chmod 750 {} +
find /var/www/example.com -type f -exec chmod 640 {} +

To keep everything safe, when the user john is no longer needed, it should be deleted from the system:

deluser john
You can send your questions and comments to: