Proxmox copy of WordPress virtual machine – changing the siteurl

I’ve gone into Proxmox and cloned a WordPress machine to a new machine. I configured DNS and DHCP to assign a new host name for the machine; now I need to get WordPress to understand that too.

Because WordPress stores the site URL inside the database, this means running a MySQL query.

The problem is that the old WordPress site (because that is what is in the new machine’s database) keeps telling Apache to serve up the pages from the old machine. So everything on the new machine will need to resolve at https://tratest.example.com but because WordPress is going to its database to find out where everything is, as soon as the page loads, it tries to go to https://aawp.example.com

That machine is powered off in Proxmox, so obviously nothing works.

Can’t really use any tools inside WordPress to do the search-and-replace, so I need something outside of WordPress. I generally do not install phpMyAdmin, because 1) it is extra work to configure Apache to serve up a different website just for this one function, and 2) that becomes just one more place a bored 14 year old might try to break in. If I don’t need it, why put it out there?

So let’s try some MySQL queries from the command line.

UPDATE wp_options SET option_value = replace(option_value, 'https://aawp.example.com', 'https://tratest.example.com') WHERE option_name = 'home' OR option_name = 'siteurl';

Nice! I did a restart of Apache, and now the new machine at the new domain name serves up the content from the cloned machine. I know that this worked because the old machine in Proxmox is still powered off.

There are also several other changes I made:

  • hostnamectl set-hostname tratest.example.com
  • edited /etc/hosts and copied the 127.0.1.1 entry to 127.0.2.1 and added the new host name, per Change host name and domain
  • edited the Apache .conf file in /etc/apache2/sites-available/ and replaced the ServerName entry

WordPress sucks, issue <whatevs>

Out of nowhere, every time I clicked on a Gutenberg block on a draft post (my Quarterly Inventory post) I’m getting “This block has encountered an error and cannot be previewed.”

The solution is (apparently) to disable every plugin – oh hey looky there: the error went away – and re-enable them one-by-one.

Yay.

I’d so rather being doing this than making progress on how to update a WordPress site URL after cloning in Proxmox. Not.

AND OF COURSE, NOTHING WAS WRONG

Grrr. I’ve now re-enabled every plugin, and Gutenberg is fine.

Apparently, the code base on WordPress is so good that one just needs to disable every plugin and re-enable them once in a while.

WordPress copy to test environment

I’m a fan of Tenets of IT

Number 15 of which is “Everyone has a test environment, not everyone is lucky enough to have a separate production environment.”

Heh.

This post will be how I copied a production web site to a test environment.

Prerequisites are:

  • A virtual machine server
  • A domain name
  • A wildcard certificate for that domain name

In my case, for the virtual machine server, I bought a used Lenovo Tiny PC from Amazon, loaded it up with RAM and installed Proxmox on it.

I had bought a domain name, really for my Nextcloud instance, but I can also use it for my home lab.

I have a firewall, which can get SSL certificates from the EFF project Let’s Encrypt, via the certbot / acme protocol. I went through the trouble to get a wildcard certificate, so that any box in my domain name can be SSL protected.

The basic steps

  1. Prepare the new machine
  2. Install WordPress
  3. Export WordPress “production” and import to “test”
  4. .
  5. .
  6. .
  7. Profit!

Prepare new machine

  1. Install Debian
  2. Add vim and other configurations
  3. Change host name and domain
  4. Add ssh key login
  5. Install Apache and MariaDB
  6. Install WordPress
  7. Update Apache enabled sites to include SSL
  8. Update Apache default Debian setting
  9. Install one WordPress plugin to import the export
  10. A note about ASE (Admin Site Enhancements)

Install Debian

This was a Proxmox step, and I think I did it from a .ISO file

Add vim and other configurations

apt-get install vim
update-alternatives --config editor
vim ~/.bash_profile
export EDITOR=vim
[ -r $HOME/.bashrc ] && source $HOME/.bashrc
export PS1='\[\e[32;40m\]\u\[\e[37m\]@\[\e[32m\]\H:\w\[\e[30m\] \[\e[32m\]\$\[\e[30m\] \[\e[0m\]'
vim ~/.bashrc

