Updating PHP on an AWS Lightsail WordPress Stack

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.

Updated 22nd September 2022 to add a link to a guide to check which PHP version you’ll get if you spin up a new Lightsail WordPress instance. Also added a note about WordPress supported PHP versions.

Updated 7th September 2023 to add a mention of the option to use Bitnami’s bncert tool to create an SSL certificate


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
  • Consider WordPress php support
  • 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.

Consider if WordPress supports the PHP version you’ll be moving to

WordPress doesn’t always support the latest version of PHP. There is a weird edgecase here where Bitnami Wordress on a Lightsail instance might actually use a PHP version which is only in beta support by WordPress.

You can check against the supported version list WordPress maintain.

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

Before you get started: You may want to consider using Bitnami’s bncert tool to create an SSL certificate rather than the steps below.

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 the default for lightsail (currently 80MB, previously 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 smaller than the default 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 post_max_size and 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://12.34.56.78/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="email@example.com" --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

Tidying up

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.

23 Replies to “Updating PHP on an AWS Lightsail WordPress Stack”

  1. I googled without any noticeable results until I’ve found your post.
    Thanks for sharing it. I’ll try it shortly on my site.
    Creating a new instance to only update PHP is really crazy but I understand from how you describe the whole process that it is the right thing.

  2. Just done my upgrade. It worked except that I need to execute this command

    sudo /opt/bitnami/ctlscript.sh restart
    instead of

    sudo /opt/bitnami/ctlscript.sh restart apache

    Thank you

  3. I had to import my new site *after* I pointed the domain to it.

    If I tried importing at the IP, then switching to the domain, half the permalinks would break.

  4. If you want to issue the certificate using a wildcard domain (for example “*.example.com”), you should add “–dns=manual” to the issue command, and it will ask you to add a TXT record to your DNS.

    Trying to issue the certificate for a wildcard domain without DNS checking will end up in an “acme: Could not determine solvers” error

  5. Awesome post! Its just what I needed for my migration. I used it for migration of 2 Lightsail servers and worked as a charm including SSL certificates with CloudFlare’s interaction in between.

    Keep it up!

  6. Hi, I must be fundamentally misunderstanding something here, but this post is called Updating PHP on an AWS Lightsail WordPress Stack, yet there do not appear to be any instructions for upating PHP. Everything is about SSL.

    I understand that you must deploy a new server stack to get the latest version, but I’ve gone into Lightsail a number of times and deployed new instances, and I am never given the option to select which version of PHP I get.

    My last attempt at doing this got me to PHP 7.3.18, when the most current is 7.4.12. I would be happy with any 7.4 version, but I don’t see how that is done.

    What am I missing? Thanks!

  7. Hey Mike,
    Your PHP version choices are limited to those offered when you select your lightsail setup. This article wasn’t intended to be about ‘Select a different version of PHP for your lightsail instance’.

    I mention in the article ‘and because Bitnami bundles everything up, it’s not recommended to go poking around with only a few parts of it.’ which based on your comment I will now make more clear, but was intended to confirm that you don’t actually update PHP on the existing setup, and instead transfer everything over to a new one.

    So right now if you want to use the lightsail WordPress bitnami stack, it looks like you’re currently only going to have a choice of PHP 7.3.18.

  8. Harry – just to follow up on the above comment, there’s still a very important aspect that is unclear in your post.

    You state that.. “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.”

    Unfortunately, nothing in your post resolves this issue. After you’ve followed the entire sequence, you will still be getting the prominent security warning that your PHP version is out of date and must be upgraded, because Lightsail haven’t made it available yet.

    They’re fantastics instructions and I’m sure I’ll use them in the future. But for now, everyone should really *avoid* doing anything mentioned in this post – otherwise you’ll find that it hasn’t helped at all and you’re going to have to spend all that time doing the same thing again later. Unless there’s another solution, all we can do is wait and hope..

  9. Hi Stephen,

    The article was intended to be more generally about updating PHP than dealing with a specific message showing in WordPress admin. I shouldn’t have made that a thing, but the ship has sailed and here we are.

    I’ve updated the article to clarify to those who don’t notice the PHP version when creating the Lightsail instance or don’t think to compare it to the message displayed in WordPress admin before progressing down the update path.

    Hopefully it’s now clear enough that nobody follows the guidance only to find they have the last minor, or even patch of PHP.

  10. Harry,

    Great write up its a life saver, I Just have a quick question to clarify the SSL cert.

    Does these steps assume that you already have a lets encrypt ssl cert in place in your old instance?

    Say if my provider is through AWS or cloudflare, do these steps apply?

    Sorry for the Noob questions I would really like to minimize the downtime on my site, ive already completed all the steps up until changing the domain over.

    Kindest regards
    Josh

  11. Hi Josh,

    No, the new instance isn’t aware of the old instance, and Let’s Encrypt also doesn’t care.
    The steps here essentially start from scratch with SSL certificates.

  12. Harry,

    Thank you so much!

    I have my old instance on EC2 and currently have a elastic IP assigned to it, I have done a little research and found that I cannot apply elastic Ip addresses to the Lightsail Instances. So im guessing I will just have to change the DNS records to point to the Static IP of the Lightsail Instance and wait for changes to propagate (forever).?

    Anyways I thought it might be a handy bit of info for anyone who is in the same situation as me.

    Thanks again for your reply!

    Josh

  13. Harry,

    Thank you for the post. I am receiving this error. Any suggestions:

    bitnami@ip-172-26-6-43:~$ sudo chown root:root /opt/bitnami/apache2/conf/server*
    chown: cannot dereference ‘/opt/bitnami/apache2/conf/server.crt’: No such file or directory
    chown: cannot dereference ‘/opt/bitnami/apache2/conf/server.key’: No such file or directory

  14. Hi, if anyone else gets a ‘cannot dereference’ error like the one John got, it’s probably because the symlink was not set up properly — letsencrypt saves certificates without the www. before the domain name, so if the symlink is set up like:

    sudo ln -sf /opt/bitnami/letsencrypt/certificates/www.[DOMAIN_NAME].key /opt/bitnami/apache2/conf/server.key

    That will cause a ‘cannot dereference’ error, since that file does not exist. The letsencrypt folder is owned by root, so tab complete doesn’t work for verifying the file exists. I would recommend double checking the certificate filename by running

    sudo ls /opt/bitnami/letsencrypt/certificates/

    Before setting up the symlink.

  15. Regarding Simon’s comment about the issue of broken permalink, I have also experienced the same problem.
    The All-in-One WP Migration has changed our permalink to the new server’s IP address. I have fixed it with a WP database plugin. Just search and replace the link

  16. David, If you’re following the guide, and using the WordPress Bitnami setup, you’re importing (via All in One WP Migration) into a db that is already in the config of the WordPress install.

  17. Thanks a lot for this excellent set of instructions Harry, it was 100% what I needed as I had not done anything with my AWS Lightsail WordPress instance since it was created 3/4 years ago.

    For information the only changes I made, was to use Bitnami’s bncert tool to create my SSL certificate

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.