Composer is a PHP dependency manager that’s used in just about any modern PHP application, and it works similarly to how Bundler works for Ruby.
Even though Composer itself gives you a warning about not running it as root, lots of people disregard this warning and run it as root anyway. We run into this issue a lot on my open source asset management project, Snipe-IT, so I figured I’d write up how to fix this if you inadvertently (or advertently) ran composer as root.
“Installing Composer” vs “Composer Install”
Many people run Composer as root because they misunderstand how Composer works. If you installed Composer globally, it wouldn’t be odd for you to have to install it as root – meaning the Composer binary itself.
But, and here’s the tricksy part, installing Composer is not the same thing as
composer install. Installing Composer means that the Composer dependency management tool is now installed on your server, while
composer install is a specific command you send to Composer to have it actually pull down those dependencies, based on the
composer.lock file that was (usually) provided by whatever software you’re trying to set up. If you install Composer globally, you can use the same Composer binary to manage dependencies for many projects – but each project will have its own composer.json and composer.lock, which Composer uses to figure out what it needs to download for you.
Let’s look at some common files and commands you might encounter when using Composer, as I think that might help clear up a few things:
composer.phar– This is your Composer binary. You will install this only once, though it may prompt you to update it occasionally. The easiest way to use Composer is to install it globally, that way it’s available anywhere in your system via the
composercommand. If it’s installed locally, you’ll have a composer.phar in your project root, and if you want to install any other PHP projects that use composer, you’ll have to download it to each project’s directory.
composer.json– This file tells Composer what libraries are required, and what version the developer of the PHP project intends for you to use, similar to the
Gemfilein Ruby or the
composer update– Unless you are a developer, you should almost never run this command. This tells Composer to grab the most recent versions of libraries specified in the
composer.jsonfile, and generate a new
composer.lockfile that locks down those library versions.
composer install– As a non-developer who is just trying to install dependencies, this is the command you typically want. composer install tells Composer to use the
composer.lockfile that the developer provided, and download the specific versions of each library. This is important, because sometimes older or newer versions of a library might not work with the PHP project. The developer’s
composer.lockfile makes sure you’re downloading the version of each library that they have tested and confirmed works with the project. The libraries will be downloaded into a folder (usually called
vendors) in the PHP project root.
You might install the Composer binary as root (and then move it to
/usr/local/bin so it’s available globally), but you pretty much never want to run
composer install as root.
Composer tries to prevent you from running
composer install as root/admin by throwing up a big fat warning, but if you’ve already run it as root once, you may end up with some permissions errors if you try to run it as non-root, which makes some people give up and just always run it as root.
If you’re seeing permissions errors when trying to run composer install as a non-privileged user, someone somewhere probably ran it as root at some point, which means root owns some of the generated files. That’s a pain in the ass to fix, but not impossible.
I wish to repent and make amends for my past transgressions and no longer run Composer as root
Great! It’s not actually that hard to make things right if you ran Composer as root, but it can be a little tricky to find all of the weird caches and config directories it hides within your system.
When you installed Composer, it created a
.composer directory somewhere in your system, usually in your home directory. So for example, on a Mac, I’d look in
/Users/snipe/.composer. On linux, I’d look in
/home/snipe/.composer. Remember that it’s a directory that starts with a dot, which on many operating systems means it’s a hidden file.
The contents of the
.composer directory usually look something like this:
For the sake of this example, let’s say my non-privileged user is
snipe. This user is part of the apache group, so it can read, write and execute any files where the group is permitted to do so – for example, error logs, file upload directories, etc.
We want to make sure that the vendor directory within the project root is owned by
snipe, not by
root, otherwise if I try to run
composer install as
snipe, I’ll get permission errors, since
root owns those files and directories.
Then we also want to make sure that
.composer directory we mentioned is readable and writable by
snipe, since that directory gets updated with new cached vendors every time you run
As we mentioned above, if you initially ran Composer as root, that directory might be in
/home/root. The easiest thing to do is to delete the
.composer directory altogether – a new one will be generated when you run composer install again, and this time, since you’re running it as
snipe, it will have the correct permissions.
So our fix would look something like this:
sudo chown -R snipe.apache /var/www/html/vendor sudo rm -Rf /home/root/.composer cd /var/www/html/ composer install
Once your .composer directory and your vendors are owned by the correct user, you should be able to run Composer as a non-root user. You may also need to delete or chown the files in
bootstrap/cache (if you have any there) as they will also be owned by root.