During my recent AWS migration of WordPress sites, I encountered a stubborn issue where simple file operations kept failing with "Permission denied" errors. The problem manifested even with basic fopen() calls:
<?php
$handle = fopen('test.txt', 'w') or die("Can't open file");
?>
First, I verified all the standard permission configurations:
- Directory permissions set to 755 (drwxr-xr-x)
- Correct ownership throughout the entire path (/home to target directory)
- Confirmed working directory with getcwd()
- PHP script has 644 permissions and matching ownership
When basic checks didn't resolve the issue, I dug deeper into server configuration:
<?php
// Check PHP safe mode status
echo 'Safe mode: ' . ini_get('safe_mode') . "\n";
// Verify disabled functions
print_r(ini_get('disable_functions'));
// Check open_basedir restrictions
echo 'open_basedir: ' . ini_get('open_basedir');
?>
The real breakthrough came when I discovered discrepancies between command line and web execution contexts:
<?php
// Better process inspection
echo exec('ps -up '.getmypid());
// Alternative UID/GID check for web context
echo "Web server user: " . exec('whoami');
?>
Key findings:
- Files created via web had Apache ownership despite suexec configuration
- Command line execution produced correct ownership
- Process inspection revealed unexpected user context
After thorough investigation, these steps resolved the issue:
- Verify suexec configuration:
# Check suexec compilation options /usr/sbin/suexec -V
- Adjust virtual host configuration:
<VirtualHost *:80> SuexecUserGroup username groupname # Other directives... </VirtualHost>
- Implement proper directory structure:
chown -R username:groupname /home/username chmod 755 /home/username chmod 755 /home/username/public_html
To avoid similar issues in future migrations:
<?php
// Safe file operations wrapper
function safe_file_create($path, $content) {
$dir = dirname($path);
if (!is_writable($dir)) {
throw new Exception("Directory not writable: $dir");
}
$temp = tempnam($dir, 'tmp');
if (file_put_contents($temp, $content) !== false) {
if (rename($temp, $path)) {
chmod($path, 0644);
return true;
}
}
@unlink($temp);
return false;
}
?>
During my recent WordPress migration to AWS, I encountered a persistent fopen()
permission denied error that seemed to defy all standard troubleshooting approaches. The basic test case:
<?php
$handle = fopen('test.txt', 'w') or die('Can\'t open file');
?>
kept failing despite proper directory permissions (755) and correct ownership throughout the path.
- Verified directory permissions with
ls -la
- Confirmed working directory with
getcwd()
- Matched script ownership with target directory
- Disabled PHP safe mode in php.ini
- Ensured
fopen
wasn't in disabled_functions - Disabled open_basedir restrictions
The real breakthrough came when I noticed files created via web execution had Apache ownership, while CLI execution produced correct permissions. This pointed to mod_suexec misconfiguration.
Instead of relying on getmyuid()
(which shows script owner, not runtime user), use:
<?php
echo exec('ps -up '.getmypid());
?>
For AWS environments running WordPress with mod_suexec, implement these steps:
- Verify actual runtime user:
<?php // Better user detection function get_runtime_user() { return exec('whoami'); } echo 'Running as: '.get_runtime_user(); ?>
- Directory permission best practices:
# Set proper ownership recursively chown -R www-data:www-data /var/www/html find /var/www/html -type d -exec chmod 755 {} \; find /var/www/html -type f -exec chmod 644 {} \;
- WordPress-specific fixes:
# Add to wp-config.php define('FS_METHOD', 'direct'); define('FS_CHMOD_DIR', (0755 & ~ umask())); define('FS_CHMOD_FILE', (0644 & ~ umask()));
When standard approaches fail, try these advanced methods:
<?php
// Check SELinux context (if applicable)
echo exec('ls -Z '.escapeshellarg(dirname(__FILE__)));
// Test actual write capability
$testfile = 'permission_test_'.time().'.txt';
if (file_put_contents($testfile, 'test') === false) {
$error = error_get_last();
echo "Write failed: ".$error['message'];
} else {
unlink($testfile);
echo "Write successful";
}
?>
On AWS infrastructure, additional factors may include:
- EC2 instance IAM roles lacking write permissions
- EBS volume mount options restricting file operations
- Security group rules interfering with certain operations
- CloudWatch logging conflicts
Always check AWS system logs for additional clues:
tail -f /var/log/syslog | grep -i permission