Fixing WordPress Security Recommendations

Fixing WordPress Security Recommendations

So.. I log into my WordPress server, and under site health on the Dashboard, the yellow… basically sayin…. “Do better”

Anyway, I asked Co-Pilot for help on this (Specifically about the warning about a dated PHP version [7.4]), and it basically said:

🛠️ Update PHP for Your WordPress Site

1. Check Your Current PHP Version

  • Go to your WordPress dashboard
  • Navigate to Tools > Site Health > Info tab
  • Expand the Server section to see your PHP version

2. Back Up Your Site First

  • Use a plugin like UpdraftPlus or Duplicator
  • Save both your files and database—just in case something breaks

3. Update PHP via Hosting Control Panel

Depending on your host, the process varies slightly:

Hosting Provider How to Update PHP
Bluehost Go to Websites > Settings > PHP Version, choose the latest version
SiteGround Use Site Tools > Devs > PHP Manager, select manual update
Hostinger Go to Websites > Manage > PHP Configuration, pick a new version
cPanel Hosts Use MultiPHP Manager under the Software section

If you’re unsure where to find this, your host’s support team can guide you.

4. Test Compatibility

  • Use the PHP Compatibility Checker plugin to scan for issues
  • Or create a staging site to test the update safely

5. Update WordPress, Plugins, and Themes

  • Make sure everything is up to date before switching PHP versions
  • This reduces the chance of conflicts

Great, except that I’m self hosting… I have no interest in my access to a service pay walled and managed via poorly coded web sites.  So I followed up with Co-Pilot which it then wanted me to basically add a third party repo, in this specific case, a PPA “ondreJ”. I had a couple issues with this.

  1. This is known as a Frankstein build.
  2. Managing third party repo’s can cause issues, and is usually frown’d apon.

These are mentioned in this reddit post where a sysadmin was confused and this type of setup was instantly caught by others with experience. Which is what AI was telling me to do, it’s reasoning was as follows:

“Ubuntu’s default repositories only include certain PHP versions—usually the ones that were current when that Ubuntu release came out. So if you’re on, say, Ubuntu 22.04 or 24.04, you might only get PHP 8.1 or 8.2 from the official repos. Anything newer (like PHP 8.3 or 8.4)? Not there yet.

That’s why developers lean on Ondřej Surý’s PPA (ppa:ondrej/php). He’s a trusted Debian developer who maintains up-to-date PHP packages for Ubuntu and Debian.”

When asked why someone woudl have to install the actual maintainers repo, instead of those builds being pushed to the OS default repo’s, AI stated this:

“Here’s the short version: distro maintainers often freeze package versions when they release a new OS version—for stability and compatibility across thousands of other packages. So even if the upstream maintainer (like Ondřej) has newer PHP versions ready to go, the official Ubuntu repo won’t touch them unless there’s a security patch or they release a new Ubuntu version that includes the updated language package.”

Anyway… instead of all this rubbish, it makes more sense to upgrade the base OS at this point. So let’s do that.

🛠️ Upgrading Base OS Debain 11 to 12

1. Back Up Your System

You’ve already got backups—perfect. Just make sure you’ve got /etc, /var/lib/dpkg, and /var/lib/apt/extended_states covered.

2. Update Current System

sudo apt update
sudo apt upgrade
sudo apt full-upgrade
sudo apt --purge autoremove

3. Edit Your APT Sources

Replace all instances of bullseye with bookworm in your sources list:

sudo sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list

If you use additional repos in /etc/apt/sources.list.d/, update those too:

