PHP cURL下载Kibana图片返回503错误,终端调用正常
Alright, let's break down why your PHP cURL script is returning a 503 and creating empty files owned by apache:apache, while the terminal cURL works perfectly. The core issue here is the context gap—your terminal runs as your user, but PHP executes under the apache process, which has different environment variables, network access rules, and permissions. Here's how to troubleshoot this step by step:
1. Proxy Configuration Mismatch
Chances are your terminal uses a proxy set via shell environment variables (like http_proxy/https_proxy), but the apache process doesn't inherit these settings. This is an extremely common gotcha.
- Compare the verbose outputs from both terminal and PHP: if the terminal shows proxy usage but PHP doesn't, that's your culprit.
- Fix this by explicitly adding proxy settings to your PHP cURL code:
curl_setopt($ch, CURLOPT_PROXY, 'http://your-proxy-host:port'); // If your proxy requires authentication: // curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'proxy-username:proxy-password');
2. Missing cURL Options from the Terminal Command
Your terminal cURL might include flags for authentication, custom headers, cookies, or a specific user-agent that your PHP script is missing. Kibana often requires these details to serve dashboard PNGs.
- Line up the terminal command's flags with PHP's cURL options:
- If you used
-u username:passwordin the terminal, addCURLOPT_USERPWDto your PHP script. - If the terminal sends custom headers (like
Accept: image/png), replicate them withCURLOPT_HTTPHEADER. - Match the
User-Agentstring—some servers block the defaultPHP-curl/xxxuser-agent. Set it to match your terminal's (e.g.,curl/7.68.0):curl_setopt($ch, CURLOPT_USERAGENT, 'curl/7.68.0');
- If you used
3. Network Access Restrictions (SELinux/IP Whitelisting)
On Linux systems, SELinux might block apache from making outgoing requests or writing to your target directory. Additionally, Kibana or your proxy might have an IP whitelist that only allows your terminal's IP, not the server's apache process IP.
- Test SELinux: Temporarily disable it with
setenforce 0and rerun your script. If it works, you'll need to add SELinux rules to allow httpd network access (e.g.,setsebool -P httpd_can_network_connect on) and/or write access to your output directory. - Check IP Whitelists: Confirm that the server running apache is allowed to connect to Kibana/proxy. If your terminal uses a different public IP than the server, that could be triggering the 503 error.
4. File Permissions (Even Though It's Creating Empty Files)
While the empty file confirms apache can write to the directory, double-check:
- The target directory has write permissions for the
apacheuser (chmod 755 or 775 should suffice). - Avoid writing to restricted paths (like
/root)—use a directory owned byapacheor with proper group permissions.
Example Fixed PHP Script
Here's a script incorporating the fixes above, plus verbose logging to help debug further:
<?php $kibanaPngUrl = "https://your-kibana-instance/dashboard/your-dashboard/png"; $outputPath = "/var/www/html/kibana_dashboard.png"; $ch = curl_init($kibanaPngUrl); // Basic cURL setup curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Replicate terminal proxy settings curl_setopt($ch, CURLOPT_PROXY, 'http://proxy.example.com:8080'); // curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'proxy-user:proxy-pass'); // Kibana authentication curl_setopt($ch, CURLOPT_USERPWD, 'kibana-admin:your-password'); // Match terminal headers and user-agent curl_setopt($ch, CURLOPT_USERAGENT, 'curl/7.68.0'); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: image/png', 'Content-Type: image/png' ]); // Enable verbose logging to debug $verboseLog = fopen('/tmp/php_curl_debug.log', 'a'); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_STDERR, $verboseLog); // Execute request $imageData = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode !== 200) { error_log("Kibana request failed with HTTP $httpCode: " . curl_error($ch)); } else { file_put_contents($outputPath, $imageData); chmod($outputPath, 0644); // Make file readable by others if needed } // Cleanup curl_close($ch); fclose($verboseLog); ?>
Final Troubleshooting Step
Compare the verbose logs from the terminal and your PHP script (/tmp/php_curl_debug.log). Look for differences in:
- Proxy usage
- Request headers
- Authentication steps
- IP address used to connect to Kibana
Any mismatch here is almost certainly the root cause.
内容的提问来源于stack exchange,提问作者Docrom

