Updated 27th September 2020 to consider restart of all services where restarting just apache isn’t enough, and also to share choice when it comes to import first vs SSL first as you may lose permalinks. Thanks to Peter and Simon in the comments.
Updated 25th January 2021 to add an initial paragraph clarifying that you can’t ‘choose’ a PHP version on Lightsail and to further clarify that you must first check which version of PHP a new AWS Lightsail instance will be built with to confirm it will resolve the message being displayed in WordPress.
Updated 11th May 2021 to confirm that snapshots cannot be used to update the PHP version of a Lightsail Bitnami instance.
NB: If you’re hoping for a way to click ‘update php’ or ‘use X version of PHP’ in Lightsail, it doesn’t (at time of writing) exist. This guidance will walk you though creating a new Lightsail instance with a newer version of PHP installed and moving everything over to it.
The AWS Lightsail service is great. Click a few buttons and you have a powerful VPS with WordPress up and running for only a few dollars a month. The Bitnami integration allows you to choose from a whole set of Stacks to include upon setup. The LAMP option allows a competent PHP developer to run almost anything on Lightsail.
But after a while running the Lightsail VPS the setup is going to get stale, and because Bitnami bundles everything up, it’s not recommended to go poking around with only a few parts of it.
That’s the challenge I was faced with. Logging into the WordPress admin console a message is displayed which is telling me WordPress would prefer a newer version of PHP please. My version was old and not receiving security updates.
I read a fair bit about my options, but after looking at the choices I decided the best thing was to do an export and import onto a new Lightsail instance.
It would be nice if all this was possible by taking a snapshot and using it as the basis for a new instance, but sadly that isn’t the case.
There are a few steps to this update which I’ll run through below, but they boil down to something like:
- Confirm the new Lightsail instances will be created with a PHP version high enough to resolve the WordPress message or the version of PHP you require for your own usage
- Confirm the existing instance has a static IP
- Create a new Lightsail Bitnami WordPress instance
- Install Let’s Encrypt ready for SSL creation later
- Export all wordpress data from the old instance
- Change the upload limits on the new instance
- Import all wordpress data to the new instance
- Switch the static IP over to put the site live on the new instance
- Install the new SSLS
- Set up a cron to renew SSLs automatically
Note: These steps were accurate at the time I wrote this guide. Your mileage may vary. Always back up everything before you start. I take no responsibility for you not checking my workings before you use it yourself.
Confirm a new Lightsail instance will be created with a high enough version of PHP
Before you get started, it’s worth you confirming that a new AWS Lightsail instance can be created with a PHP version high enough to resolve the message displayed in WordPress or a version suitable for your own needs. The Lightsail service doesn’t immediately start offering new PHP versions when they are made available, and so you may need to wait on the Lightsail PHP versions on offer being updated before you continue with this process.
Confirm the existing instance has a static IP
With Lightsail you have the choice of assigning a static IP to your instance. Static IP addresses are free as long as they are assigned to an instance.
With a static IP you can then point your domain’s A record to the IP address. This makes it much easier, and free from DNS updates—to move between Lightsail instances, as we’re about to do.
Click to manage your instance from the Lightsail dashboard then the networking tab then click the ‘create static IP’ button.
Create a New Lightsail Bitnami WordPress Instance
The only recommendations here are that the instance is large enough to hold the existing system. Unless you know better, match the new instance type to the old one.
It’s up to you, but look carefully for the ‘automated snapshot’ checkbox and enabled it if you want peace of mind at a small additional monthly cost.
Be sure to choose the WordPress Stack.
Install Let’s Encrypt ready for SSL creation later
Use the SSH connection link on the Lightsail dashboard to open an SSH terminal browser window for the new instance.
The rest of this guide assumes your new instance is using a self-contained installation. You can check yours is with the following command:
$ test ! -f "/opt/bitnami/common/bin/openssl" && echo "Using system packages." || echo "Self-contained installation."
Run the following commands, being careful to user the [TAB] key to auto complete the right file path where mentioned.
$ cd /tmp $ curl -Ls https://api.github.com/repos/xenolf/lego/releases/latest | grep browser_download_url | grep linux_amd64 | cut -d '"' -f 4 | wget -i - $ tar xf lego_[TAB to complete path] $ sudo mkdir -p /opt/bitnami/letsencrypt $ sudo mv lego /opt/bitnami/letsencrypt/lego
For now, that’s as far as we need to go with Let’s Encrypt.
Export all wordpress data from the old instance
- Log into your current live WordPress admin
- Install the free All-in-One WP Migration
- Once installed choose to Export, and select File
- Download the file to somewhere sensible on your local machine
- Make a note of the file size of the download
Change the upload limits on the new instance
If the file size of the download is larger than 40MB you’ll need to make a change to the new instances php.ini file to allow the upload for import to be successful. If it’s not 40MB you can skip to the next step
- Open an SSH browser window for the new instance using the link in the Lightsail dashboard (or jump back to the window you opened previously)
- Run the following command:
$ sudo nano /opt/bitnami/php/etc/php.ini
Now in this file you want to update both
upload_max_filesize to be larger then the export file you’ve got on your machine.
You can use
ctrl-w in nano editor to search for the two items above.
Then exit and save the php.ini file. You’ll then need to restart all services:
$ sudo /opt/bitnami/ctlscript.sh restart
Import all WordPress data to the new instance
Permalink warning: As Simon points out in the comments, if you import your data here before you point the domain to the new setup, you might find any permalinks will be set to use your IP address rather than your existing domain. It’s your call here. You could deal with a little more downtime and point the domain and sort the SSL certificate first.
Now we can import our existing WordPress data into the new instance. To do this we need to log into the new wordpress install as an admin, add the All-in-One WP Migration plugin as above, and choose Import => File
The access details for the new WordPress admin console are available from your SSH window again:
$ cat bitnami_credentials
The username is likely
user and you’ll find a password there too.
The address is just the IP address of the new instance shown on the Lightsale dashboard. Add
http:// before it and
/wp-admin after it to get something like
http://126.96.36.199/wp-admin and put it into the browser adress bar to view the login screen.
So to confirm you’ve:
- Logged in to the new wordpress instance as admin
- Installed the All-in-One WP Migration plugin
- Chosen Import, then chosen File and selected the export file from your computer to import it
Hopefully everything has gone well and you’ve got a success message.
You can check the site has your design and content by clicking the link in the top left of the WordPress admin dashboard
Switch the static IP over to put the site live on the new instance
Downtime warning. As soon as you move the IP over it will point to your new instance which doesn’t yet have an SSL certificate. It will be off for a couple of minutes if all goes well.
Use the networking option on Lightsail dashboard tabs. Click to manage the static IP. Choose to detach from current instance, then choose to add to the new instance.
Install the new SSLS
Command line commands to run. You may not want www domain coverage. Be sure you update the domain and email below.
Note you have to stop bitnami for this.
$ sudo /opt/bitnami/ctlscript.sh stop
Then we ask for the SSL to be created (see article comments below this post for a little more clarity about www vs no www ordering here)
sudo /opt/bitnami/letsencrypt/lego --tls --email="firstname.lastname@example.org" --domains="example.com" --domains="www.example.com" --path="/opt/bitnami/letsencrypt" run
Then we need to link the certificates up, just this first time you provision them.
Here we’ll move the default certs to backup (.old) locations and add references to the new ones. Then we tweak permissions:
$ sudo mv /opt/bitnami/apache2/conf/server.crt /opt/bitnami/apache2/conf/server.crt.old $ sudo mv /opt/bitnami/apache2/conf/server.key /opt/bitnami/apache2/conf/server.key.old $ sudo mv /opt/bitnami/apache2/conf/server.csr /opt/bitnami/apache2/conf/server.csr.old $ sudo ln -sf /opt/bitnami/letsencrypt/certificates/[YOUR_DOMAIN].key /opt/bitnami/apache2/conf/server.key $ sudo ln -sf /opt/bitnami/letsencrypt/certificates/[YOUR_DOMAIN].crt /opt/bitnami/apache2/conf/server.crt $ sudo chown root:root /opt/bitnami/apache2/conf/server* $ sudo chmod 600 /opt/bitnami/apache2/conf/server*
We can disabled the default Bitnami banner which will be showing over your site right now while we’re here:
$ sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1
Then let’s spin things up again:
$ sudo /opt/bitnami/ctlscript.sh restart
Add the cron
We want the SSL renewal to run regularly without having to manually go in and renew the SSL certificate. We can do that with a regular cron and bash script.
Create the bash file:
$ sudo nano /opt/bitnami/letsencrypt/scripts/renew-certificate.sh
Put the code we need in there:
#!/bin/bash sudo /opt/bitnami/ctlscript.sh stop apache sudo /opt/bitnami/letsencrypt/lego --tls --email="email@example.com" --domains="example.com" --domains="www.example.com" --path="/opt/bitnami/letsencrypt" renew --days 90 sudo /opt/bitnami/ctlscript.sh start apache
You’ll notice that the code above stops apache before it runs. So there will be less than a minute of downtime each time this runs. That’s why I would suggest once a month in the middle of the night.
Make the file executable:
$ sudo chmod +x /opt/bitnami/letsencrypt/scripts/renew-certificate.sh
Then add a line to the crontab to make it run regularly:
$ sudo crontab -e
Add this line to the bottom. First minute of the first hour of the first day of every month of every year.
0 0 1 * * /opt/bitnami/letsencrypt/scripts/renew-certificate.sh 2> /dev/null
If you updated it previously you may want to drop the php.ini max upload fields back down. See the section above for that. The default value is 40MB for both.
Now we’re using https urls for our instance, you could tweak the firewall settings to remove the http option.
You could do a backup of your previous instance and then remove it. You could also leave it up a while just in case and set a reminder to remove it later.
You may want to set a reminder in your own calendar to check the SSL has actually updated. Let’s Encrypt SSLs expire after 90 days, so that reminder should be set for a week or two before that expiry date. The simplest way to check expiry of an SSL is to go to the site in a browser and click the padlock icon. You should be able to click to view more information, including the expiry date. If it hasn’t updated on its own in the 80ish days since you created it manually, you may need to review the cron steps or look for guidance on it elsewhere.