<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[AdminsForum - Portal]]></title>
		<link>https://adminsforum.com/</link>
		<description><![CDATA[AdminsForum - https://adminsforum.com]]></description>
		<pubDate>Thu, 15 Oct 2026 05:23:39 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[Fix Primary Script Unknown PHP Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:05:11 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP page returns “File not found” and the Nginx error log says “Primary script unknown,” investigate the script path sent to PHP-FPM. Restarting PHP or raising memory limits does not correct a wrong filename.</span><br />
<br />
This guide follows the request from the website's document root to PHP-FPM. We reproduced a deliberate filename mismatch on a private aaPanel lab endpoint and verified recovery by correcting only that path. Other causes still need evidence from your own logs.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=324" target="_blank" title="">php-path-20261015.jpg</a> (Size: 124.1 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Separate this error from other 404 responses</span><br />
A missing static image, an application route that does not exist and a PHP script-path error can all produce 404. The status alone cannot distinguish them. Record the exact request path, time and timezone, then check the matching error entry.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Check the access log for the same request. Labels may differ by panel version. Our lab site's files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log
/www/wwwlogs/adminslab.com.log</code></div></div>A short SSH check, using your actual configured domain and log path, is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Do not publish complete logs or configuration dumps; redact private query strings, credentials and customer details.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify which PHP handler received the request</span><br />
Our failing error entry included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr: "Primary script unknown"
while reading response header from upstream</code></div></div>Its upstream field identified the local PHP 8.5-FPM socket used in our test. Your website may use another PHP version or socket. Confirm the site's selected PHP version and its active configuration instead of copying a socket path from a tutorial.<br />
<br />
This message shows that the FastCGI handler responded with a script problem. A connection-refused or missing-socket error points to a different investigation. Do not assume a working command-line PHP binary proves the website uses that same PHP version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare the public document root with the deployed files</span><br />
Open the site's directory settings and inspect the configured website root and, where applicable, its running directory. Then locate the application's intended public entry point in File Manager.<br />
<br />
For an illustrative deployment:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application directory: /www/wwwroot/example.com/app
Public web directory:  /www/wwwroot/example.com/app/public
Public entry point:    /www/wwwroot/example.com/app/public/index.php</code></div></div>These are examples, not paths tested on your website. Follow the application's deployment requirements. Do not point the website at a private application directory merely to make an entry file reachable; that can expose configuration or other non-public files.<br />
<br />
Check for a moved deployment, wrong folder name, filename case mismatch, missing release or a broken symlink. Linux filenames are case-sensitive. A file you can see in one directory does not prove PHP-FPM is being told to execute that same file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Trace the filename passed to PHP-FPM</span><br />
In a conventional Nginx root-based PHP setup, a configuration may construct the path like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>fastcgi_param SCRIPT_FILENAME &#36;document_root&#36;fastcgi_script_name;</code></div></div>For example, a root of /www/wwwroot/example.com/public and a script name of /index.php would form /www/wwwroot/example.com/public/index.php. Inspect the active root, matching location and included PHP configuration together. Alias-based mappings, rewrites and path-info configurations require additional care; the simple example is not a universal replacement.<br />
<br />
Do not paste an extra SCRIPT_FILENAME directive on top of the panel's existing PHP include. Find the authoritative setting first. Changing a shared include can affect other websites, so back it up and understand its scope before editing anything.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test proved</span><br />
The experiment used Nginx 1.30.5 and the installed PHP 8.5-FPM service. A separate Nginx instance listened only on loopback and accepted one exact test path. It did not alter the real website's routing.<br />
<ul class="mycode_list"><li>First, the private configuration sent a deliberately nonexistent script filename to PHP-FPM. The response was <span style="font-weight: bold;" class="mycode_b">404</span> with <span style="font-weight: bold;" class="mycode_b">File not found</span>, and the error log recorded <span style="font-weight: bold;" class="mycode_b">Primary script unknown</span>.<br />
</li>
<li>Next, we changed only that test filename to an existing, harmless PHP fixture. The response became <span style="font-weight: bold;" class="mycode_b">200</span> and contained the expected AdminsForum test message.<br />
</li>
<li>The error-log section after correction contained no new matching Primary script unknown error.<br />
</li>
</ul>
The disposable PHP file was outside the public website root. It was removed after the test, the private listener was stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration and PHP-FPM pool configuration were unchanged. The normal HTTPS website returned 200 afterward.<br />
<br />
This was a filename-mapping experiment, not a full application repair. It does not prove that your deployment has identical permissions, routing or filesystem restrictions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If the path looks correct, check access and restrictions</span><ul class="mycode_list"><li>Confirm the target file actually exists at the computed absolute path and that each parent directory can be traversed by the relevant service account.<br />
</li>
<li>Check file ownership and read permissions against your deployment's intended accounts. Do not recursively apply 777 permissions or change the ownership of the whole server.<br />
</li>
<li>If a pool uses a filesystem jail or other path restrictions, compare the path visible inside that environment. A host-side path may not mean the same thing there.<br />
</li>
<li>Look for a specific open_basedir or permission-denied message. Keep the protection enabled while correcting an unintended path or narrowly reviewing the required access.<br />
</li>
<li>For framework routes, verify the expected entry point and application rewrite rules separately. A good index.php path does not automatically fix every missing application route.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply the smallest justified correction</span><br />
Back up the affected website configuration and record the current directory settings. Correct the demonstrated mismatch in the intended site scope. If an application deployment is incomplete, restore the missing release or entry point from the correct source rather than inventing a new index.php.<br />
<br />
Validate the complete Nginx configuration before applying a configuration change. If validation fails, restore the backup and investigate the reported line. Do not disable path checks or security controls as a generic repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify both execution and exposure</span><br />
Request one safe PHP page and confirm its expected content, not just status 200. Check that the error log has no new matching entry. Test an ordinary application route and a static asset, then confirm private application files remain inaccessible through the website.<br />
<br />
Remove any temporary diagnostic file you created. Avoid leaving phpinfo pages online. Keep the original configuration backup and record which path changed so you can roll back if another route breaks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param" target="_blank" rel="noopener" class="mycode_url">Nginx FastCGI parameter documentation</a><br />
<a href="https://nginx.org/en/docs/http/request_processing.html" target="_blank" rel="noopener" class="mycode_url">How Nginx processes requests</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP page returns “File not found” and the Nginx error log says “Primary script unknown,” investigate the script path sent to PHP-FPM. Restarting PHP or raising memory limits does not correct a wrong filename.</span><br />
<br />
This guide follows the request from the website's document root to PHP-FPM. We reproduced a deliberate filename mismatch on a private aaPanel lab endpoint and verified recovery by correcting only that path. Other causes still need evidence from your own logs.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=324" target="_blank" title="">php-path-20261015.jpg</a> (Size: 124.1 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Separate this error from other 404 responses</span><br />
A missing static image, an application route that does not exist and a PHP script-path error can all produce 404. The status alone cannot distinguish them. Record the exact request path, time and timezone, then check the matching error entry.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Check the access log for the same request. Labels may differ by panel version. Our lab site's files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log
/www/wwwlogs/adminslab.com.log</code></div></div>A short SSH check, using your actual configured domain and log path, is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Do not publish complete logs or configuration dumps; redact private query strings, credentials and customer details.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify which PHP handler received the request</span><br />
Our failing error entry included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr: "Primary script unknown"
while reading response header from upstream</code></div></div>Its upstream field identified the local PHP 8.5-FPM socket used in our test. Your website may use another PHP version or socket. Confirm the site's selected PHP version and its active configuration instead of copying a socket path from a tutorial.<br />
<br />
This message shows that the FastCGI handler responded with a script problem. A connection-refused or missing-socket error points to a different investigation. Do not assume a working command-line PHP binary proves the website uses that same PHP version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare the public document root with the deployed files</span><br />
Open the site's directory settings and inspect the configured website root and, where applicable, its running directory. Then locate the application's intended public entry point in File Manager.<br />
<br />
For an illustrative deployment:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application directory: /www/wwwroot/example.com/app
Public web directory:  /www/wwwroot/example.com/app/public
Public entry point:    /www/wwwroot/example.com/app/public/index.php</code></div></div>These are examples, not paths tested on your website. Follow the application's deployment requirements. Do not point the website at a private application directory merely to make an entry file reachable; that can expose configuration or other non-public files.<br />
<br />
Check for a moved deployment, wrong folder name, filename case mismatch, missing release or a broken symlink. Linux filenames are case-sensitive. A file you can see in one directory does not prove PHP-FPM is being told to execute that same file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Trace the filename passed to PHP-FPM</span><br />
In a conventional Nginx root-based PHP setup, a configuration may construct the path like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>fastcgi_param SCRIPT_FILENAME &#36;document_root&#36;fastcgi_script_name;</code></div></div>For example, a root of /www/wwwroot/example.com/public and a script name of /index.php would form /www/wwwroot/example.com/public/index.php. Inspect the active root, matching location and included PHP configuration together. Alias-based mappings, rewrites and path-info configurations require additional care; the simple example is not a universal replacement.<br />
<br />
Do not paste an extra SCRIPT_FILENAME directive on top of the panel's existing PHP include. Find the authoritative setting first. Changing a shared include can affect other websites, so back it up and understand its scope before editing anything.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test proved</span><br />
The experiment used Nginx 1.30.5 and the installed PHP 8.5-FPM service. A separate Nginx instance listened only on loopback and accepted one exact test path. It did not alter the real website's routing.<br />
<ul class="mycode_list"><li>First, the private configuration sent a deliberately nonexistent script filename to PHP-FPM. The response was <span style="font-weight: bold;" class="mycode_b">404</span> with <span style="font-weight: bold;" class="mycode_b">File not found</span>, and the error log recorded <span style="font-weight: bold;" class="mycode_b">Primary script unknown</span>.<br />
</li>
<li>Next, we changed only that test filename to an existing, harmless PHP fixture. The response became <span style="font-weight: bold;" class="mycode_b">200</span> and contained the expected AdminsForum test message.<br />
</li>
<li>The error-log section after correction contained no new matching Primary script unknown error.<br />
</li>
</ul>
The disposable PHP file was outside the public website root. It was removed after the test, the private listener was stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration and PHP-FPM pool configuration were unchanged. The normal HTTPS website returned 200 afterward.<br />
<br />
This was a filename-mapping experiment, not a full application repair. It does not prove that your deployment has identical permissions, routing or filesystem restrictions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If the path looks correct, check access and restrictions</span><ul class="mycode_list"><li>Confirm the target file actually exists at the computed absolute path and that each parent directory can be traversed by the relevant service account.<br />
</li>
<li>Check file ownership and read permissions against your deployment's intended accounts. Do not recursively apply 777 permissions or change the ownership of the whole server.<br />
</li>
<li>If a pool uses a filesystem jail or other path restrictions, compare the path visible inside that environment. A host-side path may not mean the same thing there.<br />
</li>
<li>Look for a specific open_basedir or permission-denied message. Keep the protection enabled while correcting an unintended path or narrowly reviewing the required access.<br />
</li>
<li>For framework routes, verify the expected entry point and application rewrite rules separately. A good index.php path does not automatically fix every missing application route.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply the smallest justified correction</span><br />
Back up the affected website configuration and record the current directory settings. Correct the demonstrated mismatch in the intended site scope. If an application deployment is incomplete, restore the missing release or entry point from the correct source rather than inventing a new index.php.<br />
<br />
Validate the complete Nginx configuration before applying a configuration change. If validation fails, restore the backup and investigate the reported line. Do not disable path checks or security controls as a generic repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify both execution and exposure</span><br />
Request one safe PHP page and confirm its expected content, not just status 200. Check that the error log has no new matching entry. Test an ordinary application route and a static asset, then confirm private application files remain inaccessible through the website.<br />
<br />
Remove any temporary diagnostic file you created. Avoid leaving phpinfo pages online. Keep the original configuration backup and record which path changed so you can roll back if another route breaks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param" target="_blank" rel="noopener" class="mycode_url">Nginx FastCGI parameter documentation</a><br />
<a href="https://nginx.org/en/docs/http/request_processing.html" target="_blank" rel="noopener" class="mycode_url">How Nginx processes requests</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix 429 Too Many Requests Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-429-too-many-requests-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 12:42:27 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-429-too-many-requests-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 429 Too Many Requests response usually means a request limit has been reached. Find the layer issuing the response before changing a setting: it may be your CDN, Nginx, a security plugin or the application itself.</span><br />
<br />
This guide demonstrates one Nginx limiter on a private lab endpoint. It does not assume every aaPanel website has that rule, and it does not recommend turning off protection to make an error disappear.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=323" target="_blank" title="">nginx-429-20261015.jpg</a> (Size: 116.42 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture one safe example</span><br />
Record the URL path, time and timezone, action, response status and how often the client is sending requests. Does it affect everyone, one network, one account or only a particular API? A page can send many background requests even when a user clicks once.<br />
<br />
Inspect response headers in your browser's Network tab. If a Retry-After header is present, use its stated delay; do not assume every limiter supplies it. Avoid repeatedly submitting login forms, purchases or imports while diagnosing the problem. Save a redacted error example without session cookies, authorization headers or private query strings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the response to website logs</span><br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, find the affected site and select <span style="font-weight: bold;" class="mycode_b">Log</span>. Check <span style="font-weight: bold;" class="mycode_b">Access log</span> and <span style="font-weight: bold;" class="mycode_b">Error log</span> around the recorded time. Refresh and expand the displayed line count if needed. Labels may vary by panel version.<br />
<br />
Our lab site's logs are at:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.log
/www/wwwlogs/adminslab.com.error.log</code></div></div>Use the actual path configured for your own domain. A bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.log
tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>A 429 entry confirms that this log recorded the response, but does not by itself identify the rule. If there is no matching origin request, check the CDN or earlier proxy's events and verify you selected the correct log. Application-generated 429 responses need application logs too.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Recognize an Nginx rate-limit rejection</span><br />
Our test error log contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>limiting requests, excess: 0.991 by zone "af429"</code></div></div>The named zone was our own test limiter. Its name is not a built-in aaPanel setting. We also added a diagnostic access-log field in the isolated configuration and saw:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>200 PASSED
429 REJECTED
200 PASSED</code></div></div>Default website logs may not contain that extra field. Do not expect to find it unless your log format includes it. Nginx can use a different rejection status; seeing 503 instead of 429 does not rule out a request limiter.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What the private experiment tested</span><br />
We ran a separate Nginx configuration listening only on the lab's loopback interface. One exact path served a harmless text fixture. Its illustrative limit allowed one request per second with no extra burst allowance, and we explicitly selected 429 for rejections.<br />
<ul class="mycode_list"><li>The first request returned <span style="font-weight: bold;" class="mycode_b">200</span> with the expected text.<br />
</li>
<li>An immediate second request returned <span style="font-weight: bold;" class="mycode_b">429</span>, with a matching limiter rejection in the error log.<br />
</li>
<li>After a <span style="font-weight: bold;" class="mycode_b">1.2-second pause</span>, the next request returned <span style="font-weight: bold;" class="mycode_b">200</span> with the same expected text.<br />
</li>
</ul>
The limiter stayed active throughout. Only three requests were measured in this corrected run; this was not a load test or an application-capacity benchmark. An earlier fixture path had a permissions error, which was corrected separately before this comparison. Waiting cleared this synthetic rate condition; it does not prove waiting fixes every real 429.<br />
<br />
The temporary listener was stopped and its PID file and disposable text fixture were removed. The main Nginx configuration hash remained unchanged, and the normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Fix the cause at the correct layer</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">A client is polling too frequently:</span> reduce unnecessary refreshes, use caching where appropriate and apply bounded backoff. Honor Retry-After when supplied. Do not create a rapid retry loop after a rejection.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">An application account or API quota is reached:</span> inspect that service's quota and application logs. Changing Nginx cannot increase a third-party API allowance. Check for duplicate jobs or repeated failed requests.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">A CDN or WAF rule is rejecting legitimate traffic:</span> inspect the matching event and rule. Consider a narrow, documented adjustment for the intended endpoint after reviewing the evidence. Keep login and abuse protections in place.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Nginx sees many visitors as one address:</span> investigate how the trusted reverse proxy communicates client addresses. This is a configuration review, not a reason to trust arbitrary forwarded headers. Incorrect trust settings can let clients spoof identities.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">A valid origin rule is too strict for an application's normal behavior:</span> measure that endpoint's legitimate request pattern before choosing a scoped allowance. Avoid a blanket site-wide exemption or unlimited burst setting.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">6. Review configuration safely</span><br />
Before editing, back up the affected site's configuration and identify any included rules. Note the rule scope, key, rate and burst behavior. The test's one-request-per-second allowance was deliberately restrictive and is not a recommended value for your site.<br />
<br />
If you have evidence for a change, alter only the intended rule, validate the complete Nginx configuration using the panel's validation mechanism and apply it only after validation passes. Keep the previous configuration for rollback. Do not add duplicate location blocks or globally disable a security plugin to fix one URL.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify without creating more traffic problems</span><br />
Repeat a small number of safe requests at a normal pace. Check both response content and status, then inspect the corresponding logs. Confirm that ordinary users can finish the intended action and that the relevant protection still applies to excessive requests in a controlled test environment.<br />
<br />
Do not run bursts against a production login or somebody else's API. If many visitors share a corporate or mobile network, include that scenario in your review. Observe a representative period before calling an intermittent issue resolved.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When asking for help, include</span><br />
The failing path without private query data, time and timezone, which layer logged the rejection, a short redacted log excerpt, approximate request frequency and any recent rule changes. Never include authentication headers, full session cookies or API keys.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Find website access and error logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">Monitor resource use during controlled traffic tests</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical reference</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_limit_req_module.html" target="_blank" rel="noopener" class="mycode_url">Official Nginx request-limit module documentation</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 429 Too Many Requests response usually means a request limit has been reached. Find the layer issuing the response before changing a setting: it may be your CDN, Nginx, a security plugin or the application itself.</span><br />
<br />
This guide demonstrates one Nginx limiter on a private lab endpoint. It does not assume every aaPanel website has that rule, and it does not recommend turning off protection to make an error disappear.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=323" target="_blank" title="">nginx-429-20261015.jpg</a> (Size: 116.42 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab results, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Capture one safe example</span><br />
Record the URL path, time and timezone, action, response status and how often the client is sending requests. Does it affect everyone, one network, one account or only a particular API? A page can send many background requests even when a user clicks once.<br />
<br />
Inspect response headers in your browser's Network tab. If a Retry-After header is present, use its stated delay; do not assume every limiter supplies it. Avoid repeatedly submitting login forms, purchases or imports while diagnosing the problem. Save a redacted error example without session cookies, authorization headers or private query strings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the response to website logs</span><br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, find the affected site and select <span style="font-weight: bold;" class="mycode_b">Log</span>. Check <span style="font-weight: bold;" class="mycode_b">Access log</span> and <span style="font-weight: bold;" class="mycode_b">Error log</span> around the recorded time. Refresh and expand the displayed line count if needed. Labels may vary by panel version.<br />
<br />
Our lab site's logs are at:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.log
/www/wwwlogs/adminslab.com.error.log</code></div></div>Use the actual path configured for your own domain. A bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.log
tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>A 429 entry confirms that this log recorded the response, but does not by itself identify the rule. If there is no matching origin request, check the CDN or earlier proxy's events and verify you selected the correct log. Application-generated 429 responses need application logs too.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Recognize an Nginx rate-limit rejection</span><br />
Our test error log contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>limiting requests, excess: 0.991 by zone "af429"</code></div></div>The named zone was our own test limiter. Its name is not a built-in aaPanel setting. We also added a diagnostic access-log field in the isolated configuration and saw:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>200 PASSED
429 REJECTED
200 PASSED</code></div></div>Default website logs may not contain that extra field. Do not expect to find it unless your log format includes it. Nginx can use a different rejection status; seeing 503 instead of 429 does not rule out a request limiter.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. What the private experiment tested</span><br />
We ran a separate Nginx configuration listening only on the lab's loopback interface. One exact path served a harmless text fixture. Its illustrative limit allowed one request per second with no extra burst allowance, and we explicitly selected 429 for rejections.<br />
<ul class="mycode_list"><li>The first request returned <span style="font-weight: bold;" class="mycode_b">200</span> with the expected text.<br />
</li>
<li>An immediate second request returned <span style="font-weight: bold;" class="mycode_b">429</span>, with a matching limiter rejection in the error log.<br />
</li>
<li>After a <span style="font-weight: bold;" class="mycode_b">1.2-second pause</span>, the next request returned <span style="font-weight: bold;" class="mycode_b">200</span> with the same expected text.<br />
</li>
</ul>
The limiter stayed active throughout. Only three requests were measured in this corrected run; this was not a load test or an application-capacity benchmark. An earlier fixture path had a permissions error, which was corrected separately before this comparison. Waiting cleared this synthetic rate condition; it does not prove waiting fixes every real 429.<br />
<br />
The temporary listener was stopped and its PID file and disposable text fixture were removed. The main Nginx configuration hash remained unchanged, and the normal HTTPS website returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Fix the cause at the correct layer</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">A client is polling too frequently:</span> reduce unnecessary refreshes, use caching where appropriate and apply bounded backoff. Honor Retry-After when supplied. Do not create a rapid retry loop after a rejection.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">An application account or API quota is reached:</span> inspect that service's quota and application logs. Changing Nginx cannot increase a third-party API allowance. Check for duplicate jobs or repeated failed requests.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">A CDN or WAF rule is rejecting legitimate traffic:</span> inspect the matching event and rule. Consider a narrow, documented adjustment for the intended endpoint after reviewing the evidence. Keep login and abuse protections in place.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Nginx sees many visitors as one address:</span> investigate how the trusted reverse proxy communicates client addresses. This is a configuration review, not a reason to trust arbitrary forwarded headers. Incorrect trust settings can let clients spoof identities.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">A valid origin rule is too strict for an application's normal behavior:</span> measure that endpoint's legitimate request pattern before choosing a scoped allowance. Avoid a blanket site-wide exemption or unlimited burst setting.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">6. Review configuration safely</span><br />
Before editing, back up the affected site's configuration and identify any included rules. Note the rule scope, key, rate and burst behavior. The test's one-request-per-second allowance was deliberately restrictive and is not a recommended value for your site.<br />
<br />
If you have evidence for a change, alter only the intended rule, validate the complete Nginx configuration using the panel's validation mechanism and apply it only after validation passes. Keep the previous configuration for rollback. Do not add duplicate location blocks or globally disable a security plugin to fix one URL.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify without creating more traffic problems</span><br />
Repeat a small number of safe requests at a normal pace. Check both response content and status, then inspect the corresponding logs. Confirm that ordinary users can finish the intended action and that the relevant protection still applies to excessive requests in a controlled test environment.<br />
<br />
Do not run bursts against a production login or somebody else's API. If many visitors share a corporate or mobile network, include that scenario in your review. Observe a representative period before calling an intermittent issue resolved.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When asking for help, include</span><br />
The failing path without private query data, time and timezone, which layer logged the rejection, a short redacted log excerpt, approximate request frequency and any recent rule changes. Never include authentication headers, full session cookies or API keys.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Find website access and error logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">Monitor resource use during controlled traffic tests</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical reference</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_limit_req_module.html" target="_blank" rel="noopener" class="mycode_url">Official Nginx request-limit module documentation</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix 504 Gateway Timeout Errors in aaPanel Using Logs]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-504-gateway-timeout-errors-in-aapanel-using-logs</link>
			<pubDate>Thu, 15 Oct 2026 12:24:18 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-504-gateway-timeout-errors-in-aapanel-using-logs</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 504 Gateway Timeout means a gateway did not receive a timely response from its upstream. The useful next step is to identify which gateway timed out and what it was waiting for.</span> A slow SQL query, external API, busy PHP worker pool or an unreachable upstream can require very different fixes.<br />
<br />
This guide uses an isolated Nginx HTTP-proxy experiment, then shows how to investigate a real aaPanel website. The tested values below are deliberately tiny lab settings, not recommended production limits.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=322" target="_blank" title="">nginx-504-20261015.jpg</a> (Size: 130.65 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum original lab results, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request before changing settings</span><br />
Write down the exact time and timezone, domain, path, action and approximate waiting time. Does one report page fail, or every page? Does it fail only during traffic peaks? Avoid repeatedly submitting payments, imports or other actions that might continue on the server after the browser gives up.<br />
<br />
Check whether the response comes from your origin Nginx, another reverse proxy or a CDN. A branded error page is a clue, not conclusive proof of which layer caused the delay. Match the request against origin logs. Do not disable your firewall or expose a private origin to diagnose this.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find the matching website logs in aaPanel</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Inspect <span style="font-weight: bold;" class="mycode_b">Access log</span> and <span style="font-weight: bold;" class="mycode_b">Error log</span> around the recorded time. Refresh the viewer and expand the displayed line count if necessary. Panel layouts differ by version.<br />
<br />
On our lab site the files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.log
/www/wwwlogs/adminslab.com.error.log</code></div></div>Replace the domain with your own site's actual configured log path. A bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log
tail -n 100 /www/wwwlogs/example.com.log</code></div></div>Do not paste complete logs publicly: redact tokens, private query strings, addresses and customer information. A browser 504 with no matching origin request may point to an earlier proxy layer or the wrong log file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Read the upstream error, not just the status code</span><br />
Our failing request produced this shortened error:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>upstream timed out (110: Connection timed out)
while reading response header from upstream</code></div></div>Here Nginx was waiting for the upstream response header. A message about connecting to the upstream points to a different phase: check the upstream address, listener, route and service health. A connection refusal often leads to 502 instead; do not treat every gateway failure as the same problem.<br />
<br />
The error line's upstream field helps distinguish HTTP proxying from FastCGI. Correlate the path and timestamp with the application log and, for PHP, its slow log. A 504 alone does not prove that MySQL, PHP or Nginx needs a larger limit.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand the two common read-timeout settings</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code># HTTP reverse proxy: Node, Python or another HTTP service
proxy_read_timeout 30s;

# FastCGI: commonly a PHP-FPM website
fastcgi_read_timeout 30s;</code></div></div>These are illustrative directives, not instructions to add both. Identify the active location and included configuration first. Do not create a second conflicting location block or edit a shared PHP include without understanding every affected site.<br />
<br />
Nginx read timeouts measure the allowed gap between successive reads from the upstream; they are not a universal total request duration limit. Connection timeouts govern another phase. PHP execution limits, PHP-FPM termination limits and CDN or load-balancer limits are separate and may end the request sooner.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test actually demonstrated</span><br />
The lab used the installed Nginx 1.30.5 binary, a separate configuration and two loopback-only listeners. Its dummy HTTP upstream deliberately waited before returning a response. There were only three measured requests:<br />
<ul class="mycode_list"><li>Delay 2 seconds, read timeout 1 second: <span style="font-weight: bold;" class="mycode_b">504 in 1.002187 seconds</span>, with an upstream-header timeout in the error log.<br />
</li>
<li>Same 2-second delay, read timeout 4 seconds: <span style="font-weight: bold;" class="mycode_b">200 in 2.002012 seconds</span>. The longer allowance did not make the upstream faster.<br />
</li>
<li>Artificial delay reduced to 0.2 seconds, original 1-second timeout restored: <span style="font-weight: bold;" class="mycode_b">200 in 0.202015 seconds</span>.<br />
</li>
</ul>
The last phase changed a synthetic sleep, not a real database query or production application. This demonstrates timeout behavior, not PHP capacity or a universal performance improvement. Both test listeners were closed, the isolated PID file disappeared, the main Nginx configuration hash stayed unchanged and the normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Investigate what the real application is waiting for</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Slow PHP code:</span> correlate a PHP-FPM slow-log stack with the failing URL. Check whether workers are busy or requests are queuing. Raising worker counts beyond available memory can make the situation worse.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database work:</span> identify the actual slow query and inspect its plan before adding an index. Check locks and transaction duration. Do not change global database limits based on one gateway error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">External API:</span> inspect the application's outgoing request timeout and upstream provider status. Use bounded retries and a clear failure response; retries can multiply load.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Traffic or resource pressure:</span> compare CPU, available memory, swap activity and disk latency with the incident time. A quiet server after the event does not rule out an earlier spike.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Long exports or imports:</span> consider a background job with status polling and a downloadable result. Increasing web timeouts indefinitely leaves connections and workers occupied.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. If a timeout adjustment is justified, make it deliberately</span><br />
Back up the affected site's configuration. Record the old value, the expected operation duration and the limits of every proxy in front of it. In aaPanel open the affected site's configuration and locate the active proxy or FastCGI section. Change only the appropriate directive in the intended scope, then run the panel's configuration validation before applying or reloading it. Restore the backup if validation fails.<br />
<br />
Do not copy the lab's 1-second or 4-second settings to your website. Choose a finite budget based on a legitimate request and measured behavior. A larger budget is sometimes appropriate, but it also permits longer resource occupancy and does not repair slow application work.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the result and keep a rollback path</span><br />
Repeat one safe request and compare status, response content and elapsed time. Check the application actually finished; an HTTP 200 alone can contain an application error. Confirm the error log has no new matching upstream timeout, inspect nearby normal pages and monitor resource use. For an intermittent issue, observe a representative traffic period before declaring it fixed.<br />
<br />
A simple non-mutating request timing example is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 45 -o /dev/null &#92;
  -w 'HTTP %{http_code} | total %{time_total}s&#92;n' &#92;
  https://example.com/safe-status-page</code></div></div>Use a real, safe URL on your site. curl's own maximum time is a client-side limit, separate from Nginx's upstream timeout. Never include login tokens or secrets in a public command example.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related troubleshooting guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Find website access and error logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">Trace slow PHP requests with PHP-FPM slow logs</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Investigate MariaDB query plans and indexes</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout" target="_blank" rel="noopener" class="mycode_url">Nginx proxy_read_timeout documentation</a><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout" target="_blank" rel="noopener" class="mycode_url">Nginx fastcgi_read_timeout documentation</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 504 Gateway Timeout means a gateway did not receive a timely response from its upstream. The useful next step is to identify which gateway timed out and what it was waiting for.</span> A slow SQL query, external API, busy PHP worker pool or an unreachable upstream can require very different fixes.<br />
<br />
This guide uses an isolated Nginx HTTP-proxy experiment, then shows how to investigate a real aaPanel website. The tested values below are deliberately tiny lab settings, not recommended production limits.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=322" target="_blank" title="">nginx-504-20261015.jpg</a> (Size: 130.65 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum original lab results, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request before changing settings</span><br />
Write down the exact time and timezone, domain, path, action and approximate waiting time. Does one report page fail, or every page? Does it fail only during traffic peaks? Avoid repeatedly submitting payments, imports or other actions that might continue on the server after the browser gives up.<br />
<br />
Check whether the response comes from your origin Nginx, another reverse proxy or a CDN. A branded error page is a clue, not conclusive proof of which layer caused the delay. Match the request against origin logs. Do not disable your firewall or expose a private origin to diagnose this.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Find the matching website logs in aaPanel</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use its <span style="font-weight: bold;" class="mycode_b">Log</span> control. Inspect <span style="font-weight: bold;" class="mycode_b">Access log</span> and <span style="font-weight: bold;" class="mycode_b">Error log</span> around the recorded time. Refresh the viewer and expand the displayed line count if necessary. Panel layouts differ by version.<br />
<br />
On our lab site the files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.log
/www/wwwlogs/adminslab.com.error.log</code></div></div>Replace the domain with your own site's actual configured log path. A bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log
tail -n 100 /www/wwwlogs/example.com.log</code></div></div>Do not paste complete logs publicly: redact tokens, private query strings, addresses and customer information. A browser 504 with no matching origin request may point to an earlier proxy layer or the wrong log file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Read the upstream error, not just the status code</span><br />
Our failing request produced this shortened error:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>upstream timed out (110: Connection timed out)
while reading response header from upstream</code></div></div>Here Nginx was waiting for the upstream response header. A message about connecting to the upstream points to a different phase: check the upstream address, listener, route and service health. A connection refusal often leads to 502 instead; do not treat every gateway failure as the same problem.<br />
<br />
The error line's upstream field helps distinguish HTTP proxying from FastCGI. Correlate the path and timestamp with the application log and, for PHP, its slow log. A 504 alone does not prove that MySQL, PHP or Nginx needs a larger limit.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand the two common read-timeout settings</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code># HTTP reverse proxy: Node, Python or another HTTP service
proxy_read_timeout 30s;

# FastCGI: commonly a PHP-FPM website
fastcgi_read_timeout 30s;</code></div></div>These are illustrative directives, not instructions to add both. Identify the active location and included configuration first. Do not create a second conflicting location block or edit a shared PHP include without understanding every affected site.<br />
<br />
Nginx read timeouts measure the allowed gap between successive reads from the upstream; they are not a universal total request duration limit. Connection timeouts govern another phase. PHP execution limits, PHP-FPM termination limits and CDN or load-balancer limits are separate and may end the request sooner.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test actually demonstrated</span><br />
The lab used the installed Nginx 1.30.5 binary, a separate configuration and two loopback-only listeners. Its dummy HTTP upstream deliberately waited before returning a response. There were only three measured requests:<br />
<ul class="mycode_list"><li>Delay 2 seconds, read timeout 1 second: <span style="font-weight: bold;" class="mycode_b">504 in 1.002187 seconds</span>, with an upstream-header timeout in the error log.<br />
</li>
<li>Same 2-second delay, read timeout 4 seconds: <span style="font-weight: bold;" class="mycode_b">200 in 2.002012 seconds</span>. The longer allowance did not make the upstream faster.<br />
</li>
<li>Artificial delay reduced to 0.2 seconds, original 1-second timeout restored: <span style="font-weight: bold;" class="mycode_b">200 in 0.202015 seconds</span>.<br />
</li>
</ul>
The last phase changed a synthetic sleep, not a real database query or production application. This demonstrates timeout behavior, not PHP capacity or a universal performance improvement. Both test listeners were closed, the isolated PID file disappeared, the main Nginx configuration hash stayed unchanged and the normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Investigate what the real application is waiting for</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Slow PHP code:</span> correlate a PHP-FPM slow-log stack with the failing URL. Check whether workers are busy or requests are queuing. Raising worker counts beyond available memory can make the situation worse.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database work:</span> identify the actual slow query and inspect its plan before adding an index. Check locks and transaction duration. Do not change global database limits based on one gateway error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">External API:</span> inspect the application's outgoing request timeout and upstream provider status. Use bounded retries and a clear failure response; retries can multiply load.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Traffic or resource pressure:</span> compare CPU, available memory, swap activity and disk latency with the incident time. A quiet server after the event does not rule out an earlier spike.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Long exports or imports:</span> consider a background job with status polling and a downloadable result. Increasing web timeouts indefinitely leaves connections and workers occupied.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. If a timeout adjustment is justified, make it deliberately</span><br />
Back up the affected site's configuration. Record the old value, the expected operation duration and the limits of every proxy in front of it. In aaPanel open the affected site's configuration and locate the active proxy or FastCGI section. Change only the appropriate directive in the intended scope, then run the panel's configuration validation before applying or reloading it. Restore the backup if validation fails.<br />
<br />
Do not copy the lab's 1-second or 4-second settings to your website. Choose a finite budget based on a legitimate request and measured behavior. A larger budget is sometimes appropriate, but it also permits longer resource occupancy and does not repair slow application work.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the result and keep a rollback path</span><br />
Repeat one safe request and compare status, response content and elapsed time. Check the application actually finished; an HTTP 200 alone can contain an application error. Confirm the error log has no new matching upstream timeout, inspect nearby normal pages and monitor resource use. For an intermittent issue, observe a representative traffic period before declaring it fixed.<br />
<br />
A simple non-mutating request timing example is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 45 -o /dev/null &#92;
  -w 'HTTP %{http_code} | total %{time_total}s&#92;n' &#92;
  https://example.com/safe-status-page</code></div></div>Use a real, safe URL on your site. curl's own maximum time is a client-side limit, separate from Nginx's upstream timeout. Never include login tokens or secrets in a public command example.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related troubleshooting guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Find website access and error logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">Trace slow PHP requests with PHP-FPM slow logs</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">Investigate MariaDB query plans and indexes</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout" target="_blank" rel="noopener" class="mycode_url">Nginx proxy_read_timeout documentation</a><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout" target="_blank" rel="noopener" class="mycode_url">Nginx fastcgi_read_timeout documentation</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix 413 Request Entity Too Large Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-413-request-entity-too-large-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 11:34:38 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-413-request-entity-too-large-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 413 “Request Entity Too Large” response can come from a request-size limit before PHP handles an upload. Identify the layer returning it, check the matching log and change the smallest relevant limit. Increasing PHP's upload setting alone cannot fix a request rejected by Nginx.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: Ubuntu 22.04.5 and the aaPanel lab's installed Nginx 1.30.5 binary. We ran a separate temporary Nginx instance listening only on 127.0.0.1, with its own configuration, PID and logs. A 2KiB request failed under a 1KiB limit and reached a dummy 200 handler under a 4KiB limit. We shut down the test instance afterwards. The normal website configuration and PHP settings were not changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failed operation</span><br />
Note the hostname/path, time/timezone, method, approximate file size, total request size and HTTP status. Find out whether a small upload works and a larger one fails. A multipart request contains framing and other fields in addition to the file bytes.<br />
Check the browser's failed network request and the response. The wording may vary by Nginx version or another proxy. A CDN, reverse proxy, application or upload service can impose a separate limit; a response logo alone is not proof of the failing layer.<br />
Do not repeatedly submit production imports or other actions that might create duplicate records. Use a controlled test workflow and harmless input.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the Nginx access and error logs</span><br />
In the tested aaPanel interface, open Website → PHP Project → the site's Log button → Access log / Error log. Confirm the hostname and source path. Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">the website-log guide</a> for detailed searching and time matching.<br />
Our isolated test access log recorded POST /request-size-check with status 413. Its matching error said:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client intended to send too large body: 2048 bytes</code></div></div>This supported a Nginx request-size diagnosis. It was not evidence of a PHP memory error, missing extension or failed database connection. If your website has no matching request, investigate the correct host/log and any earlier proxy layer before editing PHP.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Understand the tiny lab comparison</span><br />
We sent the same 2,048-byte raw request body in both phases. With the relevant location set to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 1k;</code></div></div>Nginx returned 413. We changed only that test limit to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 4k;</code></div></div>After validation and a reload of the isolated instance, the same request received 200 and the dummy response text. The access log recorded both outcomes.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=321" target="_blank" title="">nginx-413-20261015.jpg</a> (Size: 124.89 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a terminal screenshot.</span><br />
<br />
The handler returned a fixed message. This demonstrates the Nginx size gate; it does not prove PHP parsed multipart data, an application validated a file or anything was stored successfully. The endpoint was private, no public firewall port was opened and the normal website remained available.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Inspect the effective site configuration</span><br />
For a real aaPanel incident, locate the affected website under Website → PHP Project and inspect its Conf/site configuration. Labels vary by release. Back up the relevant file before changing it and confirm which server/location handles the failing URL.<br />
The Nginx directive can appear in http, server or location context. Check inherited settings and a more specific location rather than assuming a global value controls every route. Avoid adding duplicate directives in the same context or replacing an existing PHP handler with an incomplete example location.<br />
An administrator can inspect the effective configuration privately with the installed binary:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/nginx/sbin/nginx -T</code></div></div>The output can contain private configuration details. Do not upload the entire dump to a public thread.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Choose a finite limit for the actual workflow</span><br />
An illustrative site-level value is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 80m;</code></div></div>This is an example, not a value applied to the existing lab website or a universal recommendation. Place a chosen limit in the appropriate existing context and consider legitimate request size, concurrent uploads, temporary storage and application policy. Setting the Nginx value to zero disables its body-size check; it was not needed for our test.<br />
Keep limits purposeful instead of making every upload unlimited. A narrow policy can be appropriate for a particular route, but it must preserve the route's existing processing/authentication configuration.<br />
If a CDN or another reverse proxy rejects the request earlier, an origin-only change cannot remove that layer's limit. Review the actual service's documented current limits and supported workflow rather than weakening unrelated security controls.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Align PHP and application limits separately</span><br />
When the request reaches PHP, check the site's selected PHP version and its active FPM settings. Relevant settings include upload_max_filesize for an uploaded file and post_max_size for the total POST data. Allow for request overhead and multiple files according to the intended application behavior.<br />
Exceeding PHP's POST limit can leave POST/file data empty, so the application's error may differ from a Nginx 413. Verify the effective serving runtime; a CLI setting may not describe the website's PHP-FPM pool.<br />
Follow <a href="https://adminsforum.com/Thread-guide-change-php-upload-and-memory-limits-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Change PHP Upload and Memory Limits</a> and <a href="https://adminsforum.com/Thread-guide-increase-wordpress-php-upload-limits-in-aapanel-to-64-mb" target="_blank" rel="noopener" class="mycode_url">the tested WordPress 64MB upload guide</a> for those existing workflows. Application/plugin limits, validation and available temporary storage still matter. We did not change PHP limits in this experiment.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Validate and verify a real repair</span><br />
Before reloading the affected site configuration on a normal aaPanel-managed Nginx installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/nginx/sbin/nginx -t</code></div></div>Use the panel's supported reload control only after validation succeeds. Our experiment reloaded only its separately configured test process, so the existing website configuration was not involved.<br />
Test a small permitted upload and the intended larger upload through the real application, inspect the response/content and confirm the expected file or record was created. Check fresh logs and a normal page. Do not treat a dummy HTTP 200 as proof that a production upload completed.<br />
Preserve a rollback copy. If a change breaks another route or causes resource pressure, restore the previous configuration, validate and repeat the relevant health checks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Cleanup and test limits</span><br />
The temporary listener was stopped, its PID file was removed by shutdown and a connection check confirmed its port was closed. The main Nginx configuration hash was unchanged and the normal website health check returned 200.<br />
We retained the private experiment configuration and result logs as documentation. No real uploaded user file, production upload cap, PHP pool or database was modified. The tiny request was chosen to demonstrate the mechanism with bounded work rather than sending large files at a busy server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size" target="_blank" rel="noopener" class="mycode_url">Nginx client_max_body_size</a> and <a href="https://www.php.net/manual/en/ini.core.php#ini.post-max-size" target="_blank" rel="noopener" class="mycode_url">PHP POST-size configuration</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 413 “Request Entity Too Large” response can come from a request-size limit before PHP handles an upload. Identify the layer returning it, check the matching log and change the smallest relevant limit. Increasing PHP's upload setting alone cannot fix a request rejected by Nginx.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: Ubuntu 22.04.5 and the aaPanel lab's installed Nginx 1.30.5 binary. We ran a separate temporary Nginx instance listening only on 127.0.0.1, with its own configuration, PID and logs. A 2KiB request failed under a 1KiB limit and reached a dummy 200 handler under a 4KiB limit. We shut down the test instance afterwards. The normal website configuration and PHP settings were not changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failed operation</span><br />
Note the hostname/path, time/timezone, method, approximate file size, total request size and HTTP status. Find out whether a small upload works and a larger one fails. A multipart request contains framing and other fields in addition to the file bytes.<br />
Check the browser's failed network request and the response. The wording may vary by Nginx version or another proxy. A CDN, reverse proxy, application or upload service can impose a separate limit; a response logo alone is not proof of the failing layer.<br />
Do not repeatedly submit production imports or other actions that might create duplicate records. Use a controlled test workflow and harmless input.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the Nginx access and error logs</span><br />
In the tested aaPanel interface, open Website → PHP Project → the site's Log button → Access log / Error log. Confirm the hostname and source path. Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">the website-log guide</a> for detailed searching and time matching.<br />
Our isolated test access log recorded POST /request-size-check with status 413. Its matching error said:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client intended to send too large body: 2048 bytes</code></div></div>This supported a Nginx request-size diagnosis. It was not evidence of a PHP memory error, missing extension or failed database connection. If your website has no matching request, investigate the correct host/log and any earlier proxy layer before editing PHP.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Understand the tiny lab comparison</span><br />
We sent the same 2,048-byte raw request body in both phases. With the relevant location set to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 1k;</code></div></div>Nginx returned 413. We changed only that test limit to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 4k;</code></div></div>After validation and a reload of the isolated instance, the same request received 200 and the dummy response text. The access log recorded both outcomes.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=321" target="_blank" title="">nginx-413-20261015.jpg</a> (Size: 124.89 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a terminal screenshot.</span><br />
<br />
The handler returned a fixed message. This demonstrates the Nginx size gate; it does not prove PHP parsed multipart data, an application validated a file or anything was stored successfully. The endpoint was private, no public firewall port was opened and the normal website remained available.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Inspect the effective site configuration</span><br />
For a real aaPanel incident, locate the affected website under Website → PHP Project and inspect its Conf/site configuration. Labels vary by release. Back up the relevant file before changing it and confirm which server/location handles the failing URL.<br />
The Nginx directive can appear in http, server or location context. Check inherited settings and a more specific location rather than assuming a global value controls every route. Avoid adding duplicate directives in the same context or replacing an existing PHP handler with an incomplete example location.<br />
An administrator can inspect the effective configuration privately with the installed binary:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/nginx/sbin/nginx -T</code></div></div>The output can contain private configuration details. Do not upload the entire dump to a public thread.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Choose a finite limit for the actual workflow</span><br />
An illustrative site-level value is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>client_max_body_size 80m;</code></div></div>This is an example, not a value applied to the existing lab website or a universal recommendation. Place a chosen limit in the appropriate existing context and consider legitimate request size, concurrent uploads, temporary storage and application policy. Setting the Nginx value to zero disables its body-size check; it was not needed for our test.<br />
Keep limits purposeful instead of making every upload unlimited. A narrow policy can be appropriate for a particular route, but it must preserve the route's existing processing/authentication configuration.<br />
If a CDN or another reverse proxy rejects the request earlier, an origin-only change cannot remove that layer's limit. Review the actual service's documented current limits and supported workflow rather than weakening unrelated security controls.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Align PHP and application limits separately</span><br />
When the request reaches PHP, check the site's selected PHP version and its active FPM settings. Relevant settings include upload_max_filesize for an uploaded file and post_max_size for the total POST data. Allow for request overhead and multiple files according to the intended application behavior.<br />
Exceeding PHP's POST limit can leave POST/file data empty, so the application's error may differ from a Nginx 413. Verify the effective serving runtime; a CLI setting may not describe the website's PHP-FPM pool.<br />
Follow <a href="https://adminsforum.com/Thread-guide-change-php-upload-and-memory-limits-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Change PHP Upload and Memory Limits</a> and <a href="https://adminsforum.com/Thread-guide-increase-wordpress-php-upload-limits-in-aapanel-to-64-mb" target="_blank" rel="noopener" class="mycode_url">the tested WordPress 64MB upload guide</a> for those existing workflows. Application/plugin limits, validation and available temporary storage still matter. We did not change PHP limits in this experiment.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Validate and verify a real repair</span><br />
Before reloading the affected site configuration on a normal aaPanel-managed Nginx installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/nginx/sbin/nginx -t</code></div></div>Use the panel's supported reload control only after validation succeeds. Our experiment reloaded only its separately configured test process, so the existing website configuration was not involved.<br />
Test a small permitted upload and the intended larger upload through the real application, inspect the response/content and confirm the expected file or record was created. Check fresh logs and a normal page. Do not treat a dummy HTTP 200 as proof that a production upload completed.<br />
Preserve a rollback copy. If a change breaks another route or causes resource pressure, restore the previous configuration, validate and repeat the relevant health checks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Cleanup and test limits</span><br />
The temporary listener was stopped, its PID file was removed by shutdown and a connection check confirmed its port was closed. The main Nginx configuration hash was unchanged and the normal website health check returned 200.<br />
We retained the private experiment configuration and result logs as documentation. No real uploaded user file, production upload cap, PHP pool or database was modified. The tiny request was chosen to demonstrate the mechanism with bounded work rather than sending large files at a busy server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size" target="_blank" rel="noopener" class="mycode_url">Nginx client_max_body_size</a> and <a href="https://www.php.net/manual/en/ini.core.php#ini.post-max-size" target="_blank" rel="noopener" class="mycode_url">PHP POST-size configuration</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix 403 Forbidden Errors in aaPanel Using Logs]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-403-forbidden-errors-in-aapanel-using-logs</link>
			<pubDate>Wed, 14 Oct 2026 21:18:55 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-403-forbidden-errors-in-aapanel-using-logs</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 403 Forbidden response means the request was denied, but it does not identify the rule or permission responsible. Read the matching error before changing file ownership, enabling directory listings or disabling security controls.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and Nginx 1.30.5. We created one temporary public-text fixture, withheld file access to reproduce a permission-related 403, then permitted group read on that file and verified HTTP 200. It was removed afterwards. No application directory, access rule or global service setting was changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the request and the layer denying it</span><br />
Record hostname/path, time/timezone, status, request method, client context and recent changes. Check whether one file, a directory URL, all website pages or only an authenticated action is denied.<br />
Cloudflare/WAF, Nginx and the application can each deny a request. A status or response logo is a clue, not proof of the source. A browser login failure may need account/application evidence rather than filesystem permissions.<br />
For a harmless GET you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/affected-path</code></div></div>Replace the hostname/path; use curl.exe and NUL on Windows. Keep certificate validation enabled. Do not test protected data by bypassing an access policy merely to get a successful response.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the website's access and error logs</span><br />
In our aaPanel interface: Website → PHP Project → the exact site's Log button → Access log / Error log. Confirm the source path and use Refresh. Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">the website log guide</a> for detailed searching and timestamp checks.<br />
Our test request appeared as 403 in the access log. The corresponding Nginx error named the temporary text file and reported:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>open() ... failed (13: Permission denied)</code></div></div>This supported a filesystem-access diagnosis for that static file. It was different from a missing file (404) or an undefined PHP function (500).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the exact file and its parent directories</span><br />
Before a repair, record permissions, owner and group:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ls -l /path/to/affected-file
namei -l /path/to/affected-file</code></div></div>Use the actual path from the matching error. namei displays path components so you can inspect parent-directory traversal as well as the final file. Availability depends on your Linux tools.<br />
A server needs appropriate read access to a served static file and search/traverse access to its parent directories. An unreadable file and a non-traversable parent require different targeted changes. ACLs and platform security controls can also affect access; mode bits alone do not explain every denial.<br />
Our fixture's parents were traversable, and the denied file had mode 000 with owner root and group www. No parent permissions were changed during the test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the process that needs access</span><br />
Our Nginx master ran as root, but its workers ran as www:www. The worker identity is the relevant one for this static request; an administrator being able to read the file does not prove the web worker can.<br />
A useful check that avoids full process arguments is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ps -eo user,group,comm</code></div></div>Inspect the Nginx rows. Do not assume that every panel uses www: different services and PHP pools can run under different users. Ownership should follow your deployment model, not a blanket command copied from another server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Apply the smallest justified permission change</span><br />
For our existing fixture ownership root:www, mode 640 gave the owner read/write, the group read and others no access. Because the workers used group www, this permitted the intended static response without allowing them to write to the file.<br />
Our one-file repair was equivalent to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>chmod 640 /www/wwwroot/adminslab.com/af-http403-lab-20261014.txt</code></div></div>That path was our disposable text fixture. Before adapting the command, verify the intended owner/group and runtime identity, record the original mode and select only the affected file. It does not change ownership or grant a different group access.<br />
This was a file-specific lab example, not a universal website permission preset. Other deployments may use another group or access model. A directory needs traversal permissions, so do not apply file mode 640 recursively to directories.<br />
The existing guide <a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Set File Permissions and Ownership in aaPanel</a> covers the panel controls. Preserve the original mode/owner/group so a real repair can be reversed. Do not recursively apply chmod 777 or give a runtime write access to all application code just to eliminate a 403.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=319" target="_blank" title="">http403-permission-20261014.jpg</a> (Size: 131.87 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a panel screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify the response and new log evidence</span><br />
After the targeted file change, the same URL returned HTTP 200 with the expected text. The access log recorded 200, no new error entry matched that file, and the normal homepage also returned 200.<br />
No Nginx reload or restart was needed for this filesystem-mode change. If you instead edit a server configuration, validate it and use the supported reload procedure before testing its behavior.<br />
We removed the temporary fixture after verification. The deliberately inaccessible file should not be left as a public test URL. Existing application files and permissions remained untouched.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Distinguish other 403 causes</span><br />
The following are investigation examples, not failures induced in this test:<ul class="mycode_list"><li>Directory URL denied: inspect the intended default document, running/document root and directory-index configuration. A missing expected index is not a reason to expose a directory listing of website files.<br />
</li>
<li>Access-rule denial: inspect the matching Nginx location and ordered allow/deny rules, or the applicable panel access restriction. Confirm whether the denial is intentional before changing it.<br />
</li>
<li>WAF/CDN denial: inspect the corresponding security event and request context. Resolve a verified false positive narrowly; do not disable the whole firewall or WAF as a shortcut.<br />
</li>
<li>Application denial: inspect account role, authentication/session state, CSRF checks and the application logger. A filesystem chmod will not correct an authorization decision.<br />
</li>
<li>Permission denied despite apparently suitable modes: inspect the process identity, parent traversal, ACLs and security-policy evidence. Do not disable the system's protection without establishing the cause.<br />
</li>
</ul>
Several layers can be involved. Compare the same request at the correct layer without publishing private upstream services or weakening authentication.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Be careful with proxy addresses</span><br />
An IP-based access rule may see a CDN/proxy address rather than the visitor address unless trusted real-IP handling is configured correctly. Do not trust arbitrary forwarded headers or whitelist large address ranges without understanding the effective client identity.<br />
Our test used loopback and a local HTTPS request with the correct hostname and certificate validation. It did not audit CDN rules or demonstrate all remote client conditions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Retain a rollback and share a small safe excerpt</span><br />
Keep the affected file's original ownership/mode and a backup before a real deployment repair. Retest the denied path, a normal page and relevant authenticated behavior. A new 200 alone is not a success if it accidentally makes protected content public.<br />
For support, include versions, time/timezone, path, status, recent change and the redacted matching message. Remove tokens, visitor IPs, private contact details and unrelated requests. Logs are evidence to interpret, not instructions to execute.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://www.gnu.org/software/coreutils/manual/html_node/Mode-Structure.html" target="_blank" rel="noopener" class="mycode_url">GNU file-mode structure</a>, <a href="https://nginx.org/en/docs/http/ngx_http_access_module.html" target="_blank" rel="noopener" class="mycode_url">Nginx access rules</a> and <a href="https://nginx.org/en/docs/http/ngx_http_autoindex_module.html" target="_blank" rel="noopener" class="mycode_url">Nginx directory listings</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">A 403 Forbidden response means the request was denied, but it does not identify the rule or permission responsible. Read the matching error before changing file ownership, enabling directory listings or disabling security controls.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and Nginx 1.30.5. We created one temporary public-text fixture, withheld file access to reproduce a permission-related 403, then permitted group read on that file and verified HTTP 200. It was removed afterwards. No application directory, access rule or global service setting was changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the request and the layer denying it</span><br />
Record hostname/path, time/timezone, status, request method, client context and recent changes. Check whether one file, a directory URL, all website pages or only an authenticated action is denied.<br />
Cloudflare/WAF, Nginx and the application can each deny a request. A status or response logo is a clue, not proof of the source. A browser login failure may need account/application evidence rather than filesystem permissions.<br />
For a harmless GET you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/affected-path</code></div></div>Replace the hostname/path; use curl.exe and NUL on Windows. Keep certificate validation enabled. Do not test protected data by bypassing an access policy merely to get a successful response.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Match the website's access and error logs</span><br />
In our aaPanel interface: Website → PHP Project → the exact site's Log button → Access log / Error log. Confirm the source path and use Refresh. Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">the website log guide</a> for detailed searching and timestamp checks.<br />
Our test request appeared as 403 in the access log. The corresponding Nginx error named the temporary text file and reported:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>open() ... failed (13: Permission denied)</code></div></div>This supported a filesystem-access diagnosis for that static file. It was different from a missing file (404) or an undefined PHP function (500).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Inspect the exact file and its parent directories</span><br />
Before a repair, record permissions, owner and group:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ls -l /path/to/affected-file
namei -l /path/to/affected-file</code></div></div>Use the actual path from the matching error. namei displays path components so you can inspect parent-directory traversal as well as the final file. Availability depends on your Linux tools.<br />
A server needs appropriate read access to a served static file and search/traverse access to its parent directories. An unreadable file and a non-traversable parent require different targeted changes. ACLs and platform security controls can also affect access; mode bits alone do not explain every denial.<br />
Our fixture's parents were traversable, and the denied file had mode 000 with owner root and group www. No parent permissions were changed during the test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the process that needs access</span><br />
Our Nginx master ran as root, but its workers ran as www:www. The worker identity is the relevant one for this static request; an administrator being able to read the file does not prove the web worker can.<br />
A useful check that avoids full process arguments is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ps -eo user,group,comm</code></div></div>Inspect the Nginx rows. Do not assume that every panel uses www: different services and PHP pools can run under different users. Ownership should follow your deployment model, not a blanket command copied from another server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Apply the smallest justified permission change</span><br />
For our existing fixture ownership root:www, mode 640 gave the owner read/write, the group read and others no access. Because the workers used group www, this permitted the intended static response without allowing them to write to the file.<br />
Our one-file repair was equivalent to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>chmod 640 /www/wwwroot/adminslab.com/af-http403-lab-20261014.txt</code></div></div>That path was our disposable text fixture. Before adapting the command, verify the intended owner/group and runtime identity, record the original mode and select only the affected file. It does not change ownership or grant a different group access.<br />
This was a file-specific lab example, not a universal website permission preset. Other deployments may use another group or access model. A directory needs traversal permissions, so do not apply file mode 640 recursively to directories.<br />
The existing guide <a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Set File Permissions and Ownership in aaPanel</a> covers the panel controls. Preserve the original mode/owner/group so a real repair can be reversed. Do not recursively apply chmod 777 or give a runtime write access to all application code just to eliminate a 403.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=319" target="_blank" title="">http403-permission-20261014.jpg</a> (Size: 131.87 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a panel screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify the response and new log evidence</span><br />
After the targeted file change, the same URL returned HTTP 200 with the expected text. The access log recorded 200, no new error entry matched that file, and the normal homepage also returned 200.<br />
No Nginx reload or restart was needed for this filesystem-mode change. If you instead edit a server configuration, validate it and use the supported reload procedure before testing its behavior.<br />
We removed the temporary fixture after verification. The deliberately inaccessible file should not be left as a public test URL. Existing application files and permissions remained untouched.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Distinguish other 403 causes</span><br />
The following are investigation examples, not failures induced in this test:<ul class="mycode_list"><li>Directory URL denied: inspect the intended default document, running/document root and directory-index configuration. A missing expected index is not a reason to expose a directory listing of website files.<br />
</li>
<li>Access-rule denial: inspect the matching Nginx location and ordered allow/deny rules, or the applicable panel access restriction. Confirm whether the denial is intentional before changing it.<br />
</li>
<li>WAF/CDN denial: inspect the corresponding security event and request context. Resolve a verified false positive narrowly; do not disable the whole firewall or WAF as a shortcut.<br />
</li>
<li>Application denial: inspect account role, authentication/session state, CSRF checks and the application logger. A filesystem chmod will not correct an authorization decision.<br />
</li>
<li>Permission denied despite apparently suitable modes: inspect the process identity, parent traversal, ACLs and security-policy evidence. Do not disable the system's protection without establishing the cause.<br />
</li>
</ul>
Several layers can be involved. Compare the same request at the correct layer without publishing private upstream services or weakening authentication.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Be careful with proxy addresses</span><br />
An IP-based access rule may see a CDN/proxy address rather than the visitor address unless trusted real-IP handling is configured correctly. Do not trust arbitrary forwarded headers or whitelist large address ranges without understanding the effective client identity.<br />
Our test used loopback and a local HTTPS request with the correct hostname and certificate validation. It did not audit CDN rules or demonstrate all remote client conditions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Retain a rollback and share a small safe excerpt</span><br />
Keep the affected file's original ownership/mode and a backup before a real deployment repair. Retest the denied path, a normal page and relevant authenticated behavior. A new 200 alone is not a success if it accidentally makes protected content public.<br />
For support, include versions, time/timezone, path, status, recent change and the redacted matching message. Remove tokens, visitor IPs, private contact details and unrelated requests. Logs are evidence to interpret, not instructions to execute.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References</span>: <a href="https://www.gnu.org/software/coreutils/manual/html_node/Mode-Structure.html" target="_blank" rel="noopener" class="mycode_url">GNU file-mode structure</a>, <a href="https://nginx.org/en/docs/http/ngx_http_access_module.html" target="_blank" rel="noopener" class="mycode_url">Nginx access rules</a> and <a href="https://nginx.org/en/docs/http/ngx_http_autoindex_module.html" target="_blank" rel="noopener" class="mycode_url">Nginx directory listings</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix PHP HTTP 500 Errors in aaPanel Using Error Logs]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs</link>
			<pubDate>Wed, 14 Oct 2026 21:11:00 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">HTTP 500 means the server could not complete the request. It does not tell you which PHP error occurred. Match the request with the relevant logs, identify the actual cause, make one targeted repair and verify the response and fresh log entries.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5, Nginx 1.30.5 and PHP 8.5.11. An isolated temporary PHP page called an undefined function, returned 500 and generated a fatal-error record. Removing that call returned 200 with the intended response and no new matching error entry. We removed the test page afterwards. No production application or global PHP settings were changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request</span><br />
Write down the exact hostname/path, time and timezone, method, status and recent changes. Check whether static files work, every PHP page fails or only one application action fails. Do not repeatedly submit an order, email or other side-effecting request merely to collect errors.<br />
For a harmless GET endpoint you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/problem-page</code></div></div>Replace the hostname and path. On Windows use curl.exe and NUL. Keep certificate validation enabled, and separately inspect the body. A browser's generic error page is not a diagnostic explanation.<br />
A CDN or application framework can return its own 500. Determine which layer handled the request before assuming the PHP service has stopped.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the matching website logs</span><br />
In the tested aaPanel interface choose Website → PHP Project → the exact site's Log button. Inspect Access log and Error log and use Refresh. Confirm the displayed source path and selected hostname.<br />
Our site used /www/wwwlogs/adminslab.com.log and /www/wwwlogs/adminslab.com.error.log. The application may use another private log too. The panel's administrative log is not a substitute for the website's log.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Check Website Logs in aaPanel</a> for time matching, rotation and safe SSH searches.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Find the fatal error, not just the status code</span><br />
The lab access log recorded the temporary page with HTTP 500 at 13:08:03 UTC. The matching Nginx error entry contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr:
PHP Fatal error: Uncaught Error:
Call to undefined function af_lab_missing_function()
.../af-http500-verified-20261014.php:4</code></div></div>This identified an undefined function in the temporary script. It did not indicate that Nginx, MySQL or the entire VPS needed reinstalling. The file/line and error type directed the investigation.<br />
A framework stack can include several files. Trace the relevant application operation and recent deployment instead of editing a random vendor file named in the stack. Preserve a small matching excerpt before changing anything.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=310" target="_blank" title="">php-http500-20261014.jpg</a> (Size: 133.63 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot. The image abbreviates the lab script path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand what a syntax check proves</span><br />
Our faulty script passed:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -l /path/to/the/affected-file.php</code></div></div>Replace the path with an actual file and use the intended installed PHP binary. This command checks PHP syntax without executing the normal application workflow. It did not detect that our function was unavailable when the request ran.<br />
A successful lint does not establish runtime compatibility, autoloading, database access or correct application behavior. The CLI and PHP-FPM can also load different ini files and extensions. Verify the website's selected PHP version and its effective serving environment; do not change versions blindly to hide an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Repair the cause shown by the error</span><br />
In our isolated demonstration, the repair was to remove the deliberately undefined call and return a fixed test message. We then repeated the same request. No service restart or pool increase was needed for this code error.<br />
For a real application, first back up and use staging or a reversible deployment. Example investigations include:<ul class="mycode_list"><li>Undefined function: check the function name, expected application include/autoloader or required extension. Determine which component supplies it before installing anything.<br />
</li>
<li>Class not found: inspect the deployment's dependencies and autoload configuration, including case-sensitive paths. Do not run arbitrary downloaded repair scripts.<br />
</li>
<li>Parse error: inspect the named file and recent edit, validate with the matching PHP version and deploy a corrected or known-good copy.<br />
</li>
<li>Memory exhausted: identify the request and resource cause. Raising memory limits without measurement may increase pressure across concurrent workers.<br />
</li>
<li>Database exception: inspect the application connection and matching database error; keep credentials out of public logs or support posts.<br />
</li>
</ul>
These are investigation examples, not additional failures triggered in this test. A 500 can have causes outside PHP as well; use the evidence actually recorded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep diagnostics private and respect log-path restrictions</span><br />
Use error logging rather than public stack traces. For the controlled request we kept display_errors off and log_errors enabled. Global settings may need to be set before execution to capture startup or parse failures; a line inside a script may not execute when parsing fails.<br />
Our earlier attempt to choose a private custom log outside the website's allowed paths was blocked by open_basedir. The error appeared through FastCGI in the Nginx error log instead. We left the restriction intact and used the existing destination for the clean verification.<br />
If a configured log is empty, check effective PHP settings, its permitted path and write permissions. Do not disable open_basedir globally or apply chmod 777 as a logging fix. Choose a supported private destination that the application's restrictions permit, or use the existing SAPI/application logger.<br />
The FPM master log describes service diagnostics; it need not contain every application's fatal error. Avoid exposing phpinfo, debug logs or tokens on the website to discover a setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify HTTP status, content and fresh logs</span><br />
At 13:08:06 UTC, the same temporary endpoint returned HTTP 200 and the text "AdminsForum clean recovery verified". Its access entry changed to 200, and there were no new error-log lines matching that page after the fix. The normal homepage also returned 200.<br />
We allowed timestamp revalidation time before checking the changed file. If your deployment disables OPcache timestamp checking, use its approved invalidation/reload process; a browser refresh alone does not guarantee fresh PHP bytecode.<br />
An old fatal entry remains historical evidence. Compare new timestamps and requests rather than clearing the log. Test an ordinary page and relevant application behavior, including reads/writes on staging where appropriate. A 200 with an error message in its body is not a complete recovery.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Clean up and retain a rollback</span><br />
We removed both temporary diagnostic pages created during the experiment and retained private test records. Existing website content, PHP pool settings and security restrictions were unchanged.<br />
Remove your own test files and temporary diagnostics after the observation window. Keep a known-good code/configuration backup and deliberate log retention. If a targeted change fails, restore it and verify service/application health again.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Distinguish a PHP 500 from a gateway failure</span><br />
A 502 or upstream connection refusal may mean Nginx cannot get a usable upstream response. An executing PHP script's fatal error is a different finding. Correlate upstream service and website logs before choosing a fix.<br />
For slow executing requests, use <a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">PHP-FPM slow logs</a>; for shared-server pressure, use <a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">resource monitoring during a controlled test</a>. Restarting everything can interrupt healthy services and hide useful evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/errorfunc.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP error logging configuration</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">HTTP 500 means the server could not complete the request. It does not tell you which PHP error occurred. Match the request with the relevant logs, identify the actual cause, make one targeted repair and verify the response and fresh log entries.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5, Nginx 1.30.5 and PHP 8.5.11. An isolated temporary PHP page called an undefined function, returned 500 and generated a fatal-error record. Removing that call returned 200 with the intended response and no new matching error entry. We removed the test page afterwards. No production application or global PHP settings were changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request</span><br />
Write down the exact hostname/path, time and timezone, method, status and recent changes. Check whether static files work, every PHP page fails or only one application action fails. Do not repeatedly submit an order, email or other side-effecting request merely to collect errors.<br />
For a harmless GET endpoint you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/problem-page</code></div></div>Replace the hostname and path. On Windows use curl.exe and NUL. Keep certificate validation enabled, and separately inspect the body. A browser's generic error page is not a diagnostic explanation.<br />
A CDN or application framework can return its own 500. Determine which layer handled the request before assuming the PHP service has stopped.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the matching website logs</span><br />
In the tested aaPanel interface choose Website → PHP Project → the exact site's Log button. Inspect Access log and Error log and use Refresh. Confirm the displayed source path and selected hostname.<br />
Our site used /www/wwwlogs/adminslab.com.log and /www/wwwlogs/adminslab.com.error.log. The application may use another private log too. The panel's administrative log is not a substitute for the website's log.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Check Website Logs in aaPanel</a> for time matching, rotation and safe SSH searches.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Find the fatal error, not just the status code</span><br />
The lab access log recorded the temporary page with HTTP 500 at 13:08:03 UTC. The matching Nginx error entry contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr:
PHP Fatal error: Uncaught Error:
Call to undefined function af_lab_missing_function()
.../af-http500-verified-20261014.php:4</code></div></div>This identified an undefined function in the temporary script. It did not indicate that Nginx, MySQL or the entire VPS needed reinstalling. The file/line and error type directed the investigation.<br />
A framework stack can include several files. Trace the relevant application operation and recent deployment instead of editing a random vendor file named in the stack. Preserve a small matching excerpt before changing anything.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=310" target="_blank" title="">php-http500-20261014.jpg</a> (Size: 133.63 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot. The image abbreviates the lab script path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand what a syntax check proves</span><br />
Our faulty script passed:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -l /path/to/the/affected-file.php</code></div></div>Replace the path with an actual file and use the intended installed PHP binary. This command checks PHP syntax without executing the normal application workflow. It did not detect that our function was unavailable when the request ran.<br />
A successful lint does not establish runtime compatibility, autoloading, database access or correct application behavior. The CLI and PHP-FPM can also load different ini files and extensions. Verify the website's selected PHP version and its effective serving environment; do not change versions blindly to hide an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Repair the cause shown by the error</span><br />
In our isolated demonstration, the repair was to remove the deliberately undefined call and return a fixed test message. We then repeated the same request. No service restart or pool increase was needed for this code error.<br />
For a real application, first back up and use staging or a reversible deployment. Example investigations include:<ul class="mycode_list"><li>Undefined function: check the function name, expected application include/autoloader or required extension. Determine which component supplies it before installing anything.<br />
</li>
<li>Class not found: inspect the deployment's dependencies and autoload configuration, including case-sensitive paths. Do not run arbitrary downloaded repair scripts.<br />
</li>
<li>Parse error: inspect the named file and recent edit, validate with the matching PHP version and deploy a corrected or known-good copy.<br />
</li>
<li>Memory exhausted: identify the request and resource cause. Raising memory limits without measurement may increase pressure across concurrent workers.<br />
</li>
<li>Database exception: inspect the application connection and matching database error; keep credentials out of public logs or support posts.<br />
</li>
</ul>
These are investigation examples, not additional failures triggered in this test. A 500 can have causes outside PHP as well; use the evidence actually recorded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep diagnostics private and respect log-path restrictions</span><br />
Use error logging rather than public stack traces. For the controlled request we kept display_errors off and log_errors enabled. Global settings may need to be set before execution to capture startup or parse failures; a line inside a script may not execute when parsing fails.<br />
Our earlier attempt to choose a private custom log outside the website's allowed paths was blocked by open_basedir. The error appeared through FastCGI in the Nginx error log instead. We left the restriction intact and used the existing destination for the clean verification.<br />
If a configured log is empty, check effective PHP settings, its permitted path and write permissions. Do not disable open_basedir globally or apply chmod 777 as a logging fix. Choose a supported private destination that the application's restrictions permit, or use the existing SAPI/application logger.<br />
The FPM master log describes service diagnostics; it need not contain every application's fatal error. Avoid exposing phpinfo, debug logs or tokens on the website to discover a setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify HTTP status, content and fresh logs</span><br />
At 13:08:06 UTC, the same temporary endpoint returned HTTP 200 and the text "AdminsForum clean recovery verified". Its access entry changed to 200, and there were no new error-log lines matching that page after the fix. The normal homepage also returned 200.<br />
We allowed timestamp revalidation time before checking the changed file. If your deployment disables OPcache timestamp checking, use its approved invalidation/reload process; a browser refresh alone does not guarantee fresh PHP bytecode.<br />
An old fatal entry remains historical evidence. Compare new timestamps and requests rather than clearing the log. Test an ordinary page and relevant application behavior, including reads/writes on staging where appropriate. A 200 with an error message in its body is not a complete recovery.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Clean up and retain a rollback</span><br />
We removed both temporary diagnostic pages created during the experiment and retained private test records. Existing website content, PHP pool settings and security restrictions were unchanged.<br />
Remove your own test files and temporary diagnostics after the observation window. Keep a known-good code/configuration backup and deliberate log retention. If a targeted change fails, restore it and verify service/application health again.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Distinguish a PHP 500 from a gateway failure</span><br />
A 502 or upstream connection refusal may mean Nginx cannot get a usable upstream response. An executing PHP script's fatal error is a different finding. Correlate upstream service and website logs before choosing a fix.<br />
For slow executing requests, use <a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">PHP-FPM slow logs</a>; for shared-server pressure, use <a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">resource monitoring during a controlled test</a>. Restarting everything can interrupt healthy services and hide useful evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/errorfunc.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP error logging configuration</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[CloudPanel Backups and Security: Remote Backups, Firewall and Basic Auth]]></title>
			<link>https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth</link>
			<pubDate>Wed, 14 Oct 2026 21:10:47 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=1">JAY</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth</guid>
			<description><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel backups and security: remote backups, firewall and Basic Auth</span></span><br />
