Home › Blog › Article

Deploy WordPress on Baota LNMP: Root, Perms, Rewrites

Deploy WordPress on Baota LNMP: Root, Perms, Rewrites

Deploy WordPress on LNMP by pointing the Nginx document root to your site folder (often a subdirectory), setting directories to 755 and files to 644, loading a WordPress rewrite block in the server config, and running PHP 8.3 with required extensions. It is done right when the homepage loads, /wp-admin redirects correctly, permalinks other than the homepage return 200 (not 404), and no file is owned by www with write permission on PHP files. Verify with curl -I, namei -l and php -m.

Preparation Before You Deploy

Confirm you run Baota Panel (as of 2026, version 9.x is current) with the LNMP stack: Nginx 1.26 or 1.27, MySQL 8.0 or MariaDB 10.11, and PHP 8.3 installed via the Baota software store. Create the site in Baota first so the panel generates /www/wwwroot/example.com and a matching Nginx vhost at /www/server/panel/vhost/nginx/example.com.conf. Have SSH root access and know the runtime user: Baota normally runs PHP-FPM and Nginx as the www user. Back up any existing vhost file before editing. If you are planning a larger build, our Custom WordPress Development team can provision the stack to spec before you begin.

Deployment Step Process

  1. Upload WordPress core into the chosen document root (or subdirectory) and set ownership.
  2. Apply 755 to directories and 644 to files across the web root.
  3. Edit the Baota Nginx vhost to set root and include WordPress rewrite rules.
  4. Confirm PHP 8.3 and extensions (mysqli, curl, gd, mbstring, zip, intl, openssl) are active.
  5. Reload Nginx, run the installer, then verify with HTTP status checks.
  6. Roll back from the saved vhost backup and file-permission snapshot if any step fails.

1. Document Root in a Subdirectory

A document root in a subdirectory means Nginx serves WordPress from a folder such as /www/wwwroot/example.com/wordpress rather than the site root itself. This is common when you host a landing page at the domain root and WordPress under /blog, or when Baota creates the root but you keep core files isolated. Set it in the vhost root directive, not with an alias, so PHP-FPM receives the correct SCRIPT_FILENAME.

Edit the vhost root

Open the generated config and change the root line. Baota writes the vhost per site; edit that file rather than nginx.conf.

