wp-cli executed by www-data user to avoid Linux permission issues

In this article I’m going to share with you a trick that I use to run wp-cli as the www-data user on my Linux development environment.

wp-cli and file owner issues

I can’t imagine doing any serious WordPress development without wp-cli. It lets you automate the WordPress installation and configuration, lets you install and manage themes and plugins, post articles, and even post file-based media such as images. Whether you run it from grunt, from shell scripts, from inside docker containers, or just from the plain old shell, wp-cli rocks!

One issue I often face is that when I run wp-cli as my default Linux user, naturally all the file operations write files owned by the current user. Sometimes this is an issue, as my web files are normally owned by user www-data (in the www-data group).

In the past that meant that I had to do this a lot, in order to avoid various permission issues:

sudo chown -R www-data:www-data /var/www/wordpress

It quickly becomes tedious. There’s a better way.

finding your wp-cli installation

If you’ve followed the installation instructions, then you probably have wp-cli.phar installed as wp at /usr/local/bin/wp. In any case, you can do

which wp


whereis wp

to find its location.

running as www-data

Now on to put a setuid flag on that file and change its owner to that of your web server (usually www-data), right?

Not so fast! The astute Linux aficionado will notice that wp-cli is not a binary, even though it’s placed under a bin dir. Actually it’s a PHP CLI script:

$ head -n 1 `which wp`
#!/usr/bin/env php

Here’s what you do instead. First, run visudo with elevated privileges:

sudo visudo

This will let you edit your sudoers file. You want to allow your current user to run your script as www-data. So, add the following line: (here I’m logged in as alex, the local user I use for development)

alex ALL=(www-data) NOPASSWD: /usr/local/bin/wp

Save the file and exit. Now you can do stuff like this:

mkdir /tmp/t
cd /tmp/t
sudo -u www-data wp core download
ls -l

You should see a WordPress installation owned by the www-data user, without ever having to enter a password for www-data (by default there shouldn’t be any password for that user anyway).

Of course, having to type sudo -u www-data wp every time is also tedious. So add this to your ~/.bashrc, or better yet to your ~/.bash_aliases if you have one.

alias wp="sudo -u www-data wp"

That should do it, assuming bash is your shell. For other shells, YMMV.

wp-cli cache permission issue

But now you might notice some warnings of the form:

Warning: copy(/home/alex/.wp-cli/cache/plugin/XXXXXXXX.zip): failed to open stream: Permission denied in phar:///usr/local/bin/wp/php/WP_CLI/FileCache.php on line 164

This just means that the script, which now runs as the www-data user, cannot write to its cache directory, because that directory is owned by you. You can fix this with a simple:

sudo chown -R www-data:www-data ~/.wp-cli/

Now you can use commands such as wp plugin install foo.zip --activate and wp plugin uninstall foo --deactivate in your dev-testing lifecycle without ever worrying about your web server choking on permission issues.

Leave a Reply

Your email address will not be published. Required fields are marked *