<br />
The steps that protect a CloudPanel server: off-server backups, locking down the panel, per-site blocking, and keeping everything updated. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 1: Remote backups</span></span><br />
A backup on the same server isn't a backup if the server dies. Go to <span style="font-weight: bold;" class="mycode_b">Admin Area → Backups</span> and choose a <span style="font-weight: bold;" class="mycode_b">Storage Provider</span>: Amazon S3, Wasabi, DigitalOcean Spaces, Dropbox, Google Drive, Hetzner Storage Box, SFTP or a custom Rclone config.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=311" target="_blank" title="">g7-01-ae55.jpg</a> (Size: 87.42 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
Turn on <span style="font-weight: bold;" class="mycode_b">Enable Remote Backup</span> and set the <span style="font-weight: bold;" class="mycode_b">Frequency</span> and <span style="font-weight: bold;" class="mycode_b">Time</span>. Pick a quiet hour, such as 02:00.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=312" target="_blank" title="">g7-02-ae56.jpg</a> (Size: 112.26 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
Enter the <span style="font-weight: bold;" class="mycode_b">bucket</span> and <span style="font-weight: bold;" class="mycode_b">region</span>, an <span style="font-weight: bold;" class="mycode_b">access key</span> and <span style="font-weight: bold;" class="mycode_b">secret key</span>, the storage directory, the <span style="font-weight: bold;" class="mycode_b">retention period</span> (days to keep) and any <span style="font-weight: bold;" class="mycode_b">excludes</span> such as cache folders, then save. (The keys in our screenshot are CloudPanel's example values, not real keys.) Create a key that can only access this one bucket.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=313" target="_blank" title="">g7-03-ae57.jpg</a> (Size: 113.31 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 2: The firewall</span></span><br />
In <span style="font-weight: bold;" class="mycode_b">Admin Area → Security → Firewall</span>, CloudPanel by default allows SSH (22), HTTP (80), HTTPS (443) and the panel (8443) from anywhere.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=314" target="_blank" title="">g7-04-ae58.jpg</a> (Size: 104.35 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Best single step: allow port 8443 only from your own IP.</span> Click <span style="font-weight: bold;" class="mycode_b">Add Rule</span>, type <span style="font-weight: bold;" class="mycode_b">CloudPanel</span>, source <span style="font-weight: bold;" class="mycode_b">Custom</span>, your IP with <span style="font-weight: bold;" class="mycode_b">/32</span>, and save. <span style="font-weight: bold;" class="mycode_b">Add your rule first</span>, then delete the rules that allow 8443 from anywhere, so you don't lock yourself out. Do the same for SSH if you have a fixed IP.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=315" target="_blank" title="">g7-05-ae60.jpg</a> (Size: 103.36 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 3: Basic Auth in front of the panel</span></span><br />
If your IP changes often, use <span style="font-weight: bold;" class="mycode_b">Basic Auth</span> instead (Admin Area → Security → Basic Auth). It puts a second username and password in front of CloudPanel's login page, which stops bots from even reaching it. As root you can also toggle it with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>clpctl cloudpanel:enable:basic-auth --userName=john --password='a-strong-password'
clpctl cloudpanel:disable:basic-auth</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=316" target="_blank" title="">g7-06-ae61.jpg</a> (Size: 89.63 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 4: Site-level security</span></span><br />
Each site has its own <span style="font-weight: bold;" class="mycode_b">Security</span> tab:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">IP Blocking:</span> block single IPs or whole ranges.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Bot Blocking:</span> block bad bots by user agent, such as the scanners you'll see in your access logs.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=317" target="_blank" title="">g7-07-ae40.jpg</a> (Size: 96.39 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Basic Authentication:</span> password-protect staging copies the public shouldn't see, with a list of <span style="font-weight: bold;" class="mycode_b">whitelisted IPs</span> that skip it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Cloudflare:</span> "Allow traffic from Cloudflare only", so nobody can bypass Cloudflare by hitting your server's IP directly.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=318" target="_blank" title="">g7-08-ae42.jpg</a> (Size: 84.98 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 5: Keep everything updated</span></span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>apt update &amp;&amp; apt -y upgrade
# take a snapshot of the server at your provider first
clp-update
reboot   # when a new kernel was installed</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Security checklist</span></span><ul class="mycode_list"><li>Remote backups on, with a tested restore.<br />
</li>
<li>Port 8443 restricted to your IP, or Basic Auth enabled.<br />
</li>
<li>Two-factor authentication on your CloudPanel admin user.<br />
</li>
<li>SSH keys instead of passwords; SSH restricted if you have a fixed IP.<br />
</li>
<li>Bad bots and abusive IPs blocked per site; Cloudflare-only mode if you use Cloudflare.<br />
</li>
<li>OS and CloudPanel updated regularly.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Security Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Backups, firewall and Basic Auth</span> (you are here)<br />
</li>
</ol>
]]></description>
			<content:encoded><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel backups and security: remote backups, firewall and Basic Auth</span></span><br />
<br />
The steps that protect a CloudPanel server: off-server backups, locking down the panel, per-site blocking, and keeping everything updated. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 1: Remote backups</span></span><br />
A backup on the same server isn't a backup if the server dies. Go to <span style="font-weight: bold;" class="mycode_b">Admin Area → Backups</span> and choose a <span style="font-weight: bold;" class="mycode_b">Storage Provider</span>: Amazon S3, Wasabi, DigitalOcean Spaces, Dropbox, Google Drive, Hetzner Storage Box, SFTP or a custom Rclone config.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=311" target="_blank" title="">g7-01-ae55.jpg</a> (Size: 87.42 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
Turn on <span style="font-weight: bold;" class="mycode_b">Enable Remote Backup</span> and set the <span style="font-weight: bold;" class="mycode_b">Frequency</span> and <span style="font-weight: bold;" class="mycode_b">Time</span>. Pick a quiet hour, such as 02:00.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=312" target="_blank" title="">g7-02-ae56.jpg</a> (Size: 112.26 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
Enter the <span style="font-weight: bold;" class="mycode_b">bucket</span> and <span style="font-weight: bold;" class="mycode_b">region</span>, an <span style="font-weight: bold;" class="mycode_b">access key</span> and <span style="font-weight: bold;" class="mycode_b">secret key</span>, the storage directory, the <span style="font-weight: bold;" class="mycode_b">retention period</span> (days to keep) and any <span style="font-weight: bold;" class="mycode_b">excludes</span> such as cache folders, then save. (The keys in our screenshot are CloudPanel's example values, not real keys.) Create a key that can only access this one bucket.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=313" target="_blank" title="">g7-03-ae57.jpg</a> (Size: 113.31 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 2: The firewall</span></span><br />
In <span style="font-weight: bold;" class="mycode_b">Admin Area → Security → Firewall</span>, CloudPanel by default allows SSH (22), HTTP (80), HTTPS (443) and the panel (8443) from anywhere.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=314" target="_blank" title="">g7-04-ae58.jpg</a> (Size: 104.35 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Best single step: allow port 8443 only from your own IP.</span> Click <span style="font-weight: bold;" class="mycode_b">Add Rule</span>, type <span style="font-weight: bold;" class="mycode_b">CloudPanel</span>, source <span style="font-weight: bold;" class="mycode_b">Custom</span>, your IP with <span style="font-weight: bold;" class="mycode_b">/32</span>, and save. <span style="font-weight: bold;" class="mycode_b">Add your rule first</span>, then delete the rules that allow 8443 from anywhere, so you don't lock yourself out. Do the same for SSH if you have a fixed IP.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=315" target="_blank" title="">g7-05-ae60.jpg</a> (Size: 103.36 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 3: Basic Auth in front of the panel</span></span><br />
If your IP changes often, use <span style="font-weight: bold;" class="mycode_b">Basic Auth</span> instead (Admin Area → Security → Basic Auth). It puts a second username and password in front of CloudPanel's login page, which stops bots from even reaching it. As root you can also toggle it with:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>clpctl cloudpanel:enable:basic-auth --userName=john --password='a-strong-password'
clpctl cloudpanel:disable:basic-auth</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=316" target="_blank" title="">g7-06-ae61.jpg</a> (Size: 89.63 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 4: Site-level security</span></span><br />
Each site has its own <span style="font-weight: bold;" class="mycode_b">Security</span> tab:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">IP Blocking:</span> block single IPs or whole ranges.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Bot Blocking:</span> block bad bots by user agent, such as the scanners you'll see in your access logs.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=317" target="_blank" title="">g7-07-ae40.jpg</a> (Size: 96.39 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Basic Authentication:</span> password-protect staging copies the public shouldn't see, with a list of <span style="font-weight: bold;" class="mycode_b">whitelisted IPs</span> that skip it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Cloudflare:</span> "Allow traffic from Cloudflare only", so nobody can bypass Cloudflare by hitting your server's IP directly.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=318" target="_blank" title="">g7-08-ae42.jpg</a> (Size: 84.98 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 5: Keep everything updated</span></span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>apt update &amp;&amp; apt -y upgrade
# take a snapshot of the server at your provider first
clp-update
reboot   # when a new kernel was installed</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Security checklist</span></span><ul class="mycode_list"><li>Remote backups on, with a tested restore.<br />
</li>
<li>Port 8443 restricted to your IP, or Basic Auth enabled.<br />
</li>
<li>Two-factor authentication on your CloudPanel admin user.<br />
</li>
<li>SSH keys instead of passwords; SSH restricted if you have a fixed IP.<br />
</li>
<li>Bad bots and abusive IPs blocked per site; Cloudflare-only mode if you use Cloudflare.<br />
</li>
<li>OS and CloudPanel updated regularly.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Security Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Backups, firewall and Basic Auth</span> (you are here)<br />
</li>
</ol>
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[CloudPanel Cron Jobs, Logs and Varnish Cache: Complete Guide]]></title>
			<link>https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide</link>
			<pubDate>Wed, 14 Oct 2026 21:10:14 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=1">JAY</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide</guid>
			<description><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel cron jobs, logs and Varnish Cache</span></span><br />
<br />
Three tools you'll use on every CloudPanel site: <span style="font-weight: bold;" class="mycode_b">cron jobs</span> for scheduled tasks, the <span style="font-weight: bold;" class="mycode_b">Logs</span> tab for troubleshooting, and <span style="font-weight: bold;" class="mycode_b">Varnish Cache</span> for fast page loads. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 1: Cron jobs</span></span><br />
Open the site's <span style="font-weight: bold;" class="mycode_b">Cron Jobs</span> tab and click <span style="font-weight: bold;" class="mycode_b">Add Cron Job</span>. The <span style="font-weight: bold;" class="mycode_b">Template</span> menu fills in common schedules for you, from every minute to once a month, or you can type the five fields yourself: minute, hour, day, month and weekday.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=305" target="_blank" title="">g6-01-ae47.jpg</a> (Size: 98.57 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Example: a real cron for WordPress.</span> WordPress's built-in cron only runs when someone visits the site. Run it every 5 minutes with real cron instead:<ul class="mycode_list"><li>Template: <span style="font-weight: bold;" class="mycode_b">Every 5 minutes</span> (<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>*/5 * * * *</code></div></div>)<br />
</li>
<li>Command:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>php /home/SITE_USER/htdocs/YOUR_DOMAIN/wp-cron.php &gt; /dev/null 2&gt;&amp;1</code></div></div></li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=306" target="_blank" title="">g6-02-ae48.jpg</a> (Size: 103.82 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
Then add this line to <span style="font-weight: bold;" class="mycode_b">wp-config.php</span> so WordPress doesn't also run it on page loads:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>define('DISABLE_WP_CRON', true);</code></div></div><br />
The job is saved and runs <span style="font-weight: bold;" class="mycode_b">as the site user</span>, with exactly the same permissions as the website.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=307" target="_blank" title="">g6-03-ae52.jpg</a> (Size: 101.13 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 2: Logs</span></span><br />
When something breaks, open the <span style="font-weight: bold;" class="mycode_b">Logs</span> tab. Choose the source (<span style="font-weight: bold;" class="mycode_b">NGINX</span> or <span style="font-weight: bold;" class="mycode_b">PHP</span>), the file (<span style="font-weight: bold;" class="mycode_b">access</span> or <span style="font-weight: bold;" class="mycode_b">error</span>) and how many lines to show, then click <span style="font-weight: bold;" class="mycode_b">Update</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=308" target="_blank" title="">g6-04-ae50.jpg</a> (Size: 148.44 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
Each access-log line is one request: time, visitor IP, URL and status code. In our screenshot, a bot was probing for <span style="font-weight: bold;" class="mycode_b">.env</span> files (which can contain secrets) minutes after the site went live. That's normal on the internet, and a good reason to block bad bots in the site's Security tab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting tip:</span> for 500 errors or blank pages, check the <span style="font-weight: bold;" class="mycode_b">PHP error log</span> first; for 404s and redirects, the <span style="font-weight: bold;" class="mycode_b">Nginx access log</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 3: Varnish Cache</span></span><br />
Varnish stores finished pages in memory, so repeat visitors are served without running PHP at all. It's <span style="font-weight: bold;" class="mycode_b">off by default</span>; switch it on per site in the <span style="font-weight: bold;" class="mycode_b">Varnish Cache</span> tab.<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Cache Lifetime:</span> how long pages are kept.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Excluded Params:</span> requests with these parameters bypass the cache (for example sessions).<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=309" target="_blank" title="">g6-05-ae39.jpg</a> (Size: 103.92 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">When to use it:</span> Varnish is a big win for blogs and content sites. For shops and member areas, test carefully: logged-in pages must never be cached for everyone. For WordPress, CloudPanel's <span style="font-weight: bold;" class="mycode_b">CLP Varnish Cache</span> plugin clears the cache when you publish.<br />
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Varnish Cache &amp; Performance Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Cron jobs, logs and Varnish Cache</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></description>
			<content:encoded><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel cron jobs, logs and Varnish Cache</span></span><br />
<br />
Three tools you'll use on every CloudPanel site: <span style="font-weight: bold;" class="mycode_b">cron jobs</span> for scheduled tasks, the <span style="font-weight: bold;" class="mycode_b">Logs</span> tab for troubleshooting, and <span style="font-weight: bold;" class="mycode_b">Varnish Cache</span> for fast page loads. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 1: Cron jobs</span></span><br />
Open the site's <span style="font-weight: bold;" class="mycode_b">Cron Jobs</span> tab and click <span style="font-weight: bold;" class="mycode_b">Add Cron Job</span>. The <span style="font-weight: bold;" class="mycode_b">Template</span> menu fills in common schedules for you, from every minute to once a month, or you can type the five fields yourself: minute, hour, day, month and weekday.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=305" target="_blank" title="">g6-01-ae47.jpg</a> (Size: 98.57 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Example: a real cron for WordPress.</span> WordPress's built-in cron only runs when someone visits the site. Run it every 5 minutes with real cron instead:<ul class="mycode_list"><li>Template: <span style="font-weight: bold;" class="mycode_b">Every 5 minutes</span> (<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>*/5 * * * *</code></div></div>)<br />
</li>
<li>Command:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>php /home/SITE_USER/htdocs/YOUR_DOMAIN/wp-cron.php &gt; /dev/null 2&gt;&amp;1</code></div></div></li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=306" target="_blank" title="">g6-02-ae48.jpg</a> (Size: 103.82 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
Then add this line to <span style="font-weight: bold;" class="mycode_b">wp-config.php</span> so WordPress doesn't also run it on page loads:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>define('DISABLE_WP_CRON', true);</code></div></div><br />
The job is saved and runs <span style="font-weight: bold;" class="mycode_b">as the site user</span>, with exactly the same permissions as the website.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=307" target="_blank" title="">g6-03-ae52.jpg</a> (Size: 101.13 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 2: Logs</span></span><br />
When something breaks, open the <span style="font-weight: bold;" class="mycode_b">Logs</span> tab. Choose the source (<span style="font-weight: bold;" class="mycode_b">NGINX</span> or <span style="font-weight: bold;" class="mycode_b">PHP</span>), the file (<span style="font-weight: bold;" class="mycode_b">access</span> or <span style="font-weight: bold;" class="mycode_b">error</span>) and how many lines to show, then click <span style="font-weight: bold;" class="mycode_b">Update</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=308" target="_blank" title="">g6-04-ae50.jpg</a> (Size: 148.44 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
Each access-log line is one request: time, visitor IP, URL and status code. In our screenshot, a bot was probing for <span style="font-weight: bold;" class="mycode_b">.env</span> files (which can contain secrets) minutes after the site went live. That's normal on the internet, and a good reason to block bad bots in the site's Security tab.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting tip:</span> for 500 errors or blank pages, check the <span style="font-weight: bold;" class="mycode_b">PHP error log</span> first; for 404s and redirects, the <span style="font-weight: bold;" class="mycode_b">Nginx access log</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Part 3: Varnish Cache</span></span><br />
Varnish stores finished pages in memory, so repeat visitors are served without running PHP at all. It's <span style="font-weight: bold;" class="mycode_b">off by default</span>; switch it on per site in the <span style="font-weight: bold;" class="mycode_b">Varnish Cache</span> tab.<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Cache Lifetime:</span> how long pages are kept.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Excluded Params:</span> requests with these parameters bypass the cache (for example sessions).<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=309" target="_blank" title="">g6-05-ae39.jpg</a> (Size: 103.92 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">When to use it:</span> Varnish is a big win for blogs and content sites. For shops and member areas, test carefully: logged-in pages must never be cached for everyone. For WordPress, CloudPanel's <span style="font-weight: bold;" class="mycode_b">CLP Varnish Cache</span> plugin clears the cache when you publish.<br />
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Varnish Cache &amp; Performance Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Cron jobs, logs and Varnish Cache</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[CloudPanel SSH, SFTP, FTP and File Manager: How to Upload Files]]></title>
			<link>https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files</link>
			<pubDate>Wed, 14 Oct 2026 21:09:43 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=1">JAY</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files</guid>
			<description><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel SSH, SFTP, FTP and File Manager: how to upload files</span></span><br />
<br />
This guide covers every way to get files onto a CloudPanel site: the site user over SSH and SFTP, SSH keys, extra SSH and FTP users for developers, and the built-in File Manager, plus the one habit that prevents permission problems. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">1. The site user: your main login</span></span><br />
Every site already has one login: its <span style="font-weight: bold;" class="mycode_b">site user</span>. In the site's <span style="font-weight: bold;" class="mycode_b">Settings</span> tab you can reset its password, or paste your <span style="font-weight: bold;" class="mycode_b">public SSH key</span> to log in with a key instead of a password.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=302" target="_blank" title="">g5-01-ae10.jpg</a> (Size: 76.29 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">2. Log in over SSH</span></span><br />
From your own computer:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ssh SITE_USER@YOUR_SERVER_IP
ls
# backups  htdocs  logs  tmp
ls htdocs
# example.com</code></div></div>You land in the site user's home. Your website lives in <span style="font-weight: bold;" class="mycode_b">htdocs/YOUR_DOMAIN</span>. A site user can't see any other site.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">3. Upload with SFTP (FileZilla, WinSCP, Cyberduck)</span></span><br />
Use <span style="font-weight: bold;" class="mycode_b">SFTP</span>, not plain FTP:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Protocol: SFTP
Host:     YOUR_SERVER_IP
Port:     22
User:     SITE_USER  (password or SSH key)
Folder:   /home/SITE_USER/htdocs/YOUR_DOMAIN</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">4. Extra SSH and FTP users</span></span><br />
Need to give a developer access without sharing the main login? Open the <span style="font-weight: bold;" class="mycode_b">SSH/FTP</span> tab → <span style="font-weight: bold;" class="mycode_b">SSH Users</span> → <span style="font-weight: bold;" class="mycode_b">Add User</span>. They get their own password or key, and you delete them when the job's done.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">FTP Users</span> work the same way, for older tools that only speak FTP. Plain FTP isn't encrypted, so prefer SFTP. If you do use FTP, you'll also need to allow the FTP and passive ports in the firewall (Admin Area → Security).<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=303" target="_blank" title="">g5-02-ae43.jpg</a> (Size: 97.02 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">5. The File Manager</span></span><br />
The <span style="font-weight: bold;" class="mycode_b">File Manager</span> tab works in your browser: upload, create, edit, rename, compress and extract files, and see the owner and permissions of each one. Everything is owned by the site user, which is exactly what PHP needs to write uploads and caches.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=304" target="_blank" title="">g5-03-ae45.jpg</a> (Size: 132.72 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Avoid permission problems: don't work as root</span></span><br />
Don't create site files as <span style="font-weight: bold;" class="mycode_b">root</span> over SSH. They'd be owned by root, and the site couldn't change them (failed uploads, cache errors, plugin updates that won't install). Always log in as the <span style="font-weight: bold;" class="mycode_b">site user</span> (or an extra SSH user for that site) and you'll never have permission problems.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Security tips</span></span><ul class="mycode_list"><li>Prefer SSH keys over passwords.<br />
</li>
<li>Remove extra SSH/FTP users as soon as they're not needed.<br />
</li>
<li>If you have a fixed IP, restrict port 22 to it in Admin Area → Security → Firewall.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Users, SSH &amp; SFTP Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">SSH, SFTP, FTP and File Manager</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></description>
			<content:encoded><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel SSH, SFTP, FTP and File Manager: how to upload files</span></span><br />
<br />
This guide covers every way to get files onto a CloudPanel site: the site user over SSH and SFTP, SSH keys, extra SSH and FTP users for developers, and the built-in File Manager, plus the one habit that prevents permission problems. Tested on CloudPanel 2.5.4, Ubuntu 24.04.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">1. The site user: your main login</span></span><br />
Every site already has one login: its <span style="font-weight: bold;" class="mycode_b">site user</span>. In the site's <span style="font-weight: bold;" class="mycode_b">Settings</span> tab you can reset its password, or paste your <span style="font-weight: bold;" class="mycode_b">public SSH key</span> to log in with a key instead of a password.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=302" target="_blank" title="">g5-01-ae10.jpg</a> (Size: 76.29 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">2. Log in over SSH</span></span><br />
From your own computer:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ssh SITE_USER@YOUR_SERVER_IP
ls
# backups  htdocs  logs  tmp
ls htdocs
# example.com</code></div></div>You land in the site user's home. Your website lives in <span style="font-weight: bold;" class="mycode_b">htdocs/YOUR_DOMAIN</span>. A site user can't see any other site.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">3. Upload with SFTP (FileZilla, WinSCP, Cyberduck)</span></span><br />
Use <span style="font-weight: bold;" class="mycode_b">SFTP</span>, not plain FTP:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Protocol: SFTP
Host:     YOUR_SERVER_IP
Port:     22
User:     SITE_USER  (password or SSH key)
Folder:   /home/SITE_USER/htdocs/YOUR_DOMAIN</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">4. Extra SSH and FTP users</span></span><br />
Need to give a developer access without sharing the main login? Open the <span style="font-weight: bold;" class="mycode_b">SSH/FTP</span> tab → <span style="font-weight: bold;" class="mycode_b">SSH Users</span> → <span style="font-weight: bold;" class="mycode_b">Add User</span>. They get their own password or key, and you delete them when the job's done.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">FTP Users</span> work the same way, for older tools that only speak FTP. Plain FTP isn't encrypted, so prefer SFTP. If you do use FTP, you'll also need to allow the FTP and passive ports in the firewall (Admin Area → Security).<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=303" target="_blank" title="">g5-02-ae43.jpg</a> (Size: 97.02 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">5. The File Manager</span></span><br />
The <span style="font-weight: bold;" class="mycode_b">File Manager</span> tab works in your browser: upload, create, edit, rename, compress and extract files, and see the owner and permissions of each one. Everything is owned by the site user, which is exactly what PHP needs to write uploads and caches.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=304" target="_blank" title="">g5-03-ae45.jpg</a> (Size: 132.72 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Avoid permission problems: don't work as root</span></span><br />
Don't create site files as <span style="font-weight: bold;" class="mycode_b">root</span> over SSH. They'd be owned by root, and the site couldn't change them (failed uploads, cache errors, plugin updates that won't install). Always log in as the <span style="font-weight: bold;" class="mycode_b">site user</span> (or an extra SSH user for that site) and you'll never have permission problems.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Security tips</span></span><ul class="mycode_list"><li>Prefer SSH keys over passwords.<br />
</li>
<li>Remove extra SSH/FTP users as soon as they're not needed.<br />
</li>
<li>If you have a fixed IP, restrict port 22 to it in Admin Area → Security → Firewall.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Users, SSH &amp; SFTP Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin" target="_blank" rel="noopener" class="mycode_url">Databases, users and phpMyAdmin</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">SSH, SFTP, FTP and File Manager</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[CloudPanel Databases: Create a Database, Users and Use phpMyAdmin]]></title>
			<link>https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin</link>
			<pubDate>Wed, 14 Oct 2026 21:09:13 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=1">JAY</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-cloudpanel-databases-create-a-database-users-and-use-phpmyadmin</guid>
			<description><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel databases: create a database and users, and use phpMyAdmin</span></span><br />