Find the aliases I want and add them, uncomment them, etc. I always add:

alias ..='cd ..'
vim /etc/inputrc

Find # "\e[5~": history-search-backward and uncomment it

Change host name and domain

I should mention that in my home firewall, it is also my local DNS resolver. So inside there, I have server1.example.com mapped to the IP address Proxmox gave to my new virtual machine (Proxmox got it from my DHCP server).

hostnamectl set-hostname server1.example.com
vim /etc/hosts

In here, I added an entry for 127.0.1.1 which maps the fully qualified host and domain name to the host. So for example, 127.0.1.1 server1.example.com server1

The address 127.0.1.1 is specified because Apache will try to identify the site by name (later). Everything in the 127.x.x.x maps to the local machine, so they all go to the same place. But having it as 127.0.1.1 stops a duplication conflict with 127.0.0.1 for localhost

Add ssh key login

ssh-copy-id root@server1.example.com

Never, in production, would I be commonly logging in as root. But this is a test / play environment, and I find the process cumbersome to set up an alternative user, and then have to be constantly doing a su - (switch user) to root. Since this is in my home lab and not visible on the public Internet, this is not so much a risk. And … before I really try anything screwy, I can take a Proxmox snapshot.

Another thing I run into, is that because I can rip and replace virtual machines easily, I tend to have to delete old entries from the ./ssh/known_hosts file.

ssh-keygen -R "server1"

Install Apache and MariaDB

Essentially, I am following the instructions here at Rose Hosting

One change I make is that immediately after installing MySQL, I run the process to secure the MySQL installation:

mysql_secure_installation

Yes, I set the switch to unix_socket authentication. I have zero need for MySQL to authenticate across a network. This is overkill for a home lab, but since this is how production is going to be set, the machine in test should match it.

Install WordPress

I still follow the instructions at Rose Hosting

Update Apache enabled sites to include SSL

The Rose Hosting instructions don’t disable the 000-default.conf web site

a2dissite 000-default.conf

Now, how to make https:// work? Well, there is already a default-ssl.conf file, so all it really needs is a certificate and key, and for Apache to use SSL. The SSL certificate files mentioned there are /etc/ssl/certs/ssl-cert-snakeoil.pem and /etc/ssl/private/ssl-cert-snakeoil.key

I have exported my wild card certificate and key to my local machine, so now I upload them to those directories, and change the names in the default-ssl.conf file.

Update the ServerName setting in default-ssl.conf to server1.example.com

Update the DocumentRoot setting in default-ssl.conf to /var/www/html/wordpress

Add rewrite rules to the non-SSL site to redirect to the SSL site. In wordpress.conf add:

RewriteEngine On
RewriteCond %{REQUEST_URI} !.well-known/acme-challenge
RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L]
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
apachectl -t

If this checks out well, that’s nice, but there is still one more thing to add:

a2enmod ssl

Update Apache default Debian setting

This one threw me for a loop – all my redirects were going to 404 error pages.

It turns out that the default setting on Debian has an Apache configuration file with rewrites not allowed.

vim /etc/apache2/apache2.conf

Find my way to the <Directory /var/www/> section. Change the AllowOveride setting from None to All.

The /var/www directory is of course higher up in the directory structure of what Apache is going to serve up. Because it is higher, the AllowOveride None directive overrides the lower level allow all. Whoops – for WordPress this is no bueno.

Finally, restart (not reload) Apache:

systemctl restart apache2

Install one WordPress plugin to import the export

For this, I am following the instructions by Ferdy Korpershoek on this YouTube video

(The YouTube front page has become politicized trash, but for technical videos, it still has good stuff one can find).

Essentially, I install the All-in-One WP Migration plugin on the production web site, do an export, and then install a fixed version of the All-in-One WP Migration plugin on the test web site.

