How to fix Error: mkdir(): Permission denied when running composer

Quick Answer:

For security reasons, lets keep root as the owner and just allow ourselves to read, write, and execute within the area which we will be working in.

  1. Change directories

    cd /var/www/

  2. Change group ownership

    sudo chown -Rv root:$USER .

  3. Add priviledges to our group

    sudo chmod -Rv g+rw .

  4. For the grand finale, go ahead and create your new laravel project

    composer create-project laravel/laravelprojectName--prefer-dist

Congratulations, We're done. :)

In-Depth Explanation

Explanation behind the solution: By default you have two users; root and $USER(this is the global variable, but the actual name is whatever you put as your username). Every user created comes with a group as well. So if my username is john, I have a group called john. There are many ways to solve this problem but I perfer this route for a few reasons:

  1. I still want root to be the owner of the files for security reason.

  2. I am working in a localhost so there shouldn't be any other (guest)users writing on my files.

In order to achieve this we will need to edit the group ownership and add the proper permissions. We will leave the others as is and only allow them to read and execute the files.

So lets get started:

  1. I like being in the directory that I am making changes to in order to avoid mistakes so first we will need to enter the the directory which we will be working in.

    cd /var/www/

  2. We will need to change the group ownership of the directories which we will be working in. Starting from the directory which we are in and all the future directories and files we will create underneath this directory. So basically any children directories from now on will be own by our group.

    sudo chown -Rv root:$USER .

chown = command to change owner.

-R = Recursive - This is basically stating to perform the same command to all the directories within this directory.

-v = verbose - we are stating here to keep us updated by showing us what is actually happening.

root:$USER = This is were we are setting the ownership. The first word before the colon(:) states the root will be the single owner. The second word after the colon(:) states that the group owner will be $USER(the current user).

. = This just means 'here, in this directory'.

  1. Now we are going to add the right privileges to our group. Keep in mind this is where we allow root to be the primary owner while ONLY allowing ourself's to create changes(of course, besides root). As I mentioned before, this does not allow other users to create any changes what so ever.

    sudo chmod -Rv g+rw .

chmod = command to change modifications, in this case, privileges.

-Rv = Recursive & Verbose

g = this states who will receive the modifications. In our case g-group Other options are u-user and o-other.

+ = symbolizes add

r = symbolizes read

w = symbolizes write

  1. Now we are done. Try creating a new laravel project.

    composer create-project laravel/laravelprojectName` --prefer-dist

Note: If this is not working, enter the command ls -al | grep $USER while inside the /var/www/ directory.

If you get this: drwxrw-r-x

You are missing the executable(x) privilege for the group. The first x is for the user and last x is for others. There should be middle x for the group.

Run the following command and you should be all set to go:

sudo chmod -Rv g+x .

Now if you run ls -al | grep $USER, you should get:

drwxrwxr-x


  1. add "www" group and add your user to this group

    sudo groupadd www
    sudo usermod -a -G www ec2-user
    
  2. logout/login

  3. set ownership and write permissions

    sudo chown -R root:www /var/www
    sudo chmod 2775 /var/www
    find /var/www -type d -exec sudo chmod 2775 {} +
    find /var/www -type f -exec sudo chmod 0664 {} +
    

Referencing: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html