<br />
In CloudPanel, <span style="font-weight: bold;" class="mycode_b">databases belong to a site</span>. This guide shows how to create a database and user, add extra users with limited rights, open phpMyAdmin, handle large imports from the command line, and where CloudPanel keeps automatic database backups. Tested on CloudPanel 2.5.4, Ubuntu 24.04, MySQL 8.4.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 1: Open the site's Databases tab</span></span><br />
Open <span style="font-weight: bold;" class="mycode_b">Sites</span> → <span style="font-weight: bold;" class="mycode_b">Manage</span> → <span style="font-weight: bold;" class="mycode_b">Databases</span>. Our WordPress database is already listed, created by the one-click installer. Note the connection details at the top: host <span style="font-weight: bold;" class="mycode_b">127.0.0.1</span>, port <span style="font-weight: bold;" class="mycode_b">3306</span>. Your app uses these.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=298" target="_blank" title="">g4-01-ae34.jpg</a> (Size: 103.25 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 2: Add a database</span></span><br />
Click <span style="font-weight: bold;" class="mycode_b">Add Database</span> and enter a database name, a database user name and a password. CloudPanel creates both and grants the user access in one step.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 3: Add extra database users</span></span><br />
The <span style="font-weight: bold;" class="mycode_b">Database Users</span> list shows every user, the database it can reach and its permissions. Use <span style="font-weight: bold;" class="mycode_b">Add Database User</span> for extra users, with <span style="font-weight: bold;" class="mycode_b">Read and Write</span> or <span style="font-weight: bold;" class="mycode_b">Read Only</span> access. A read-only user is ideal for reporting or backup tools, which then can never change your data.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=299" target="_blank" title="">g4-02-ae36.jpg</a> (Size: 104.64 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 4: Open phpMyAdmin with one click</span></span><br />
Click <span style="font-weight: bold;" class="mycode_b">Manage</span> next to a database user and phpMyAdmin opens already logged in as that user, with no extra password to type. Browse tables, run SQL, and import or export from the tabs at the top.<br />
<br />
On the right, phpMyAdmin shows the server. On our install it's <span style="font-weight: bold;" class="mycode_b">Percona Server 8.4</span>, a drop-in MySQL build, chosen when we ran the installer.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=300" target="_blank" title="">g4-03-ae38.jpg</a> (Size: 178.15 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 5: Big imports and exports with clpctl</span></span><br />
Large databases can time out in the browser. As root, use clpctl instead:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code># export a compressed dump
clpctl db:export --databaseName=my-database --file=/tmp/dump.sql.gz

