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
or
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.
Thanks for sharing, Alex!
In your example, user “alex” is sudo, correct? And with your settings, “alex” is running WP-CLI as “www-data” (e.g. the Nginx user).
So, what do you chown/chmod for: /usr/local/bin/wp
Also, what about: /usr/local/bin/
Overall, what users & groups do you use in this environment?
I saw some related discussion on GitHub:
https://github.com/wp-cli/wp-cli/issues/3181
https://github.com/wp-cli/wp-cli/issues/1241
Anyway cheers!
Hello,
Yes user “alex” is in the sudoers list in my system.
Did you run into some problem?
Thanks for sharing the links I will have a look.
Awesome, thanks Alex! WordFence is preventing my comment from being posted so trying again with generic terms….
Is your /usr/local/bin/ also the same? Or have you ever seen permissions issues with updating WP-CPI?
We are playing with a small auto-installer for LEMP stack so were wondering about WP-CLI best permissions.
https://github.com/littlebizzy/slickstack
Would love to mention your name in Credits? Thanks!
Jesse, you are correct, this interferes with
wp cli update
:If you want to mention me in some credits please do, but I don’t have a good solution about this problem at the moment. If you do find a solution, I would love to hear about it.
Big thanks! Saved a lot of time & headache!! π
Hi there. Thanks for this post.
Regarding this issue:
$ wp cli update
Error: /usr/local/bin is not writable by current user.
The way I got around this was to create a bash alias like this:
alias wp-cli-update="sudo chown -R MYUSER:MYUSER ~/.wp-cli/ && sudo wp cli update && sudo chown -R www-data:www-data ~/.wp-cli/"
I can now use
wp-cli-update
to change the permissions on~/.wp-cli/
to what’s required, update wp-cli, and change the permissions back to what otherwise makes things work for wp commands in general.Great Tutorial…
Having the same issue.
Error: /usr/local/bin/wp is not writable by current user.
I created the alias in my .bashrc file as you instructed, but getting the same error (even after reboot).
Any suggestions?
My apologies, works great… forgot to add sudo…. going for coffee… :-/
Great to hear that you got it working!
Great post! Saved me a bunch of time, thanks.
Glad to hear it!
sudo -u www-data wp ai1wm backup
returns an error:
Error: Strange wp-config.php file: wp-settings.php is not loaded directly.
ls-las
6344 -rwxr-xr-x 1 www-data www-data 6494444 Feb 24 23:26 wp
My wp-config.php has
/** Absolute path to the WordPress directory. */
if ( !defined(‘ABSPATH’) )
define(‘ABSPATH’, dirname(__FILE__) . ‘/’);
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . ‘wp-settings.php’);