Ferdy does clean up the new / fresh web site first, by deleting and emptying the default pages and posts. I also deleted the default plugins.

After the import is done, I need to log in again, because the database was replaced, which is where my login credentials are stored. After getting logged in, I need to save Permalinks twice.

A note about ASE (Admin and Site Enhancements)

I was almost at hooray! But, I have a small security enhancement via Admin and Site Enhancements (ASE) which threw a tiny wrench in the monkeyworks. Yes, in production, I’ve hidden the login URL to somewhere other than normal. So after the import, All-in-One WP Migration (100 GB version) provides a link to update the Permalinks, but because of ASE, that URL was not found. No biggie, I simply had to use the URL that was appropriate for the production web site.

Profit!

And now I get to bask in the glory of messing the heck out of the test (not production!) WordPress web site. Fun times. 🙂

I think I’ll take a Proxmox snapshot first.

Updating to WordPress 6.6 was a mistake

Automattic (I presume) added a JavaScript framework to WordPress 6.6, which increased the amount of RAM the server uses. On a small machine, the RAM increase is massive: almost doubling the amount of RAM used.

Nicely, the downgrade of WordPress to version 6.5.5 was easy enough; but, this now leaves a huge question mark for the future. At some point, either my server goes out of date and becomes vulnerable to new-found security flaws, or, I have to start shelling out an additional $84 per year for their new fanciness.

It would be nice if they put a radio button in the administration page to enable or disable the new React JSX stuff.

WordPress Gutenberg is getting worse

A lot of this blog are my entries to help myself with some task. I like to copy / paste commands that I don’t want to memorize. If those commands help someone else trying to do the same task, that’s wonderful.

Copy / past has been a bit of a chore on WordPress, however. I’ve tried three different plugins. The first one worked for a while, but then broke. It was based on WordPress shortcodes. I don’t recall if it was WordPress that upgraded and broke the plugin, or if it was the plugin that upgraded and broke. Whatever: the shortcode stopped working.

The second plugin worked at least once, but then broke after an update of some sort. It was supposed to work either by specifying a shortcode or text formatting. I’m pretty sure the text formatting was supposed to be for “inline code”. When the plugin saw that the text was marked up that way, it added the copy-to-clipboard function. It was pretty frustrating to go back and edit some old posts and less than a month later, those posts are trashed up without providing copy-to-clipboard access.

This third plugin, Copy Code To Clipboard works well, and it is based on the /preformatted text attribute.

I don’t recall if this is the way it always was, but: it appears that this only works with whole blocks now. You can have inline code or keyboard input within a paragraph, but you cannot have /preformatted within your paragraph.

But, the /preformatted block type is just implementing the HTML tags <pre> and </pre>

So, I can edit in HTML mode and insert it that way, right?

Where WordPress has made things worse, is that now, <pre> and </pre> implement a forced <br></br> immediately before <pre> and immediately following </pre>

And it doesn’t put those codes in the HTML. It just sneaks them in there and taunts me with the extra lines before and after every piece of text I want copy-to-clipboard for.

Thanks, WordPress developers: I hate it. You’ve made the world a worse place.

And another thing ….

This showed up many months ago, shortly after Gutenberg became official: Ctrl-K for creating an anchor (link) used to be great. On another web site I maintain, we have an old kludgy events calendar plugin, and it still works great there. That events calendar plugin does not use Gutenberg.

All I want for Ctrl-K is to highlight the text to form a link, hit Ctrl-K to start the anchor creation, hit Ctrl-V to paste in the URL, and hit <Enter> to finish the anchor.

Guess what no longer works in Gutenberg? Hitting <Enter> to finish the anchor.

I am always so very overjoyed when I have to finish an operation by grabbing my mouse and finding the stupid little button to click to indicate that I want to finish creating the anchor. I’m editing an anchor: there’s really not that much more that I can do here.

Like what the heck was the <Enter> key supposed to otherwise signal?

