When you self-host WordPress on your own VPS like Vultr or Digital Ocean you do not get a default ftp user (besides root). You do not want to use the root user or you will get permission errors. This post shows you how to correct the permission problems if you want to have an SFTP user with nginx and php-fpm.
I am using Debian 9 for this tutorial so I am assuming you are using PHP 7.
Adding SFTP User with Correct Permissions for nginx with PHP-FPM
- Create a new user with the right home folder
- ftp user is made member of www-data group
- Configure nginx to run as ftp user
- php-fpm runs as ftpuser and www-data group
- Correct permissions
Create SFTP User
Create a new ftp user, /var/www
is the home folder for the ftp user
sudo useradd -d /var/www/ ftpuser
Set the password for the ftpuser
, when you are prompted for the password you will not see characters as you type!
sudo passwd ftpuser
Add the ftpuser
to the www-data
group
sudo usermod -aG www-data ftpuser
Your new ftp user is now a member of the right group and has the right home folder
We can make the user have the primary group www-data so that becomes the group owner by default
sudo usermod -g www-data ftpuser
Change nginx User
Note: if you notice weird behavior after making this change return the user to root
and reload nginx.
Open your nginx configuration
sudo nano /etc/nginx/nginx.conf
Change the user
value to your ftpuser
# WP-Bullet.com nginx configuration
user ftpuser;
worker_processes auto;
pid /run/nginx.pid;
Verify the nginx syntax is correct
sudo nginx -t
You should get these confirmation messages
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Now nginx will run as the ftp user.
Change PHP-FPM User
Open your php-fpm configuration
sudo nano /etc/php/7.0/fpm/pool.d/www.conf
Change the user
value to your ftpuser
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = ftpuser
group = www-data
Verify the php-fpm syntax
sudo php-fpm7.0 -t
You should see this success message
[25-Mar-2017 07:05:24] NOTICE: configuration file /etc/php/7.0/fpm/php-fpm.conf test is successful
Now php-fpm is configured to run as the ftpuser.
Correcting Permissions
Recursively change the permissions for the ftpuser
‘s home folder
sudo chown -R ftpuser:www-data /var/www
Set 775
for folders so the ftpuser and www-data group can execute
sudo find /var/www/ -type d -exec chmod 775 {} +
Set 664
for files so the ftpuser and www-data group can write to files
sudo find /var/www/ -type f -exec chmod 664 {} +
Change the permissions for the /var/lib/nginx
folder
sudo chown -R ftpuser:www-data /var/lib/nginx
Change the log folder permissions as well
sudo chown -R ftpuser:www-data /var/log/nginx
Change php sessions permissions
sudo chown -R ftpuser:www-data /var/lib/php/sessions
That should do it for the permissions.
Finalizing
Now the services just need to be restarted
sudo service php7.0-fpm restart
sudo service nginx restart
You should now be able to upload files over SFTP without any permission problems.
If you still have FTP prompts then try adding these to your wp-config.php
file.
// permission fixes
define( 'FS_METHOD', 'direct' );
define( 'FS_CHMOD_DIR', ( 0775 & ~ umask() ) );
define( 'FS_CHMOD_FILE', ( 0664 & ~ umask() ) );
You can use this script as a permissions reset
USER=ftpuser
sudo chown -R ${USER}:www-data /var/www/
sudo find /var/www/ -type f -exec chmod 664 {} +
sudo find /var/www/ -type d -exec chmod 775 {} +
sudo chown -R ${USER}:www-data /var/lib/nginx
sudo chown -R ${USER}:www-data /var/log/nginx
sudo chown -R ${USER}:www-data /var/lib/php/sessions
Sources
Incomplete Chunked Encoding Error
Create Home Directory for Users
Add Linux User to Group
Connection Reset by Peer
Editing wp-config.php
when I try to connect the user to filezilla the following message appears:FATAL ERROR: No supported authentication methods available (server sent: publickey)
Sounds like you need to look at /etc/ssh/sshd_config it may have a directive requiring SSH keys as the only login method for the user
This is exactly I was looking for. It helped. Thank you very much for the great article.