A2 Hosting runbook — Phase 0 cleanup (executed 2026-04-24)¶
The play-by-play of the production cleanup on fruitplug.co.uk (A2 Hosting az1-ts106). Every step below was run via infra/a2/*.py tooling.
Environment snapshot¶
| Value | |
|---|---|
| Host | az1-ts106.a2hosting.com |
| IP | 106.0.62.69 |
| SSH | fruitplu@fruitplug.co.uk:7822 |
| Home | /home/fruitplu |
| WP path | /home/fruitplu/public_html |
| WP | 6.9.4 |
| WC | 10.7.0 |
| PHP | 7.4.33 (EOL — upgrade pending via cPanel) |
| MySQL | 8.0.39 |
| WP-CLI | 2.12.0 |
| Disk | 7.0T total, 159G free (98% full) |
| public_html | 1.6 GB |
1. Backup ✅¶
Command: A2_PASSPHRASE=... python infra/a2/a2.py backup
Remote dir: /home/fruitplu/backups/pre-cleanup-20260424-205535/
| Archive | Size |
|---|---|
db.sql |
69 MB · 105 tables |
wp-content-plugins.tar.gz |
113 MB |
wp-content-themes.tar.gz |
33 MB |
wp-content-mu-plugins.tar.gz |
4 KB (empty — no mu-plugins) |
wp-content-uploads.tar.gz |
936 MB (stays on server) |
Downloaded locally to backups/a2-20260424-205535/ (219 MB) except uploads. Retrieve uploads via python infra/a2/a2.py pull-uploads when needed.
2. Plugin cleanup ✅¶
Ran in 5 batches of 4 (+ final 2), smoke-testing the home page between each.
- Batch 1:
elementor,kingcomposer,unlimited-elements-for-elementor,apus-themer - Batch 2:
mobile-menu-premium,loading-page,wp-multi-step-checkout,woo-checkout-field-editor-pro - Batch 3:
xt-woo-ajax-add-to-cart,woo-variation-swatches,show-only-lowest-prices-in-woocommerce-variable-products,customize-my-account-for-woocommerce - Batch 4:
google-site-kit,woocommerce-google-analytics-integration,meta-tag-manager,pdf-catalog-woocommerce-pro - Batch 5:
cost-of-goods-for-woocommerce,printify-for-woocommerce
All 18 deactivated cleanly (home returned 200 after every batch), then wp plugin delete removed the files.
Active count: 38 → 20 plugins.
3. Revisions cleanup ✅¶
wp post delete $(wp post list --post_type=revision --format=ids) --force
Before: 578 revisions. After: 0.
4. HPOS migration ⏳ DEFERRED¶
Attempted wp option update woocommerce_custom_orders_table_enabled yes → Woo fatal error because orders in the old posts table aren't synced to the HPOS tables yet.
Proper flow requires the admin UI:
- Log in to wp-admin → WooCommerce → Settings → Advanced → Features
- Enable Order data storage: High-performance order storage (HPOS) — this turns on sync in compatibility mode
- Wait until the order sync banner clears (4,188 orders; should take 10–30 min depending on server load)
- Set Compatibility mode off
- Verify with
wp option get woocommerce_custom_orders_table_enabled→ should returnyes
5. Data fixes ✅¶
Categories rebalanced.
Before:
- Uncategorized: 6 products (2 rare fruits, 1 box, 3 specials)
- Signature Collection Box appeared in both Fruits and Fruit Plug Boxes
After: | Category | Count | |---|---| | Rare & Special (NEW) | 5 | | Fruit Plug Boxes | 4 | | Fruits | 24 | | Merchandise | 10 | | Subscription | 3 | | Uncategorized | 0 |
- Created
Rare & Special(term_id 149, slugrare-special) — Super Rare Cacao Pod, MANGO MADNESS, Soursop leaves, Jelly nut coconut, Super Rare Annona - Moved
Guineps (Box)into Boxes (was Uncategorized) - Removed Signature Collection Box from the Fruits category (it's a box, not a fruit)
- PWA
/shop/rare-specialgoes live automatically via the Woo Store API
6. Fruit description rewrites ⏳ PENDING¶
Manual content work: 26 fruits × ~80 words each, consolidating from the existing Preparation Guide page. Can be done in wp-admin → Products → Quick Edit, or bulk via wp post update <id> --post_content="...".
7. PHP 7.4 → 8.2 upgrade ✅¶
Upgraded via cPanel → Account PHP Settings (global). On first switch the site 500'd because the default extension set on PHP 8.2 missed some WP-required extensions. Fix was ticking them in cPanel → Select PHP Version → Extensions:
| Extension | Status before | After |
|---|---|---|
mysqli |
unchecked | ✅ ticked |
sodium |
unchecked | ✅ ticked |
imagick |
unchecked | ✅ ticked |
Already-enabled extensions that WP needs and we confirmed present: mysqlnd, pdo_mysql, gd, curl, intl, mbstring, zip, openssl, xml, dom, json, bcmath, fileinfo.
Site restored to 200 on the next request.
8. fruitplug-api plugin install ✅¶
- 14 files uploaded via SFTP to
wp-content/plugins/fruitplug-api/ wp plugin activate fruitplug-apisucceeded- Activation hook ran
Migrations::activate()which created: wp_fruitplug_points_ledgerwp_fruitplug_streakswp_fruitplug_passportwp_fruitplug_saved_boxeswp_fruitplug_referralswp_fruitplug_push_endpointswp_fruitplug_reel_products- Default seasonal calendar seeded in
wp_options(fruitplug_seasonal_calendar) - REST health check at
/wp-json/fruitplug/v1/healthreturns{"status":"ok", …}
Active plugin count: 21 (20 cleanup survivors + fruitplug-api)
8. Remaining active plugins (20)¶
| Plugin | Audit verdict |
|---|---|
| woocommerce | keep (core) |
| woocommerce-payments | keep (Stripe) |
| woocommerce-subscriptions | keep (migration bridge) |
| woocommerce-shipstation-integration | keep (fulfilment) |
| woocommerce-shipment-tracking | keep |
| local-delivery-drivers-for-woocommerce | keep |
| bp-custom-order-status-for-woocommerce | keep (driver statuses) |
| customer-reviews-woocommerce | keep (218 reviews) |
| woo-update-manager | keep (commercial updater) |
| mailchimp-for-woocommerce | keep (email) |
| google-listings-and-ads | keep (Merchant Center) |
| facebook-for-woocommerce | keep (Meta pixel) |
| tiktok-for-business | keep (TikTok pixel) |
| redirection | keep (URL redirects for migration) |
| jetpack-protect | keep (security) |
| easy-hide-login | keep (security) |
| wordpress-seo | keep (user-confirmed) |
| cmb2 | evaluate (check dependencies) |
| jetpack | evaluate (remove unless Backup is used) |
| akismet | evaluate (remove — we don't accept WP comments) |