# New WordPress Site — Full Procedure Step-by-step for spinning up a new WordPress site on kaburusvr from scratch. Covers subdomain or top-level domain. Tested against WordPress 7.0 / CyberPanel on Ubuntu 24. --- ## Prerequisites - Domain or subdomain DNS pointing to `49.13.202.144` via Cloudflare (proxied) - CyberPanel admin access - SSH access to kaburusvr (root) - Cloudflare API token available at `/root/.acme.sh/account.conf` → `SAVED_CF_Token` --- ## Step 1 — Cloudflare DNS Add the A record before creating the site. CyberPanel will try to verify the domain. ```bash CF_TOKEN=$(grep SAVED_CF_Token /root/.acme.sh/account.conf | cut -d"'" -f2) ZONE_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=" \ -H "Authorization: Bearer $CF_TOKEN" \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result'][0]['id'])") curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \ -H "Authorization: Bearer $CF_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type":"A","name":"","content":"49.13.202.144","proxied":true}' ``` Zones in use: `kaburu.co`, `kaburu.cc`, `kaburu.co.uk` — pick the right one. --- ## Step 2 — Create Site in CyberPanel Via MCP tool or CyberPanel UI. Use PHP 8.3 as default. ``` Domain: Owner: admin Package: Default PHP: PHP 8.3 SSL: true (checkbox — but see Step 3, the cert it issues will fail) openBasedir: true ``` **Note the Linux user CyberPanel assigns** — you need it for Step 5. ```bash # Get it after creation: stat -c '%U' /home/ ``` ### Known gotcha — public_html permissions CyberPanel creates `public_html` as `0750`. LiteSpeed needs `0755` or it returns 403. ```bash chmod 755 /home//public_html ``` This is handled automatically by `wp-install.sh` but must be done before any HTTP requests hit the site (e.g. before issuing the SSL cert via HTTP challenge — irrelevant here since we use DNS-01, but good to know). --- ## Step 3 — Issue SSL **Do not use CyberPanel's "Issue SSL" button.** It uses HTTP-01 challenge which Cloudflare intercepts and 404s. All certs must use DNS-01 via Cloudflare API. ```bash CF_Token=$(grep SAVED_CF_Token /root/.acme.sh/account.conf | cut -d"'" -f2) CF_DNS_API_TOKEN=$CF_Token /root/.acme.sh/acme.sh \ --issue \ -d \ --dns dns_cf \ --server letsencrypt \ --keylength ec-256 mkdir -p /etc/letsencrypt/live/ /root/.acme.sh/acme.sh --install-cert -d --ecc \ --cert-file /etc/letsencrypt/live//cert.pem \ --key-file /etc/letsencrypt/live//privkey.pem \ --fullchain-file /etc/letsencrypt/live//fullchain.pem \ --reloadcmd "systemctl reload lsws" ``` CyberPanel writes the correct cert paths into vhost.conf automatically when you tick SSL on creation — so the vhost is ready, it just needed a real cert dropped in. Verify: ```bash openssl x509 -issuer -enddate -noout -in /etc/letsencrypt/live//fullchain.pem # Should show: issuer=C = US, O = Let's Encrypt (NOT STAGING) ``` See [[ssl-issuance]] for full troubleshooting. --- ## Step 4 — PHP Settings in vhost.conf CyberPanel creates a minimal `phpIniOverride` with only `open_basedir`. Expand it: ``` # /usr/local/lsws/conf/vhosts//vhost.conf phpIniOverride { php_admin_value open_basedir "/tmp:$VH_ROOT" php_value memory_limit 256M php_value upload_max_filesize 256M php_value post_max_size 256M php_value max_execution_time 300 php_value max_input_time 300 php_value max_input_vars 10000 } ``` Then reload LiteSpeed: ```bash systemctl reload lsws ``` **Note:** `wp-install.sh` does NOT patch vhost.conf — that must be done manually or via a separate step before running the script. The script writes `.user.ini` inside `public_html` for WordPress-level settings, but vhost.conf controls LiteSpeed-level limits which take precedence for upload sizes and execution time. --- ## Step 5 — Install WordPress ```bash wp-install.sh "" ``` - `blank` — bare WordPress, no plugins. Use for client sites being migrated or built fresh. - `full` — WordPress + standard Kaburu plugin set (see below). ### What the script does 1. Creates MariaDB database `_wp` and user `_usr` with a random password 2. Downloads WordPress en_GB (latest, from en-gb.wordpress.org) 3. Writes `wp-config.php` (utf8mb4, localhost) 4. Runs `wp core install` — admin user `kaburu`, email `web@kaburu.co`, pass `Kaburu2026` 5. Sets locale to en_GB 6. Writes `.user.ini` to `public_html/` with WordPress PHP settings 7. Sets ownership to `:` recursively, dirs 755, files 644, wp-config.php 600 8. `full` only: installs and activates plugin list, then re-fixes ownership ### Full install plugin list Free (from wordpress.org): - `litespeed-cache` — page caching, CDN integration - `mainwp-child` — MainWP management dashboard connection - `seo-by-rank-math` — SEO - `wordfence` — security/WAF - `wp-accessibility` — accessibility fixes - `wp-security-audit-log` — audit log - `complianz-gdpr` — GDPR/cookie consent Premium (from `/usr/local/bin/wp-premium/*.zip` if directory exists): - Any `.zip` files present are installed and activated ### Script internals — important notes - **WP-CLI must use lsphp83**, not system PHP. System PHP (`/usr/bin/php`) has no mysqli extension. Script hardcodes `PHP_BIN=/usr/local/lsws/lsphp83/bin/php`. - **Linux user** is derived from `stat -c '%U' /home/` — not guessed from the domain name. CyberPanel generates usernames like `testm1387`, `rfkab7804` etc. - **Database naming**: `_wp` and `_usr` — matches CyberPanel convention (it prefixes DBs with the Linux username when created via UI). - **`set -euo pipefail`** — script exits hard on any failure. Check `/var/log/wpinstaller.log` for detail. --- ## Step 6 — Connect to MainWP After `full` install, connect the site to MainWP dashboard on `kaburusvr.uk`: 1. MainWP Dashboard → Sites → Add New 2. URL: `https://` 3. Admin: `kaburu` 4. MainWP Child plugin must be active (it is, from step 5) --- ## Step 7 — Post-install checklist ``` [ ] Site loads at https:// — HTTP 200, no SSL error [ ] wp-admin accessible, login with kaburu / Kaburu2026 [ ] Locale is English (UK) — Settings → General [ ] LiteSpeed Cache active and configured [ ] Rank Math active [ ] MainWP Child active + connected [ ] Wordfence active (configure scan schedule) [ ] Complianz active (run setup wizard) [ ] Brevo SMTP configured via Fluent SMTP (if sending email) [ ] Site added to Matomo (stats.kaburu.co) [ ] Cloudflare SSL mode: Full (Strict) for the zone ``` --- ## Script location ``` /usr/local/bin/wp-install.sh ``` Version 2.0 — 2026-06-03. Replaces v1.0 (broken: system PHP, nobody:nobody ownership). --- ## Kaburu defaults reference | Setting | Value | |---------|-------| | WP admin user | `kaburu` | | WP admin email | `web@kaburu.co` | | WP admin pass | `Kaburu2026` | | PHP version | PHP 8.3 (lsphp83) | | memory_limit | 256M | | upload_max_filesize | 256M | | max_input_vars | 10000 | | max_execution_time | 300s | | DB charset | utf8mb4 / utf8mb4_unicode_ci | | Locale | en_GB | | SSL | Let's Encrypt production via DNS-01/Cloudflare |