In the current Gutenberg, it is simply a no-op. Useless. A waste of a keystroke. Until I find the stupid mouse cursor and click on the stupid little submit button, the anchor is incomplete. All editing has come to a stop, until I do some freaking mouse work.

Thanks, WordPress developers: I hate it. You’ve made the world a worse place, again.

WordPress migration notes, part 2

One problem is that I need to install WP-CLI on the new server, and dealing with it is not easy.

The installation instructions don’t say one way or another, but WP-CLI should not be installed as root. Later, if you go to run it as root, it will bark at you that you’re doing a bad thing. Okay, nice to know.

But we do now have the problem that the user who runs WordPress (well, Apache, which runs the PHP code that is WordPress) is the www-data user. I cannot log in as the www-data user, by design (it is a good design). So, how to run this WP-CLI stuff?

sudo -u www-data wp <command>

Okay, this says to switch to user www-data (sudo = switch user and do) (the -u option specifies which user, in this case www-data), and run the wp binary and any command line options you want it (wp) to do.

Cool, but the user I’m logged in as has no idea of where the WordPress installation is. So now, every freaking command I have to type, sudo -u www-data wp <command>, also needs --path=/var/www/html/wordpress in there too.

This sucks.

There is supposed to be a file, wp-cli.local.yml, that I can put the path into. But that file is in my directory, and the sudo command switches away from that.

This sucks, still.

The www-data user does have a home directory; but, it won’t ever be used because the account runs /usr/sbin/nologin on every access. That is secure, but it doesn’t help me from having to type sudo -u www-data wp --path=/var/www/html/wordpress<command> every freaking time I need to do something.

Also, I am a fan of using the page-up key to search my bash history. That works great when I type a few letters, say gre and hit PgUp to search through my last few grep commands. Do I need to reassign ownership of files I’ve added to /var/www/html/wordpress/ ? chow and PgUp, and in a keystroke or two, I’ve got chown -R www-data:www-data /var/www/html/wordpress/ ready to run. Ditto the Apache2 enable and disable site commands. There are a ton of examples where just a few keystrokes and the PgUp key are great.

But having to type su and hitting PgUp presents me with a wall of noise, to finally find the command at the end that I actually want to repeat.

This sucks.

So, there is a solution. It seems kludgy, but it works, as long as you are willing to put up with its kludginess.

  1. cd to /var/www/html/wordpress/
  2. create a file, wp-cli.local.yml, in the location where WordPress is installed (where you just did the cd to), and inside it, put:
    • path: /var/www/html/wordpress

So, as long as you are already in the “right” place, and you have this file which points to your “right place”, you don’t have to specify the “right place” on the command-line of WP-CLI.

The other option is to be in my home directory, and do everything via bash scripts. I wanted to use the command-line, but I may need to put one more level of indirection in the process to get things to work easily. Like I said: kludge.

However, since the bash script has WPPATH="/var/www/html/wordpress" in it, all that sudo -u www-data nonsense goes away. Sure, I’m running it as some random user from some random location, but (I assume) that the WP-CLI people are just fine with that because if a random hacker gets into an ssh session on my box, I’m done for, anyway. Why not just assume whoever is running these commands is authorized?

This sucks quite a bit less, although it doesn’t make me warm and fuzzy about security.

WordPress migration notes

I have a production WordPress site on Amazon Lightsail that I need to migrate away from. These are notes on how to migrate over only the stuff I want to keep.

Backstory: Amazon Lightsail was very inexpensive, at under $5 per month for hosting on their smallest machine, and it did fine. Two things became problems, however:

  • Bitnami WordPress is super easy to spin up, and everything just works. But upgrading to a newer version of something (say PHP or MySQL or something) is a non-starter. The only way to upgrade is to spin up a new machine and do a migration to a new machine.
  • Amazon recently did a price increase. Now, I can get a Linode machine with double the RAM for only $2 more, and that will include backups.

Okay, so I need to migrate, but over the years, I’ve tried different plugins, and even though many of them were uninstalled, the installation routine left crap in the database. How to migrate to a new server, but leave behind the crap? This will be the topic of this post.