# import a dump
clpctl db:import --databaseName=my-database --file=/tmp/dump.sql.gz

# create a database and user from the shell
clpctl db:add --domainName=example.com --databaseName=my-database --databaseUserName=myuser --databaseUserPassword='a-strong-password'

# show the database root (master) login
clpctl db:show:master-credentials</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Automatic database backups</span></span><br />
CloudPanel also dumps every database automatically each night (at 03:15 on our server) into the <span style="font-weight: bold;" class="mycode_b">backups</span> folder in the site user's home, and keeps 7 days of them. It's a useful safety net, but it's on the same server, so also set up <span style="font-weight: bold;" class="mycode_b">remote backups</span> in the Admin Area.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=301" target="_blank" title="">g4-04-ae45.jpg</a> (Size: 132.72 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Tips</span></span><ul class="mycode_list"><li>Give each app its own database user, and use read-only users wherever writing isn't needed.<br />
</li>
<li>Never expose port 3306 in the firewall; apps on the same server connect via 127.0.0.1.<br />
</li>
<li>Keep the master credentials for emergencies only.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Databases &amp; phpMyAdmin Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Databases, users and phpMyAdmin</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></description>
			<content:encoded><![CDATA[<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel databases: create a database and users, and use phpMyAdmin</span></span><br />
<br />
In CloudPanel, <span style="font-weight: bold;" class="mycode_b">databases belong to a site</span>. This guide shows how to create a database and user, add extra users with limited rights, open phpMyAdmin, handle large imports from the command line, and where CloudPanel keeps automatic database backups. Tested on CloudPanel 2.5.4, Ubuntu 24.04, MySQL 8.4.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 1: Open the site's Databases tab</span></span><br />
Open <span style="font-weight: bold;" class="mycode_b">Sites</span> → <span style="font-weight: bold;" class="mycode_b">Manage</span> → <span style="font-weight: bold;" class="mycode_b">Databases</span>. Our WordPress database is already listed, created by the one-click installer. Note the connection details at the top: host <span style="font-weight: bold;" class="mycode_b">127.0.0.1</span>, port <span style="font-weight: bold;" class="mycode_b">3306</span>. Your app uses these.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=298" target="_blank" title="">g4-01-ae34.jpg</a> (Size: 103.25 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 2: Add a database</span></span><br />
Click <span style="font-weight: bold;" class="mycode_b">Add Database</span> and enter a database name, a database user name and a password. CloudPanel creates both and grants the user access in one step.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 3: Add extra database users</span></span><br />
The <span style="font-weight: bold;" class="mycode_b">Database Users</span> list shows every user, the database it can reach and its permissions. Use <span style="font-weight: bold;" class="mycode_b">Add Database User</span> for extra users, with <span style="font-weight: bold;" class="mycode_b">Read and Write</span> or <span style="font-weight: bold;" class="mycode_b">Read Only</span> access. A read-only user is ideal for reporting or backup tools, which then can never change your data.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=299" target="_blank" title="">g4-02-ae36.jpg</a> (Size: 104.64 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 4: Open phpMyAdmin with one click</span></span><br />
Click <span style="font-weight: bold;" class="mycode_b">Manage</span> next to a database user and phpMyAdmin opens already logged in as that user, with no extra password to type. Browse tables, run SQL, and import or export from the tabs at the top.<br />
<br />
On the right, phpMyAdmin shows the server. On our install it's <span style="font-weight: bold;" class="mycode_b">Percona Server 8.4</span>, a drop-in MySQL build, chosen when we ran the installer.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=300" target="_blank" title="">g4-03-ae38.jpg</a> (Size: 178.15 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Step 5: Big imports and exports with clpctl</span></span><br />
Large databases can time out in the browser. As root, use clpctl instead:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code># export a compressed dump
clpctl db:export --databaseName=my-database --file=/tmp/dump.sql.gz

# import a dump
clpctl db:import --databaseName=my-database --file=/tmp/dump.sql.gz

# create a database and user from the shell
clpctl db:add --domainName=example.com --databaseName=my-database --databaseUserName=myuser --databaseUserPassword='a-strong-password'

# show the database root (master) login
clpctl db:show:master-credentials</code></div></div><br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Automatic database backups</span></span><br />
CloudPanel also dumps every database automatically each night (at 03:15 on our server) into the <span style="font-weight: bold;" class="mycode_b">backups</span> folder in the site user's home, and keeps 7 days of them. It's a useful safety net, but it's on the same server, so also set up <span style="font-weight: bold;" class="mycode_b">remote backups</span> in the Admin Area.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=301" target="_blank" title="">g4-04-ae45.jpg</a> (Size: 132.72 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Tips</span></span><ul class="mycode_list"><li>Give each app its own database user, and use read-only users wherever writing isn't needed.<br />
</li>
<li>Never expose port 3306 in the firewall; apps on the same server connect via 127.0.0.1.<br />
</li>
<li>Keep the master credentials for emergencies only.<br />
</li>
</ul>
<br />
Questions? Ask in <span style="font-weight: bold;" class="mycode_b">CloudPanel Databases &amp; phpMyAdmin Support</span>.<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">CloudPanel guide series</span></span><br />
<ol type="1" class="mycode_list"><li><a href="https://adminsforum.com/Thread-guide-what-is-cloudpanel-complete-overview-of-the-free-hosting-control-panel-2026" target="_blank" rel="noopener" class="mycode_url">What is CloudPanel? Complete overview</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-system-requirements-2026-os-cpu-ram-disk-and-ports" target="_blank" rel="noopener" class="mycode_url">CloudPanel system requirements</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-features-the-complete-list-2026" target="_blank" rel="noopener" class="mycode_url">CloudPanel features: the complete list</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-create-a-php-site-in-cloudpanel-step-by-step-2026" target="_blank" rel="noopener" class="mycode_url">How to create a PHP site</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-a-free-let-s-encrypt-ssl-certificate-in-cloudpanel" target="_blank" rel="noopener" class="mycode_url">How to install free Let's Encrypt SSL</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-how-to-install-wordpress-in-cloudpanel-one-click-setup-guide" target="_blank" rel="noopener" class="mycode_url">How to install WordPress (one-click)</a><br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Databases, users and phpMyAdmin</span> (you are here)<br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-ssh-sftp-ftp-and-file-manager-how-to-upload-files" target="_blank" rel="noopener" class="mycode_url">SSH, SFTP, FTP and File Manager</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-cron-jobs-logs-and-varnish-cache-complete-guide" target="_blank" rel="noopener" class="mycode_url">Cron jobs, logs and Varnish Cache</a><br />
</li>
<li><a href="https://adminsforum.com/Thread-guide-cloudpanel-backups-and-security-remote-backups-firewall-and-basic-auth" target="_blank" rel="noopener" class="mycode_url">Backups, firewall and Basic Auth</a><br />
</li>
</ol>
]]></content:encoded>
		</item>
	</channel>
</rss>