Correct file permission using local server

3 minute read

Solution 1

Add yourself to the www-data group and set the setgid bit on the /var/www directory such that all newly created files inherit this group as well.

    sudo gpasswd -a "$USER" www-data

Correct previously created files (assuming you to be the only user of /var/www):

    sudo chown -R $USER:www-data /var/www
    find /var/www -type f -exec chmod 0660 {} \;
    sudo find /var/www -type d -exec chmod 2770 {} \;

(even safer: use 640 or 2750 and manually chmod g+w file-or-dir that needs to be writable by the webserver)

Solution 2

Create a symlink for each project to your home directory. Say your project is located at ~/projects/foo and you want to have it located at /var/www/foo, run:

    sudo ln -sT ~/projects/foo /var/www/foo

If your home directory has no execute bit (descend) set for other (for security reasons), change the group of it to www-data, but set the execute bit only (no read/write). Do the same for the ~/projects folder as it may contain other projects than www. (You don’t need sudo if you have previously added your user to the www-data group.)

    sudo chgrp www-data ~ ~/projects
    chmod 710 ~ ~/projects

Set the group to www-data on ~/projects/foo and allow the webserver to read and write to files and files+directories and descend into directories:

    sudo chgrp www-data ~/projects/foo
    find ~/projects/foo -type f -exec chmod 660 {} \;
    find ~/projects/foo -type d -exec chmod 2770 {} \;

Even safer: use 640 and 2750 by default and manually chmod files and directories that need to be writable by the webserver user. The setgid bit should be added only if you want every newly created file in ~/projects/foo to be accessible by the group.

From now on, you can access your site at http://localhost/foo and edit your project files in ~/projects/foo.

Solution 3 (my preferred solution)

Use virtual host for managing projects Create vhost configuration file in /etc/apach2/sites-available e.g foo.conf

<VirtualHost 	foo.local:80>
	ServerName foo.local
	ServerAlias foo.local
	DocumentRoot "~/projects/foo"
	<Directory "~/projects/foo">
		Options FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
	CustomLog	/var/log/apache2/foo.local-access.log combined
	ErrorLog	/var/log/apache2/foo.local-error.log
</VirtualHost>

Add line to /etc/hosts 127.0.0.1 foo.local

Set group to www-data on ~/projects/foo and allow the webserver to read and write to files and files+directories

    sudo chgrp www-data ~/projects/foo
    find ~/projects/foo -type f -exec chmod 660 {} \;
    find ~/projects/foo -type d -exec chmod 2770 {} \;

Enable configuration

    sudo a2ensite foo.conf

” From now on you can access your website at http://foo.local

Note: file permision explanation

This explanation is so good that I shamelessly will copy it here

  • Permissions are specified for three categories of users:
    • User: the owner of the file
    • Group: the members of the group associated with the file
    • All: everyone
  • Per category, the following permissions can be granted:
    • r (read): the users in the category are allowed to read the file
    • w (write): the users in the category are allowed to change the file
    • x (execute): the users in the category are allowed to run the file

That means that permissions can be represented by 9 bits (3 categories with 3 permissions each):

  User Group All
Permissions r, w, x r, w, x r, w, x
Bit 8, 7, 6 5, 4, 3 2, 1, 0

The permissions of a single category of users are stored in 3 bits:

Bits Permissions Octal digit
000 ––– 0
001 ––x 1
010 –w– 2
011 –wx 3
100 r–– 4
101 r–x 5
110 rw– 6
111 rwx 7

That means that octal numbers are a compact representation of all permissions, you only need 3 digits, one digit per category of users. Two examples:

755 = 111,101,101: I can change, read and execute; everyone else can only read and execute. 640 = 110,100,000: I can read and write; group members can read; everyone can’t access at all.

Leave a Comment