server {
    listen 80;
    server_name example.com www.example.com;
    root /www/wwwroot/example.com/wordpress;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        fastcgi_pass unix:/tmp/php-cgi-83.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Verify

Run nginx -t to test syntax, then curl -I http://example.com/. A 200 with X-Powered-By absent or your custom header means the root resolved. To confirm the physical path Nginx uses, temporarily add add_header X-Root $document_root; inside server {}, reload, and inspect the response header.

Pitfall and rollback

The common pitfall is editing root but leaving location blocks with hardcoded paths, causing File not found from PHP-FPM. Roll back by restoring the vhost backup you made: cp /www/backup/nginx/example.com.conf.bak /www/server/panel/vhost/nginx/example.com.conf && nginx -s reload.

2. Directory 755 and File 644

Get a Quote

Email + requirement + budget range — we reply with a quote within 24 hours.

Permissions 755 on directories and 644 on files let the www user read and traverse (execute) into folders and read files, while preventing the web user from writing PHP or theme files. This blocks a whole class of remote code execution after a plugin flaw. Owner should be a deploy user or root; group may be www for upload dirs only.

Apply permissions

From the web root run the two find commands. Never use chmod -R 777.

cd /www/wwwroot/example.com/wordpress
find . -type d -exec chmod 755 {} ;
find . -type f -exec chmod 644 {} ;
chown -R root:www .
chmod -R 775 wp-content/uploads

Verify

Use namei -l wp-config.php to see each path component’s permissions, and ls -ld wp-content/uploads to confirm the uploads dir is group-writable. The installer should not complain about write access to wp-config.php; if it does, permissions are too open, not too closed.

Pitfall and rollback

Applying 644 to wp-config.php before the installer writes it will break setup; temporarily use 600 owned by the deploy user, then revert to 644. Rollback: re-run the two find commands from a known-good state, or restore from your filesystem snapshot.

3. Rewrite Rules

Rewrite rules in Nginx replace Apache .htaccess. For WordPress the core rule is try_files $uri $uri/ /index.php?$args; inside location /, which routes pretty permalinks to index.php while serving static files directly. Baota’s “rewrite” dropdown can include a WordPress template, but writing it manually avoids surprises.

Add the rewrite block

Place this inside the server {} block of the vhost. It handles the front controller and denies access to sensitive files.

location / {
    try_files $uri $uri/ /index.php?$args;
}

location ~* /(?:uploads|files)/.*.php$ {
    deny all;
}

location ~* .(?:php|phar)$ {
    deny all;
}

Verify

Set Settings > Permalinks to Post name, then curl -I http://example.com/sample-page/. Expect HTTP/1.1 200 OK. A 404 means try_files is missing or a conflicting location matched first. Check error_log at /www/wwwlogs/example.com.error.log.

Pitfall and rollback

A second location / or a location ~ .php$ placed before the general block can swallow requests. Roll back to the backed-up vhost and re-add only the try_files line, testing after each change. See the official WordPress Nginx documentation for reference directives.

4. PHP Version and Extensions

4. PHP Version and Extensions

WordPress in 2026 recommends PHP 8.3 (8.2 minimum still supported for a period). Missing extensions cause white screens or failed updates. Baota lets you install PHP 8.3 side-by-side and pick it per site in the site settings.

Confirm version and modules

Use the CLI to check what the site actually runs, not just what the panel shows.

php -v
php -m | grep -E 'mysqli|curl|gd|mbstring|zip|intl|openssl'

In Baota, open Software Store > PHP 8.3 > Extensions and install mysqli, curl, gd, mbstring, zip, intl, openssl, imagick (optional). Restart PHP-FPM after changes.

Verify

Create a temporary phpinfo.php with <?php phpinfo(); in the root, load it, and confirm PHP Version 8.3.x and the modules listed. Delete the file immediately. Site Health > Info should show no missing extension warnings.

Pitfall and rollback

A common pitfall is installing extensions for PHP 8.2 while the site uses 8.3; always match the version suffix in Baota. Roll back by switching the site’s PHP version back in the panel and reinstalling the previous extension set. For deeper recovery steps see our guide on WordPress Site Backup and Restore.

Verification and Rollback

After all steps: homepage 200, /wp-admin 302-to-login then 200, a permalink sample page 200, no PHP files writable by www, and php -v shows 8.3. Keep three rollback assets: the vhost backup, a tar of the web root, and a database dump. Restore in reverse order: database, files, vhost, then nginx -s reload.

Action Checklist

  • Set Nginx root to the subdirectory and test with nginx -t.
  • Run find for 755 dirs and 644 files; keep uploads at 775.
  • Add try_files $uri $uri/ /index.php?$args; and verify a permalink returns 200.
  • Enable PHP 8.3 with mysqli, curl, gd, mbstring, zip, intl, openssl.
  • Back up vhost, files and DB before each change for fast rollback.

Frequently asked questions

Do I need .htaccess on Baota LNMP?

No. Nginx does not read .htaccess. Put rewrite logic in the vhost location / block with try_files, then reload Nginx.

Why do I get “File not found” from PHP-FPM?

The root or SCRIPT_FILENAME does not match the real path. Check the vhost root and ensure fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; is set.

Can uploads stay writable if files are 644?

Yes. Set wp-content/uploads to 775 owned by root:www so the web user writes there only, while PHP files remain 644.

Need production-grade provisioning? Our engineers handle LNMP hardening, CI deploys and performance tuning. Explore our WordPress development services to get a stack built for scale.

References & further reading

Need WordPress Development?

Free proposal and quote within 24 hours — we serve clients worldwide.

QQ