First, I installed WP-CLI, instructions can be found here.

Then, on the new machine, I installed only those Plugins which I know I need.

I took a snapshot backup at this point, simply because it seems prudent.

On the new machine, I logged in with ssh and ran this:

wp --path='/var/www/html/wordpress' db query "SHOW TABLES" --skip-column-names --allow-root

This gives me a list of the tables in the new machine that I want from the old machine.

+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+

This is a pretty minimal list; the old machine has a list 362 tables long! Matomo was a particularly egregious offender here.

With this information, I can use a script written by Mike Andreasen over on the WP Bullet website to dump the databases on the old machine:

# set WP-CLI flags
WPFLAGS="--allow-root"

# define path to the database dumps without trailing slash
DBSTORE="/tmp"
# get the name of the database
DBNAME=$(wp config get DB_NAME ${WPFLAGS})

# list all of the tables regardless of database prefix
TABLELIST=(wp_posts wp_postmeta)

# create the temporary directory for storing the dumps
mkdir -p ${DBSTORE}/${DBNAME}

# loop through tables and export, log details to /tmp/mysqlexport-<database>.txt
for TABLE in ${TABLELIST[@]}
do
    # export the table
    wp db export ${DBSTORE}/${DBNAME}/${TABLE}.sql --tables=${TABLE} ${WPFLAGS} | tee /dev/stderr
done > /tmp/mysqlexport-${DBNAME}.txt

With this done, I scp the files from the old machine to my local machine. Then I scp them up to the new machine. The next script assumes they are in the sql directory in the wordpress folder.

I tried it, but I should have taken a snapshot, first. 😉

I need to search-and-replace all instances of the old domain name in the MySQL dump files, and put in the new domain name. Technically, once the actual switch happens, the new machine will be found at the old name, so this shouldn’t be necessary. But, the whole reason for migrating to a development machine is to test out this migration process. And the new machine does have a different domain name.

The script to upload the MySQL dumps looks like this:

# define WordPress path
WPPATH="/var/www/html/wordpress"

