Score:0

Wordpress asking for FTP when deleting plugins

pk flag

Wordpress asks me for FTP credentials when I try to delete or install plugins. I know it has to do with permissions but I have been unable to figure it out. I have a linux system user XYZ and apache2 run as www-data. This works:

sudo chown www-data:www-data -R /path/to/wordpress
sudo chmod 700 -R /path/to/wordpress

But it's unsafe. My initially planned configuration was:

sudo chown XYZ:www-data -R /path/to/wordpress
sudo chmmod 750 -R /path/to/wordpress
sudo chmod 770 -R /path/to/wordpress/wp-content

According to the wordpress docs, wp-content is the only folder which the webserver should have write-access to. It comprises the plugins and themes folders.

But it doesn't work. I've spent several hours researching online but nothing has helped so far and I don't know what to try anymore. What are the right permissions to allow automated updates and plugin installation, without giving the webserver write-access to everything?

edit: For whatever reason, the following does not work:

sudo chown XYZ:www-data -R /path/to/wordpress
sudo chmod 770 -R /path/to/wordpress

I thought it to be identical to the first variant above, giving www-data write-access to everything. But it doesn't do the trick.

That's my wp-config:

<?php
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'XXX' );

/** MySQL database username */
define( 'DB_USER', 'XXX' );

/** MySQL database password */
define( 'DB_PASSWORD', 'XXX' );

/** MySQL hostname */
define( 'DB_HOST', '127.0.0.1:XXX' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', 'utf8mb4_0900_ai_ci' );

define( 'AUTH_KEY',         'XXX' );
define( 'SECURE_AUTH_KEY',  'XXX' );
define( 'LOGGED_IN_KEY',    'XXX' );
define( 'NONCE_KEY',        'XXX' );
define( 'AUTH_SALT',        'XXX' );
define( 'SECURE_AUTH_SALT', 'XXX' );
define( 'LOGGED_IN_SALT',   'XXX' );
define( 'NONCE_SALT',       'XXX' );

/**#@-*/

/**
 * WordPress database table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'XXX';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the documentation.
 *
 * @link https://wordpress.org/support/article/debugging-in-wordpress/
 */
define( 'WP_DEBUG', false );

/* Add any custom values between this line and the "stop editing" line. */



/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

This is my php.ini excluding comments:

engine = On

short_open_tag = Off

precision = 14

output_buffering = 4096

zlib.output_compression = Off

implicit_flush = Off

unserialize_callback_func =

serialize_precision = -1

open_basedir = "/var/www/"

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,show_source,highlight_file,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,

disable_classes =

zend.enable_gc = On

zend.exception_ignore_args = On

expose_php = Off

max_execution_time = 30

max_input_time = 60

memory_limit = 128M

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

display_errors = Off

display_startup_errors = Off

log_errors = On

log_errors_max_len = 1024

ignore_repeated_errors = Off

ignore_repeated_source = Off

report_memleaks = On

variables_order = "GPCS"

request_order = "GP"

register_argc_argv = Off

auto_globals_jit = On

post_max_size = 256M

auto_prepend_file =

auto_append_file =

default_mimetype = "text/html"

default_charset = "UTF-8"

doc_root =

user_dir =

enable_dl = Off

file_uploads = On

upload_tmp_dir = "/tmp"

upload_max_filesize = 250M

max_file_uploads = 20

allow_url_fopen = Off

allow_url_include = Off

default_socket_timeout = 60

cli_server.color = On

pdo_mysql.default_socket=

SMTP = localhost

smtp_port = 25

mail.add_x_header = Off


odbc.allow_persistent = On

odbc.check_persistent = On

odbc.max_persistent = -1

odbc.max_links = -1

odbc.defaultlrl = 4096

odbc.defaultbinmode = 1

mysqli.max_persistent = -1

mysqli.allow_persistent = On

mysqli.max_links = -1

mysqli.default_port = 3306

mysqli.default_socket =

mysqli.default_host =

mysqli.default_user =

mysqli.default_pw =

mysqli.reconnect = Off

mysqlnd.collect_statistics = On

mysqlnd.collect_memory_statistics = Off

pgsql.allow_persistent = On

pgsql.auto_reset_persistent = Off

pgsql.max_persistent = -1

pgsql.max_links = -1

pgsql.ignore_notice = 0

pgsql.log_notice = 0

bcmath.scale = 0

session.save_handler = files

session.use_strict_mode = 0

session.use_cookies = 1

session.use_only_cookies = 1

session.name = PHPSESSID

session.auto_start = 0

session.cookie_lifetime = 0

session.cookie_path = /

session.cookie_domain =

session.cookie_httponly =

session.cookie_samesite =

session.serialize_handler = php

session.gc_probability = 0

session.gc_divisor = 1000

session.gc_maxlifetime = 1440

session.referer_check =

session.cache_limiter = nocache

session.cache_expire = 180

session.use_trans_sid = 0

session.sid_length = 26

session.trans_sid_tags = "a=href,area=href,frame=src,form="

session.sid_bits_per_character = 5

zend.assertions = -1

tidy.clean_output = Off

soap.wsdl_cache_enabled=1

soap.wsdl_cache_dir="/tmp"

soap.wsdl_cache_ttl=86400

soap.wsdl_cache_limit = 5

ldap.max_links = -1

I installed php like this:

sudo apt install php libapache2-mod-php php-mysql

Does that help @GeraldSchneider ?

Tim avatar
gp flag
Tim
It's really fiddly. There's documentation here https://wordpress.org/support/article/changing-file-permissions/
lampstackxyz avatar
pk flag
I've read that. Doesn't help.
Tim avatar
gp flag
Tim
I deleted the answer that wasn't quite right. Unfortunately you're probably going to have to learn about Unix permissions and Wordpress requirements, or find a good tutorial. I always find it difficult when I have to do it, which is why I script it.
in flag
I don't think your problem is the filesystem, every variant you posted should work. Please add your PHP configuration and your wp-config.php. Is PHP loaded as a module or via fpm?
lampstackxyz avatar
pk flag
@GeraldSchneider I put those details in the original question. Do you have any idea why chown XZY:www-data with chmod 770 does not work, but chown www-data:www-data chmod 700 does? I spent all night yesterday reading blogs, forums... I don't get it.
Score:0
ar flag

Add

define('FS_METHOD','direct');

to your wp-config.php file.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.