sudo sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list.d/*

Optionally, add the new non-free-firmware section:

sudo sed -i 's/non-free/non-free non-free-firmware/g' /etc/apt/sources.list

4. Refresh Package Index

sudo apt update

5. Minimal Upgrade First

sudo apt upgrade --without-new-pkgs

6. Full System Upgrade

sudo apt full-upgrade

Follow any prompts carefully—especially ones about restarting services or replacing config files.

7. Reboot

sudo reboot

8. Verify Upgrade

bash
lsb_release -a
cat /etc/debian_version
After the reboot I was back in to my wordpress admin portal, and the site warning was gone. Yay… but some still remain.. lets see if we can clean these up.. on at a time:
right inactive plugins, that should be easy enough. Deleted 2 unused plugins, and sure enough the warning is gone. Same with themes, let’s do that next.
Appearance -> Themes -> Theme Details -> Delete.
Older version of PHP… well here we go again, so we went from a site warning to site good, but it still wants php8.3… which was discussed above. Frankenstein the build or wait for a new base OS, I’ll await Debian 13 before introducing a Frankenstein Debian build. We’ll ignore this warning.

Recommended Module: ZIP

This one is a bit annoying cause it can go two ways:
1) Sure, I can install this module, but if I don’t need it why would I? Just to remove this warning, I suppose.

Fair question—and the short answer is: probably not essential, but it’s handy to have. 👍

The zip module isn’t required for WordPress to function at a basic level. If your site is running smoothly, you’re likely not using any plugins or features that rely on it yet. But here’s why WordPress flags it:

📦 What the zip Module Is Used For

  • Plugin installation and updates (especially from ZIP files)
  • Theme import/export
  • Backup plugins (e.g., Duplicator, UpdraftPlus)
  • Migration tools

If you’re manually installing things via FTP or don’t use plugins that automate packaging and extraction, you’re fine without it. WordPress just lists it because a lot of plugins assume it’s present.

🧠 TL;DR

  • ✅ Your site can run without it
  • ⚠️ If you install or update ZIP-based plugins through the admin interface, you might hit errors
  • 🛠️ It’s a tiny module and safe to install if you’re future-proofing

How to?

🛠️ Enable the zip PHP Module on Debian 12

1. Install the Extension

Make sure you install the correct version for your PHP setup. If you’re using PHP 8.2 (the default in Debian 12):

sudo apt update
sudo apt install php8.2-zip

If you’ve upgraded to PHP 8.3 via SURY:

sudo apt install php8.3-zip

2. Restart Your Web Server

Depending on your setup:

sudo systemctl restart apache2

3. Verify Installation

Run:

php -m | grep zip

If it returns zip, you’re good to go.

2) Don’t install it from a security stand point:

Security Angle: Why Not Installing zip Might Be Safer

  • Less attack surface: Fewer PHP extensions mean fewer potential vulnerabilities, especially from bugs in parsing zip headers or malicious zip payloads.
  • Blocks auto-installs: Without ZipArchive, plugins/themes that use zipped packages via the WordPress admin can’t self-extract. That forces all installs to be manual—good for auditability.
  • Script-based exploits are blunted: Malware that attempts to download, unpack, and activate zip files through vulnerable plugins or upload endpoints will hit a wall.
  • Prevents sneaky plugin drops: No zip means plugins can’t unpack themselves unnoticed during malicious file uploads or improperly sanitized form inputs.

⚠️ Trade-Offs

  • Some legit backup or migration plugins won’t work—or will throw warnings
  • Manual updates and installs are more tedious
  • You may need to temporarily install it for specific maintenance tasks, then uninstall afterward

Object Cache

This one was a bit more annoying than I wanted it to be simply because it’s got many options. beside 1) Do it vs 2) Don’t do it.

Right now, my site runs fine but doesn’t want a faster site… right… Right?

🔴 Redis

Pros

  • Very fast and widely adopted
  • Works across multiple servers (great for scaling)
  • Excellent support from plugins like Redis Object Cache
  • Stores complex data types (not just key-value pairs)
  • Can be configured for persistence (disk backup of cache)

⚠️ Cons

  • Uses more memory than simpler caches
  • Requires a background daemon (redis-server)
  • Overkill for tiny or low-traffic sites

🔵 Memcached

Pros

  • Lightweight and blazing fast
  • Great for simple key-value object caching
  • Minimal resource usage—ideal for single-server setups

⚠️ Cons

  • Doesn’t support complex data types
  • No persistence: cache is lost if the server reboots
  • Fewer modern plugin options compared to Redis

🟣 APCu

Pros

  • Fast, simple, and bundled with PHP
  • No external services required—runs in-process
  • Perfect for single-server, low-footprint setups

⚠️ Cons

  • Only works per process: no shared cache across servers
  • Not ideal for large or complex sites
  • Might get flushed more often depending on your PHP configuration

In my case I’m going to try memcached, why I unno….

🧰 Install Memcached + WordPress Integration

1. Install Memcached Server + PHP Extension

bash
sudo apt update
sudo apt install memcached php8.2-memcached
sudo systemctl enable memcached
sudo systemctl start memcached

Replace php8.2 with your actual PHP version if needed.

2. Verify Memcached Is Running

echo "stats settings" | nc localhost 11211

You can use Bash’s built-in TCP support:

exec 3<>/dev/tcp/127.0.0.1/11211
echo -e "stats\r\nquit\r\n" >&3
cat <&3

This opens a raw TCP connection and sends the stats command directly.

You should see a list of stats—if not, Memcached isn’t active.

3. Install a WordPress Plugin

The most common plugin for Memcached integration is W3 Total Cache:

  • Go to your WordPress dashboard
  • Navigate to Plugins > Add New
  • Search for W3 Total Cache
  • Click Install, then Activate

4. Configure W3 Total Cache for Memcached

  • Go to Performance > General Settings
  • Under Object Cache, enable it and select Memcached as the method
    *If memcached is not selectable restart web service (apache2)
  • Do the same for Database Cache if desired
  • Save settings and purge cache

✅ Optional: Use a Drop-In Instead of a Plugin

If you want to skip plugins entirely:

  • Download object-cache.php from Memcachy
  • Place it in /wp-content/
  • Add this to wp-config.php:
    php
    define('WP_CACHE', true);
    $memcached_servers = array(
      array('127.0.0.1', 11211)
    );
    

This gives you Memcached support without a full plugin UI.

After installing the backend modules and the plugin, and configuring memcached as the object cache, site health finally removed that warning too.. now the final one.. HTTPS.

HTTPS

Now it’s not possible to access my site via HTTP, not externally anyway. So, why the warning?

Ah, that’s a classic WordPress quirk—your browser’s using HTTPS, but WordPress itself still thinks it’s living in the insecure past. 😅

Here’s how to fix it since you’re self-hosting:

🔐 Update WordPress URLs to Use HTTPS

  1. Log into your WordPress Admin Dashboard
  2. Go to Settings > General
  3. Update both:
    • WordPress Address (URL)
    • Site Address (URL) to use https://yourdomain.com instead of http://
  4. Scroll down and click Save Changes

But it’s greyed out…

🛠️ How to Fix It

  1. Open your wp-config.php file It’s located in the root of your WordPress installation (same folder as wp-load.php and wp-settings.php).
  2. Look for these lines:
    define('WP_HOME','http://yourdomain.com');
    define('WP_SITEURL','http://yourdomain.com');
    

    Or they might be using https:// if you’ve already set up SSL.

  3. Delete or comment them out:
    php
    // define('WP_HOME','https://yourdomain.com');
    // define('WP_SITEURL','https://yourdomain.com');
    
  4. Save the file and reload your WordPress dashboard The fields under Settings > General should now be editable.

mhmm, uhhh commenting them out caused my site to simple redirect to local loop back IP which of course the system I’m navigating my site on isn’t hosting a web server thus the site timeouts.

yeah, that redirect to 127.0.0.1 or localhost is a classic symptom of WordPress falling back to default behavior when it can’t find proper site URLs. Here’s what likely happened:

🧠 Why It Redirected to Localhost

When you commented out WP_HOME and WP_SITEURL in wp-config.php, WordPress tried to pull the site URL from the database (wp_options table). If those values are still set to http://localhost or http://127.0.0.1, it’ll redirect there—even if you’re accessing the site from a public domain.

🛠️ How to Fix It

✅ Option 1: Restore the Correct URLs in wp-config.php

Uncomment and update the lines like this:

define('WP_HOME', 'https://yourdomain.com');
define('WP_SITEURL', 'https://yourdomain.com');

Replace yourdomain.com with your actual domain name.

✅ Option 2: Update URLs Directly in the Database

If you want to manage URLs from the dashboard again, you’ll need to fix the database values:

  1. Access phpMyAdmin or use the MySQL CLI
  2. Run:
    sql
    UPDATE wp_options SET option_value = 'https://yourdomain.com' WHERE option_name IN ('siteurl', 'home');
    
  3. Clear your browser cache and reload the site

You can then safely remove the hardcoded lines from wp-config.php and regain control via the WordPress admin panel.

FINALLY What a PITA… Hope this helps someone…

Small Rabbit Hole

Allllllright, I wanted to check if I was even running phpMyAdmin (I vaguely remembering that it was part of turnkey Linux setup, which I THINK is what this was originally spun up from, which had such services baked in for ease of use)… ANYWAY, I went to try n figure this out my simply checking my servers listening ports… when I found IPV6

🚫 IPv6

I dislike it, others disagree. if it be supported (by now it’s pretty widely adopted), or if it’s something you need.. ughhh, then give er… let  the world be your oyster or some dumb shit. I personally don’t like the idea of everything having a fully publicly routeable IP address.. if it even works that way.. unno… I still stick to IPv4 where, yes I use NAT… ooo nooooo…

Anyway long story short I wanted to disable IPv6 on my WordPress server…

🧱 Method 1: Disable via sysctl (Persistent)

Edit the system config file:

sudo nano /etc/sysctl.conf

Add these lines at the end:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Apply changes:

sudo sysctl -p

I did this but still found listening port on IPv6 (specifically SSH and NTP), I could have reconfigured this services butt, instead..

🧨 Method 2: Blacklist the IPv6 Kernel Module

Create a blacklist file:

sudo nano /etc/modprobe.d/blacklist-ipv6.conf

Add:

blacklist ipv6

Then update initramfs:

sudo update-initramfs -u
sudo reboot

This didn’t work for me.

🧪 Method 3: Disable via GRUB Boot Parameters

Edit GRUB config:

sudo nano /etc/default/grub

Find the line starting with GRUB_CMDLINE_LINUX_DEFAULT and add:

ipv6.disable=1

Example:

GRUB_CMDLINE_LINUX_DEFAULT="quiet ipv6.disable=1"

Update GRUB:

sudo update-grub
sudo reboot

This finally worked!

Rabbit Hole #2: stunnel4

what is stunnel4

Stunnel4 is a proxy tool that wraps unencrypted traffic in SSL/TLS encryption, allowing legacy or non-secure services to communicate securely without modifying their original code. Think of it as a secure tunnel that sits between a client and a server, encrypting everything that passes through.

🔐 What Stunnel4 Does

  • Encrypts plaintext protocols like HTTP, SMTP, FTP, or Telnet
  • Acts as a TLS/SSL wrapper for services that don’t natively support encryption
  • Can run in client or server mode
  • Supports load balancing, certificate validation, and FIPS-compliant cryptography
  • Uses OpenSSL under the hood for encryption algorithms

🧠 How It Works

Imagine you have a mail server that only speaks plain SMTP on port 25. You can configure Stunnel to:

  • Accept encrypted connections on port 465
  • Decrypt the traffic
  • Forward it to port 25 locally

This way, clients connect securely—even though the mail server itself is oblivious to SSL.

🛠️ Typical Use Cases

  • Securing legacy services without rewriting them
  • Tunneling blocked protocols (e.g. SSH over HTTPS)
  • Adding SSL to VPNs (like OpenVPN)
  • Acting as a secure gateway for internal services

Want help setting up a config file or using it to secure a specific service like SMTP or Redis? I can walk you through it.

“Tunneling blocked protocols (e.g. SSH over HTTPS)” This is exactly what I see my system doign on port 12320.. and it shows as service stunel4. but I don’t know if I want to stop the service as a whole…

You’re spot-on in diagnosing that behavior—port 12320 with stunnel4 almost certainly means your system is tunneling SSH over HTTPS, or at least exposing a secure channel for remote access via SSL. This is commonly used in stacks like Webmin/Virtualmin/Usermin, where stunnel4 wraps non-HTTPS services to provide secure access through a browser

🔍 What Port 12320 Usually Does with stunnel4

  • Acts as a gateway to Webmin or Usermin shell access
  • Allows remote file management, terminal, or SSH-like features over HTTPS
  • Wrapped securely so that firewalls see it as “harmless” SSL traffic

You can confirm this by checking:

sudo systemctl status stunnel4
cat /etc/stunnel/stunnel.conf

Or:

grep -r 12320 /etc/stunnel/

That config file should reveal exactly which service is being tunneled.

⚠️ Should You Stop It?

That depends on:

  • Do you use Webmin/Virtualmin remotely?
  • Are you managing your server through a web browser interface?
  • Is 12320 exposed to the public internet or locked behind a firewall?

If you don’t use it and it’s open to the world, you could:

  • Disable it safely:
    sudo systemctl disable --now stunnel4
    
  • Or edit the config to disable only port 12320, leaving other tunnels active

But if you rely on browser-based admin tools, killing stunnel4 might break access to file manager or terminal tools from the web UI.

🧠 Pro Tip

Rather than killing the whole service, you can:

  • Comment out the 12320 tunnel in stunnel.conf
  • Reload the config:
    bash
    sudo systemctl restart stunnel4
    

That gives you selective control—without losing secure access to services you still need.

Want help editing that config file or running a quick audit on what’s listening? I can help you tailor your server’s security posture to your exact setup.

stunnel4.service, Loaded: masked (Reason: unit stunnel4.service is maked.), Active: inactive (dead) grep -r 12320 /etc/stunnel/ /etc/stunnel/shellinabox.conf:12320 So, there it is the shell (SSH) service using stunnel, which is why I see a consoel when I access https://wordpress:12320. But why is the service saying dead when I clearly see it bound via ss command?

Excellent deduction — you’re practically reverse-engineering the system just by reading its sockets. 🧠🔧 Let’s break down what’s happening:

🧩 Why stunnel4.service Says Dead but the Port Is Active

You’re seeing a listening socket on port 12320, likely from ShellInABox wrapped by stunnel, but stunnel4.service reports:

Loaded: masked
Active: inactive (dead)

Here’s the likely cause:

⚙️ Stunnel is running, but not via the stunnel4.service unit

  • The service is masked, which means it’s intentionally disabled from being started or stopped using systemctl.
  • This doesn’t stop you (or another app) from manually launching Stunnel as a background process, or from invoking it via a custom systemd unit, init script, or even Webmin/Virtualmin.

🧠 ss shows the port because:

  • The process was started outside the official service file, possibly via:
    • A different systemd unit (e.g., webmin-stunnel.service)
    • A direct call in /etc/rc.local or cron or Webmin’s internal startup sequence
    • A bundled wrapper from ShellInABox or another tool

🔍 How to Find the Real Parent Process

Let’s track down what’s owning port 12320:

sudo lsof -i :12320

Or:

sudo ss -tulpn | grep 12320

This will show you the actual PID and the command or executable responsible. Likely output will say something like:

LISTEN  ... 12320  ... /usr/bin/stunnel

Once you get the PID, trace it:

ps -fp <PID>

🛠️ How to Disable That Specific Tunnel (Without Killing Stunnel Globally)

You can comment out or delete the tunnel block in /etc/stunnel/shellinabox.conf. Try this:

  1. Edit the config:
    sudo nano /etc/stunnel/shellinabox.conf
    
  2. Comment out all lines by adding #:
    conf
    # accept = 12320
    # connect = 127.0.0.1:12319
    # TIMEOUTclose = 0
    
  3. Save and exit, then reboot.

Rabbit Hole #3: Master

using ss -plunt it shows as service “master” I can’t see that in webmin.. what’s going on here? Port 25

Ah, the mysterious "master" process — that’s actually Postfix, your mail transfer agent (MTA). 📨

When you run:

sudo ss -plunt | grep :25

and see something like:

LISTEN 0 100 0.0.0.0:25 0.0.0.0:* users:(("master",pid=1234,fd=12))

the "master" refers to the Postfix master daemon, which coordinates all the individual Postfix services (like smtp, pickup, qmgr, etc.).

I disabled postfix and sure enough port 25 listener went away.

I also disabled NTP service, to drop listening on port 123.

OK, final one, I saw system listening on port  UDP 10000. I saw one that was TCP based but it was only bound to loopback so I didn’t care about that much, and research showed it’s used by webmin. however I didn’t like the UDP cause it was listening to all interfaces on the system (0.0.0.0).

After enough searching I found it configured by webmin itself.

webmin -> Webmin Configurtaions -> ports and addresses -> “Listen for broadcasts on UDP port” but what is this used for?

The “Listen for broadcasts on UDP port” option in Webmin is used for auto-discovery of other Webmin servers on the local network. Here’s what it’s doing:

📡 What It’s For

  • Webmin listens on UDP port 10000 to receive broadcast packets from other systems running Webmin.
  • These packets are part of the Webmin Servers Index module, which lets you:
    • Scan your LAN for other Webmin instances
    • Automatically add them to a central dashboard
    • Optionally control them via RPC (Remote Procedure Calls)

🧠 Why It’s Optional

  • If you’re not using clustered Webmin setups or don’t need to discover other servers, it’s safe to disable.
  • Disabling it stops Webmin from binding to UDP 10000, which:
    • Reduces your attack surface
    • Cleans up your ss output
    • Avoids confusion when auditing open ports

✅ What Happens When You Turn It Off

  • Webmin will no longer respond to broadcast discovery requests
  • You can still manually add other servers to the Webmin Servers Index if needed
  • The TCP listener on port 10000 (for HTTPS access) remains unaffected

Hope all these tweaks helps someone.

WordPress: Error Establishing a Connection to the Database

This will be a short one, as I didn’t take screen shots, and I didn’t have to do much to resolve it. Just wanted to make note of it.

The other day I wanted to check my own site and instead of loading I got the message “Error Establishing a Connection to the Database”.

I applied my usual fix first; reboot. While the VM was rebooting it appeared there had been some disk corruption? the automatic fsck failed stating a manual fsck was required.

so…

fsck /dev/sda1

and a bunch of “errors” and fix?<y>

after a bunch of answering yes, it stated the disk was repaired successfully.

after this I typed “exit” or “return”, and the system rebooted like normal. Lucky for me the WordPress site came up clean after that. However even had this had failed, we all have backups right?

Migrating WordPress

The Story

In the beginning, there was a man! This man ran! This man ran a site, it was awww inspiring, and so unknown. It ran on Linux in many forms, then one day it realized!!!!!!!! Everything becomes out of date!

Ahem, anyway…

Reasons for migrating

Whatever the reason maybe, mine happens to be this little gem right here:

I’m sorry… did that just say insecure… me… insecure…

OK, sometimes I can be a little insecure but you didn’t have to shove it in my face. Anyway, whatever your reason for migrating maybe. I haven’t done, and maybe you haven’t either. So lets do this… together!

Yeah… I googled… This was my main source, so big thanks to Tom Ewer for this write up much like his mine will be rather indepth and manual. If you wish to avoid learning the nitty gritty and just want to get it done, or use a plugin to help see wpbeginner site here they use a plugin called duplicator and seems to have solid reviews. Since I’m not a fan of paid magic, I’m gonna do this manually.

Migrating WordPress

Step 1 – Backup

Make sure you have a backup of your WordPress Server, in my case since they are VMs, I used Veeam to create a backup of my current WordPress server. Sadly even after logging in to the hosting VM and updating the repos and host OS (Debain 8 Jessie), this version of Debian ran out of support and thus it’s repos weren’t able to supply the updated PHP libraries needed to clear the alert.

After that backup I followed along with Toms blog and instead of FTP (File Transfer Protocol) I used SCP (Yeah… I’m NOT insecure! :P) WinSCP that is, what this actually means I’m not sure apparently either Secure Contain Protect or Special Containment Procedures, but under the hood it just uses SSH? Oh… “Secure Copy (SCP) is method of transferring files between computers over a secure channel. It uses the SSH protocol to do so”

In my case since it was Turnkey Linux, the web files were located at /var/www

Step 2 – Export WP Database

Now Tom ended up using phpMyADmin in his example, I wasn’t sure if the Turnkey image I deployed was using the same, turns out after a quick google search and right on the VMs console, states Adminer on port 12322

after login…

Export….

Left all the default selections…. then… what the….

I was expecting a file to save, so instead I had to select all and save it to a file with Notepad++, all this was, was an output of the DBs in raw SQL.

Step 3 – Create DB Instances

Create your new DB instances, depending on how the SQL server handles DBs imports creation of actual DB’s and their tables may very.

Step 4 – Verify DB Login Credentials

From the backup files in step 1, look in config.php for the DB user connection strings. Verify this user has a login and has proper access rights to the DB’s and Tables being imported.

Now….

What happened to me

Now in my case I simply spun up a new TurnKey WordPress server to see if they were maintaining their images, and sure enough this new was running on Debian 9 Strech, which is the recommended version. So from here although the Adminer version is the same @ 4.2.5 it looks different. Another thing to note was on the old version I was able to login to Adminer with ‘root’ on the new Adminer I had to login in with ‘adminer’.

Now Tom states to create the Databases, I’m not sure if he means the instances here, cause in my case it turns out the creation of the databases happens at import. So what happened to me was this.. first I tried to import…

Then he says to edit the config.php in my case since it was all default WordPress I figured, meh hopefully it’ll all match.. hahah so I skipped his Step 4, also skipped his step 5 cause I already did that, as I said the creation of the DBs happens at import, at least if they don’t already exist like the above error. In my case it just stated it for mysql, but not wordpress so I assumed the other 4 successful queries were for my wordpress data (hahah so many assumed mistakes).

So I uploaded those unedited web files back to the same dir on the new server….

and….

DOH! hahaha That’s why you don’t skip Tom’s Step 4, but in my case I had no interest in creating these as they should already exist, at least unless the WordPress image has changed that (in this case so lucky, they didn’t) so all I had to do was figure out how to set the wordpress users password on the new DB to match that which is in the config.php…. so I opened config.php grabbed the wordpress users password, and found out about this trick by James Goodwin… 😀

However, I was able to load my new WordPress site, but it was still the default one, not mine with my posts, themes, plugins… what the… which brought me back to my “failed” DB import….

When WordPress gives you attitude you drop em like their hot, drop em like their hot…. but in this case WordPress is hot is I won’t drop it, but I will drop those useless databases So, since this was all just a test server anyway, I went back into the Adminer on the new server and simple selected both MySQL, and wordpress and clicked the drop button.

Then back into import, selected the same export SQL file… and…

and sure enough my site loaded with all my content, all my plugins, all my posts, and no more PHP warning!

Summary

Now this covers the manual work to move WordPress, however much like what Tom covered, the final touches of how the site is accessed (direct NAT, behind load balancers, etc) are all on you in order to complete the migration for public access.

In my case I’ll probably prepare this new VM with the exact same Private IP information just on a separate vSwitch, once it’s verified working 100% shutdown the old VM, swap the vSwitch connection to production, test, if good, delete old VM, if not change vSwitch ports and bring up old server.

Worse case delete both VMs, restore my original server from my Veeam backups.

*NOTE* I did experience one issue were I was unable to update WordPress or plugins after the migration. Turns out many posts point to the File System permissions (which I suspected) I checked my old WordPress instance vs my new one and noticed all the files under the physical path had different owner and grp (root on new vs www-data on old) so…

chown -R www-data:www-data /path/to/wordpress

After that updates worked without issue.

Classic Editor

Ahhhh Yes!!!!! The Classic editor where life is easy!

CHeck this out!

Ohhhhh man! That took me 2 seconds! and it’s perfect!

Go Classic editor, simple and it works! Leave fancy editor stuff for plug-ins WordPress…. You’re bloating WordPress like MS bloated Windows…

At least Classic Editor will be supported till 2021, and my guess with how crappy the new editor seems, it’ll probably be supported longer. like XP, good things die hard. New shitty things die fast.

WordPress 5 and Blocks

Here I am, trying out WordPress 5+ and it’s new content editor.

Big Gaping Asshole… I mean spacer Block!!! OMG Now I can move My big Gaping Spacer Block using Arrows… OMG!!! AMAZING… meh

My old ways don’t work and it’s painful to do something that was super easy before.

I sound like like an old fart but I liked the old way, not that I don’t like the ingenuity and clearly the scaleabilty of the new way, but things were obviously missed…

for instance I used to be able to paste my imgur links and then using my old plug in options mark them clickable and pop out. Now if I paste it, it tatoos the living crap out of the image with imgur crap all over it….

God look at this garbage

But hey at least I can caption my shit and move them around, cause you know how often I screw up the order of my post when I make them….

This paragraph, I can, cause you know how people love to mess up there paragraphs and have to rearrange them all the time!

Now when I press enter it simply adds a new “Document” block, so If I wanted this paragraph after ^ That Paragraph.

If that was confusing trust me so is finding the Point of these “blocks” if I had maybe some horizontal control I could see some use, but it’s literally just vertical, up down that’s it… wooo, man it was so hard before selecting content with the mouse and using, keyboard shortcuts (Ctrl + X to cut, move to location, Ctrl+v to paste) in those times you needed to re-arrange… boy that stuff sure was hard to do. I’m glad I have blocks now to waste my life learning how to get something simple as my old pop up image plug-in to work again….. Pricks….

Time to install the Classic editor!

Splitting WordPress Titles
Post Headers

I wanted to do this since I noticed my one header being really long and was unsightly… I decided to google this, like I google everything…

First one I found, I didn’t want to dink with code, I like coding but mostly PowerShell (If you haven’t noticed based on my categories)… Sorry you’re out!

Second one I found, I didn’t like cause it used a plugin… However there’s always something great to learn form the comments, specially “pessimists” *Cough* realists such as this great comment by “KRZYSIEK DRÓŻDŻ”

“Wow, you really need a plugin for that?

Why don’t you just insert tag? Installing million plugins, that aren’t doing anything really isn’t a good idea… Especially, if such plugin is not popular, so very few people have looked at/controlled it’s code (this plugin had 30 active installs).”

Made me gooo, waaaaaa that’s it? So sure enough I add <br> in my Title, and Bam! The Title is split on 2 lines, now that was easy. Thanks Krzysiek!

Looks like my third source basically does the same thing.