# loop through all of the 
for DUMP in /var/www/html/wordpress/sql/*.sql;
do
    wp db import ${DUMP} --allow-root --path=${WPPATH}
done

But, until the data is cleaned up, the new WordPress website gets the dreaded white-screen-of-death.

WordPress media upload in wrong folder

This one is a little weird. I had inherited a web site; I do some volunteer service, and the original web site was done in FrontPage 98. People who used the web site knew the URL to a particular file on that web site: the meetings directory.

Later, a member showed me an app that was super useful; but the best way to implement it was as a WordPress plugin. I guess I’m learning WordPress now (not that I was a fan of FrontPage 98: good riddance).

After the conversion, the members that knew the URL to the meeting directory complained that their bookmarks were broken. Fair enough, I had broken them. I got a redirector plugin, and created a 301 redirect from the known URL to the new location.

But there was a problem with the new location: my default WordPress URL scheme for the uploads folder includes putting year and month in the URL. So an upload today would be in ./uploads/2023/04/

What’s going to happen next month, when there is a new meetings directory file? It isn’t going in the April folder, I can assure you. Am I going to have to update the redirect every single month?

I’ve been doing computers for 40 years. Having to update the redirect every single month is stupid. Why can’t I just move the file to the root of the uploads directory?

Well … turns out WordPress needs to have a database entry for every file. I can move the file, but that orphans that entry in the database.

Even if I do move it, how does the old office manager update it? A regular old Media Library upload will upload the new file to a dated folder, and now we’ve got two files with the same name but different locations and URLs.

I had to find a plugin that does media file replace (in-place), but that wasn’t too hard. I use Enable Media Replace by ShortPixel. It was pretty easy to train the old office manager to follow the steps: click on the file in the Media Library, find the Replace button, and follow the directions on screen.

That was six years ago. This morning, the new office manager deleted the file. She had the presence of mind to recognize that something was wrong; but not enough to halt before doing damage. The new meeting directory file now has the wrong name and the wrong URL.

I kind of hate WordPress for the permissions trouble. What looked to be simple with the WordPress CLI (command line interface), wp media import did not work. ./wordpress/bin/wp would only ever get Permission denied. I should probably mention that the “user” I’m logged in as is not the same user as who runs the web site and has access to all the files.

Here are the steps I had to take to repair the damage. I got to figure them out; hopefully you will find them useful. And if the file gets damaged again, I’ll have these instructions for a quick repair.

  1. ssh into the server and find the uploaded file. In this case it will be in ./uploads/2023/04/
  2. rename the file to the old file name.
  3. move the file from ./wordpress/htdocs/wp-content/uploads/2023/04/ to ./wordpress/htdocs/wp-content/uploads/
  4. Delete the file in the WordPress Media Library (web page). WordPress will still show you the file, because it isn’t looking at the file, it’s looking at it’s database entries about the file. It looks like the file is there, but it’s a phantom. Delete it.
  5. Back to the server command line prompt: change the file system permisssions to be way too permisive.
  6. ./wordpress/bin/wp media import ./wordpress/htdocs/wp-content/uploads/file.pdf --path=./wordpress/htdocs/ --skip-copy
  7. change the file system permisssions back. ASAP.
  8. When you look at the WordPress Media Library (web page), you will see your file again – but this time it has a non-time-stamped URL. Huzzah! Paste that link into whatever page needs to serve it up. In my case, since I moved the new file to where the old file was, the links were still good.

How to give way too many permissions (this is terrible):

sudo chmod -R 777 /path/to/folder/wordpress

How to fix the permissions:

find ./wordpress -type d -print0 | sudo xargs -0 chmod 755

find ./wordpress -type f -print0 | sudo xargs -0 chmod 644

The Helm migration is complete

As I mentioned before, The Helm email appliance company is calling it quits, which I understand. If the business isn’t going to make it, it is better to pull the plug than just keep letting things linger. Best of luck to them on their next adventure.

So, what did I do?

  • (there was a detour while Amazon pissed on their customers wanting to run Mail-In-A-Box) (me)
  • I provisioned the smallest Ubuntu 22.04 LTS machine that Linode has.
    • Mildly annoyed that it doesn’t really support LVM (Logical Volume Manager); they have a backup service that runs an agent inside their machines, and that agent doesn’t do LVM. Still, I know that I’m going to need to grow disks, so I had to learn how to re-partition the Linode so I could do LVM. LVM done.
  • I made a mail server on the Linode machine at a domain name I have that I don’t really use. I followed the excellent guide from Christoph Haas at workaround.org: ISPmail guide for Debian 11 “Bullseye”
  • I got RoundCube webmail working for the domain name; complete with SPF and DKIM.
  • I got Thunderbird to send and receive from the domain name.
  • Then I added Nextcloud to the same box. I wanted CalDav for contacts and calendar, when I eventually hook my iPhone to it.
    • The Nextcloud documentation really needs a lot of work here. If I were retired, I would like to help them with their documentation.
    • Finally, I have the files.example.tld function of The Helm replaced, although at a different domain name.
    • Rspamd uses Redis, but so does Nextcloud. But one uses the network stack, and the other, Unix sockets. Get them both set same.
  • Then I added Duplicati backup. This wasn’t great, as it added a ton of overhead in the form of Mono, just for a graphical user interface.
  • I realize that I’m going to want to host my WordPress here too. I don’t want to have to wrangle four Let’s Encrypt SSL certificates, one for each domain. What about a single wildcard SSL certificate?
    • Yes, that can be done, but: my domain names registrar doesn’t support it. Linode does, though. I install the Linode DNS agent on my machine, and spin up Linode DNS servers to do the DNS work. I have to configure my domain names registrar to tell the rest of the world that Linode is where my name servers are.
    • Somewhere in there I installed the Unbounded DNS resolver. Looks like I need this on my home machine, too, for Home Assistant.io1
  • I got to the point where I could request the domain name transfer. Turns out the people at The Helm were going through Ghandi.net. Ghandi.net tooks as long as they legally could, before actually doing the DNS transfer.
    • Ghandi –> registrar, then registrar to point to Linode. Linode DNS needs to be reconfigured for SPF and DKIM. I had gotten some DNS records wrong, too.
  • Thunderbird to connect to the mail.domain.tld, and though the name hasn’t changed, everything underneath has. Thunderbird is not happy; I lose all my old mail.
    • Well, I didn’t, but it is in a new folder now, so that I’ve got an old version of my mailbox and a new version of my mailbox, and they are separate. Not ideal. Perhaps I could have done an IMAP to IMAP transfer, if I hadn’t already moved the domain name.
  • Hey, looky there: one of the volumes filled up (but everything else was unaffected). Time to grow a disk using LVM.
  • iPhone to connect to CalDAV; phew that was not well documented and had tons of conflicting information.
  • Not really happy with Duplicati, so I remove it and Mono, and install Restic backup instead.
  • Okay, so the last thing left to do is to migrate this blog from Amazon to this new Linode machine. The transfer using NS Cloner goes well, as it usually does. But domain names need to be updated via Let’s Encrypt certbot.
    • Crud. I’m on holiday out of town with family, and have only a Windows laptop with me. Per best practice security protocols, I can only ssh in from home. Logging in via root@ is blocked, and I don’t think I can even do a ssh-copy-id without getting in first and lowering the root login barrier. The certbot to add gerisch.org to the domains list is going to have to wait.
  • Here I am, at home, and I’m done. Dovecot, Postfix, RoundCube, Nextcloud, and WordPress all on one box.
  • While I was on holiday, I took the .mp3 files on the Nextcloud, and made Nextcloud Music Player playlists for the different types of files. Then on the 16 hour drive home, my iPhone logged in to the Nextcloud web interface and played playlists.
    • It’s a bit of nirvana to me, to have a large list of songs (randomized of course) playing absolutely advertising-free because I paid for the songs in the first place.
  1. I ended up not connecting Home Assistant to their cloud ↩︎

WordPress initial install error: “Cannot select database”

The full error is

Cannot select database

The database server could be connected to (which means your username and password is okay) but the database could not be selected.

What is actually wrong is that you don’t have a file wp-config.php

From what I gather, it used to be that wget http://wordpress.org/latest.tar.gz would bring in a .tar.gz file which contained wp-config.php. That file isn’t there any more in the source.

In the old scheme, the installer would modify it with the user name, password, database table name and then proceed with the rest of the installation.

If I had to guess, I’d guess the new scheme is supposed to do cp wp-config-sample.php wp-config.php and then the installation picks up as it did before (modifying it with the user name, password, database table name); then proceeding with the rest of the installation.

Someone got the idea that instead of maintaining two wp-config files, they could maintain and ship one, and then copy it during install. This is a good idea: makes the source a tiny bit smaller, saving storage and transfer bytes. Just one thing though: do the copy, stupid, and check your results. Err out in a rather ugly mess if you didn’t get the copy right – then at least you’d hear about it mightily if you got it wrong.

The solution is to manually copy the file, edit it with the user name, password, and database table name, and then try to install again, twice.

If you simply copy wp-config-sample.php to wp-config.php and then run the install, it’s going to bark at you that wp-config.php already exists. Also, it is not going to ask you for the user name, password, and database table name. Since you already had to fuck around with the wp-config.php file, surely you already took care of the user name, password, and database table name.

So,

  1. start the install from scratch
  2. copy the file wp-config-sample.php to wp-config.php
  3. edit the new file, supplying database table name, user name, and password
  4. start the install from scratch again and let it bark at you that the new file already exists
  5. click the try again link.

Finally the “famous five minute install” is done after you spent thirty minutes in frustration finding this post and not doing what the documentation says.

Personally, I think it is low quality programming to leave this bug in the basic install process. It’s been there for months. So, what? No-one at Automattic tests the installer any more?