This guide requires the following tools and accounts:
- AWS Lightsail
- Cloudflare – Setup a free Cloudflare account on their website or be ready to add a new domain to your existing account.
- Duplicator Pro – Hands down the easiest way to perform a WordPress migration. Worth the price for migrations and backups.
- FileZilla – This is the free FTP client we use in our Mac environment.
The following how-to will migrate your site to Lightsail using the Bitnami WordPress instance. As time allows, I’ll update with more screenshots, but for now this will be mostly step by step.
Table of Contents
-
- Prepare your site for migration
- Create a WordPress Instance
- Setup FileZilla
- Login to the Lightsail terminal via SSH
- Setup the initial Cloudflare DNS and HTTPS settings
- Setup a free SSL certificate
- Deploy the Duplicator Pro package
- Adjust additional server settings
- Configure the Cloudflare firewall
- Configure the Lightsail firewall
- Complete the final checklist
1. Prepare your site for migration using Duplicator Pro
If you already have a Duplicator Pro package ready to go, download it and have it ready for upload. If you haven’t already installed Duplicator Pro, purchase a license, install the plugin file, and follow the steps listed on this page to build a package of your current site.
2. Create a WordPress Instance on AWS Lightsail
Browse to the AWS Lightsail Home Page.
- Click Create Instance.
- Setup the new instance:
- Instance location: Lightsail should auto detect what region is best for you. You want to pick the region closest to the target audience of your website.
- Select a platform: For this guide, choose Linux/Unix.
- Select a blueprint: Choose Apps + OS, and then WordPress.
- NOTE: You can upgrade an instance easily later, but you can’t downgrade it. The $3.50 option is pretty fast, but the burst limits and 512mb memory option can be outgrown quickly.
- Identify your instance: I use a naming convention like WP-mysitedomain.com when naming instances and IPs. Helps to keep it all organized later.
- Click Create Instance. It takes a few minutes, but your new site instance will be ready soon.
Now that the Instance is created, it’s time to setup a Static IP address.
- Back at the Lightsail home page, click Networking.
- Click Create Static IP.
- Static IP location: Choose the same region as the Instance location above.
- Attach to an instance: Choose the instance you just created from the drop-down list. (It’s important you do this during this step. AWS does not charge you for a Static IP unless it’s just sitting there and not tied to an instance.)
- Identify your static IP: Use the same naming convention as above. For my sites, I’d type IP-mysitedomain.com.
- Click Create.
The instance has been created and provisioned with your Static IP address. Now we need to setup the FTP client.
3. Setup FileZilla to connect to the instance via SFTP
Click the blue heading on your new Instance to open its settings page.
- Under “Use your own SSH client”, click to download the default key.
- Launch FileZilla.
- Click File > Site Manager.
- Click New site.
- Enter a name for the new site. I continue with something like AWS – mysitedomain.com to keep it organized.
- In the right pane, enter/choose the following:
- Protocol: SFTP.
- Host: Enter the static IP you created earlier.
- Logon Type: Key file
- User: bitnami
- Key file: Click Browse, and find the key you downloaded.
- Click Connect.
The FTP client is now setup and ready to upload files. We’ll have to change a few things on the AWS Instance before we upload. Time to open up an SSH window.
4. Login to the Lightsail terminal via SSH and perform some move-in housekeeping
Click the orange icon that looks like a terminal window to open a browser SSH console.
A new SSH window similar to the one below will appear (the private browsing note at the top will show only if you were in an original private browsing window):
Allow dynamic alterations to .htaccess:
- Edit wordpress-https-vhost.conf:
sudo nano /opt/bitnami/apache/conf/vhosts/wordpress-https-vhost.conf
The Linux nano editor will appear on screen. Browse through the list until you see the entry <Directory “/opt/bitnami/wordpress”>.
- Find “AllowOverride none” and change it to “AllowOverride All“.
- After making the changes, Press Control + O to write the changes. Press enter.
- Press Control + X to exit Nano.
- Do the same for wordpress-vhost.conf:
sudo nano /opt/bitnami/apache/conf/vhosts/wordpress-vhost.conf
- Restart Apache: sudo /opt/bitnami/ctlscript.sh restart apache
NOTE: The above change allows WordPress to use local .htaccess files, however, Bitnami still requires cumbersome manual entries of .htaccess info into the file found at
/opt/bitnami/apache/conf/vhosts/htaccess/wordpress-htaccess.conf.
According to Bitnami, all .htaccess files needed require a special entry in this above file for every directory that contains an .htaccess file.
(This is supposed to be easy, I know! Need help? Check out our Personalized VPS Hosting!)
Delete symbolic links to wp-config.php and wp-content:
- Browse to the bitnami WordPress directory: cd /opt/bitnami/wordpress
- Remove all folders in the directory: sudo rm -r */
- An error will state that wp-content cannot be deleted. Remove it: sudo rm wp-content
- Connect to the SFTP server in FileZilla.
- In the right pane, browse to /opt/bitnami/wordpress/.
- Download a copy of wp-config.php to your local computer.
- Back in the SSH window, delete wp-config.php: sudo rm /opt/bitnami/wordpress/wp-config.php
- Back in FileZilla, re-upload the backed up wp-config.php to the /opt/bitnami/wordpress/ directory.
- NOTE: These steps may seem strange, but you are actually deleting a symbolic link to wp-config.php that is stored elsewhere. Re-uploading moves wp-config.php back to the standard WordPress location. Duplicator Pro will eventually read this file, detect the database settings prior to removal, and then overwrite it with an updated copy.
Now we’ll switch to Cloudflare and setup/adjust the DNS records to point to Lightsail.
5. Setup the initial Cloudflare DNS and HTTPS settings
I’m going to assume you know your way around Cloudflare and DNS records. To date I haven’t found a better CDN and DNS management tool, and it’s free. Add your new site, or browse to its current domain Overview page.
Point DNS records to the new IP address:
- On the Overview page, click DNS Settings under the Quick Actions menu.
- Update the A record for yourdomainname.com to match the new Static IP address you created above.
- Unless you are hosting subdomains elsewhere, review the other A records and change their IP addresses to the new Static IP as well.
- The A record for localhost should remain 127.0.0.1.
- Leave all A records proxied (except for localhost).
Set SSL/TLS encryption mode to Full (strict):
- On the left nav menu, select SSL/TLS.
- Set the encryption mode to Full (strict).
Turn off Always Use HTTPS:
You will setup your SSL Certificate to handle this step for you soon.
- On the left nav menu, select SSL/TLS > Edge Certificates.
- Set Always Use HTTPS to Off.
Purge Cache:
- Go back to the Overview page.
- Click Purge Cache under the Quick Actions menu.
- Click Purge Everything, and confirm when prompted.
Pause Cloudflare on site:
You will turn this back on after you setup SSL.
- Go back to the Overview page.
- Click Pause Cloudflare on site under the Advanced Actions menu (near the bottom of the page), and confirm when prompted.
Now we’ll setup an SSL Certificate via Bitnami’s command line tool in Lightsail.
6. Setup the new site with a free SSL certificate
Now is a good time to restart all the server services prior to requesting a certificate. It also allows a little more time for the DNS settings just made to propogate.
- Restart all services: sudo /opt/bitnami/ctlscript.sh restart
- Start the Bitnami certificate tool: sudo /opt/bitnami/bncert-tool
- The tool will check for an update. When prompted, type Y and press enter to update.
You may get an error stating that the IP address is incorrect. If this happens, check that you completed the DNS settings in step 5 correctly. It may be the DNS cache needs a little more time to point the IP to the site.
- When prompted, answer the following questions:
- Enable HTTP to HTTPS redirection?: Y
- Enable non-www to www redirection?: Y
- Enable www to non-www redirection?: N
- Follow the rest of the prompts to complete the request. When prompted, enter the e-mail address of the site contact.
- Once the SSL steps are complete, open a window and browse back to the Cloudflare page for your site.
- At the bottom of the Overview page, click Enable Cloudflare on Site to turn Cloudflare services back on.
Now it’s time to upload your Duplicator Pro package and migrate your site.
7. Install the Duplicator Pro package on your new site
Additional helpful links for this section:
Duplicator Pro - Installer - User Guide
Duplicator Pro - How to easily move a WordPress site
If you think there is a lot to do already, you’ll be happy you’re using Duplicator Pro. The following steps replace the typical MySQL craziness that goes hand in hand with WordPress migrations.
- Connect to your site via FileZilla SFTP.
- In the right pane, browse to the /opt/bitnami/wordpress/ folder.
- Upload both of the files included in the Duplicator Pro package to the wordpress folder. There will be a zip file and a file ending with or named installer.php.
- In a new browser window, type the following, replacing yoursitedomain.com with the domain name of your new site: https://www.yoursitedomain.com/installer.php
- NOTE (Domain Names): Your domain name should work in this step if DNS and your new SSL certificate are setup correctly. You can also use your site’s static IP address, but it’s good to have the domain name working in this step. Some variations to the steps above may require the IP address.
- NOTE (installer.php): The installer.php file may include more characters and a longer name. Make sure the file name matches the URL exactly.
The following screen should appear. The default Mode should show an Overwrite install. Install Type should be a Full install single site. Where the arrow indicates, click Advanced:
If permissions are correct, the current wp-config.php file should populate the database details that you will be overwriting. Make sure to click Apply to confirm the database details.
Under Site Details, if you were able to browse to this installer using your https://www.yoursitedomain.com address, then we want to make sure that both the New Site URL and the Old value match.
NOTE: This is a me workflow. Other workflows may not let you redirect the DNS for your domain this early in the process. But it helps. If you can’t, then the New Site URL will likely need to be your server’s static IP address for now. You’ll have to do a find and replace on the database later to correct this (not shown, but here is some helpful information using the free WP Migrate find and replace tool).
Verify all your settings are ready to go, and click Validate.
At this stage, you’ll have to let the validate console tell you any warnings or notes. Some warnings are okay, some are not. Take some time to troubleshoot any errors, and when ready, check the box I have read and accept all terms & notices (assuming of course you did this and accept full responsibility for everything you’re doing to your site :). When ready, click Next.
From here out, if all is good, you’ll be safe to click through the next 2-3 steps with no adjustments. When completed, you’ll be presented with a status page. Troubleshoot any errors. If all looks good, click the link to login to the WordPress Admin area and proceed with cleanup. You’ll need to use a login from the previous site to gain access. Take a look around the new site and note any problems.
Now for some more server maintenance.
8. Adjust additional server settings
Open up the Lightsail SSH terminal window again, and work through the following adjustments:
Restart all server services:
sudo /opt/bitnami/ctlscript.sh restart
Resolve “WordPress Asking for FTP Credentials” Error:
Edit your wpconfig.php file to add a line. If this isn’t done, you will constantly be prompted for FTP credentials when installing plugins.
- sudo nano /opt/bitnami/wordpress/wp-config.php
- Type the below-mentioned command above the line define(‘DB_NAME’, ‘*****’);
- After making the changes, Press Control + O to write the changes. Press enter.
- Press Control + X to exit Nano.
Update the Bitnami .htaccess file to setup security headers:
- sudo nano /opt/bitnami/apache/conf/vhosts/htaccess/wordpress-htaccess.conf
- NOTE: This and upcoming edits to wordpress-htaccess.conf require completion of this step above.
- Add the following code to the file:
<IfModule mod_headers.c>
Header set Strict-Transport-Security “max-age=63072000; includeSubDomains; preload”
Header set Permissions-Policy “camera=(), microphone=(), geolocation=(), interest-cohort=()”
Header set X-Content-Type-Options nosniff
Header set X-DNS-Prefetch-Control “on”
Header set X-Frame-Options “SAMEORIGIN”
Header set X-XSS-Protection “1; mode=block”
Header set Referrer-Policy “same-origin”
Header set Content-Security-Policy “upgrade-insecure-requests;”
</IfModule>
# END WordPress
</Directory>
- After making the changes, press Control + O to write the changes. Press enter.
- Press Control + X to exit Nano.
- Restart Apache: sudo /opt/bitnami/ctlscript.sh restart apache
- Update Bitnami’s PHP.ini to reflect your time zone and site needs:
- sudo nano /opt/bitnami/php/etc/php.ini
- Change the following values to match your setup. I use Divi for site builds, which requires the following changes. My time zone is also EST, near Detroit:
- date.timezone = “America/Detroit” (see PHP Timezones for yours)
- memory_limit = 512M
- post_max_size = 200M
- upload_max_filesize = 100M
- max_execution_time = 120
- max_input_time = 320
- max_input_vars = 1000
- display_errors = 0
After making the changes, press Control + O to write the changes. Press enter.
Press Control + X to exit Nano.
Restart Apache: sudo /opt/bitnami/ctlscript.sh restart apache
WORDFENCE USERS ONLY: If you use Wordfence, you will be prompted often with a constant message that the .user.ini file is publicly accessible. You need to edit 2 files, wordpress-vhost.conf and wordpress-https-vhost.conf. Make sure Wordfence has been reactivated and setup, then proceed with the following steps. [Reference: WordPress.org]
NOTE: I’ve had issues writing to this file using Nano. If you decide to use FileZilla to edit locally and re-upload instead of Nano, You’ll need to change permissions of each file below to bitnami before starting:
sudo chown -R bitnami:bitnami /opt/bitnami/apache/conf/vhosts/wordpress-vhost.conf
sudo chown -R bitnami:bitnami /opt/bitnami/apache/conf/vhosts/wordpress-https-vhost.conf
….and then change them back to root after the very last steps:
sudo chown -R root:root /opt/bitnami/apache/conf/vhosts/wordpress-vhost.conf
sudo chown -R root:root /opt/bitnami/apache/conf/vhosts/wordpress-https-vhost.conf
- File #1:
- sudo nano /opt/bitnami/apache/conf/vhosts/wordpress-vhost.conf
- Immediately under the line #END WORDPRESS, add the following lines:
-
# Wordfence WAF
<Files “.user.ini”>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</Files>
# END Wordfence WA
-
- After making the changes, press Control + O to write the changes. Press enter.
- Press Control + X to exit Nano.
- File #2:
- sudo nano /opt/bitnami/apache/conf/vhosts/wordpress-https-vhost.conf
- Immediately under the line #END WORDPRESS, add the following lines:
-
# Wordfence WAF
<Files “.user.ini”>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</Files>
# END Wordfence WA
-
- After making the changes, press Control + O to write the changes. Press enter.
- Press Control + X to exit Nano.
- See the note above regarding file permissions. If you changed them, change them back to root.
- Restart Apache: sudo /opt/bitnami/ctlscript.sh restart apache
Reset all WordPress folder/file ownership and permissions:
NOTE: These permissions are necessary for Bitnami to work correctly. [Reference: Bitnami]
- sudo chown -R bitnami:daemon /opt/bitnami/wordpress
- sudo find /opt/bitnami/wordpress/ -type d -exec chmod 775 {} \;
- sudo find /opt/bitnami/wordpress/ -type f -exec chmod 664 {} \;
- sudo chmod 640 /opt/bitnami/wordpress/wp-config.php
Update and Upgrade the server to the latest packages:
Bitnami restricts the packages you can upgrade, including the LAMP stack. This is good, it keeps you from breaking stuff. But let’s upgrade what we can:
- sudo apt-get update
- sudo apt-get upgrade
Restart all server services:
- sudo /opt/bitnami/ctlscript.sh restart
That’s it for my list of server adjustments. Now, we’ll tighten up security, starting with Cloudflare.
9. Configure your Cloudflare firewall
Browse to the Cloudflare page for your site. At the bottom of the Overview page, verify that Cloudflare services are turned back on.
Enable HSTS, and we’ll start using those security headers we setup earlier:
- On the left nav menu, select SSL/TLS > Edge Certificates.
- Browse down the page, and click Enable HSTS:
- Select I understand at the bottom of the splash page.
- On the Configure page, turn on all checkboxes and change Max Age Header (max-age) to 12 months and click Save:
- Test if the secure headers are turned on by visiting both securityheaders.com and hstspreload.org. You should get green indicators and an A+ if this and the above steps in section 8 were setup correctly.
Block bad bots, but allow the good ones:
- On the left nav menu, select Security > Bots.
- Turn Bot Fight Mode on.
- On the left nav menu, select Security > WAF.
- Click Create firewall rule. Enter the following:
- Rule name: Allow Known Bots
- Field: Known Bots equals ON
- Choose an action: Allow
- When finished, Deploy firewall rule.
Block No-Referrer Requests to Plugins:
(This rule will prevent anyone but your domain from accessing the wp-content/plugins directory.)
- On the left nav menu, select Security > WAF.
- Click Create firewall rule.
- Rule name: Block No-Referrer Requests to Plugins
- Click Edit expression above the Expression preview box. We’ll copy and paste this one, which enters most of the values for you.
- Copy and paste this expression into the preview box. Change the bolded text to match your site domain:
- When finished, Deploy firewall rule.
Block XML-RPC Attacks:
(Perform this step only if you do not post from a phone or to multiple sites.)
- On the left nav menu, select Security > WAF.
- Click Create firewall rule.
- Rule name: Block XML-RPC Attacks
- Click Edit expression above the Expression preview box. We’ll copy and paste this one, which enters most of the values for you.
- Copy and paste this expression into the preview box:
- When finished, Deploy firewall rule.
Whitelist the new server’s Static IP address in Cloudflare:
(Some plugins, including Duplicator Pro‘s automatic backup feature, cannot be setup correctly if this step isn’t performed.)
- On the left nav menu, select Security > WAF.
- Click Tools in the top menu.
- Fill in the following fields:
- IP, IP range, country name, or ASN: Enter the Static IP address for your new Lightsail server.
- Action: Change to Allow.
- Notes: Enter a description. I use “Lightsail IPv4”.
- Click Add.
- If you also use IPv6, follow the exact same steps to add an entry for your IPv6 server address.
Now let’s tighten up Lightsail.
10. Configure your Lightsail firewall
Now that we’ve locked down Cloudflare, we still need to make some changes to our Lightsail server. Right now, our Static IP address is directly accesible, and Cloudflare can be completely circumvented.
Browse to the Lightsail home page to get started.
Click the blue heading on your new Instance to open its settings page.
- Click Networking at the top. The following screen will appear. We will be working in the IPv4 Firewall and IPv6 Firewall sections.
- Under IPv4 Firewall, click the Edit button next to the HTTP section.
- Check the box Restrict to IP address.
- This will open a blank box where an IP range can be entered. Click Add another to keep adding blank fields. At the time of writing, Cloudflare has a total of 15 IP ranges, so you’re going to need 15 fields. Add those fields and get ready to copy and paste.
- Open this link (Cloudflare IP ranges) in a new browser window, and place the new window side by side with the window you are working in. You’re going to be doing a lot of copy and pasting.
- This page will list both the IPv4 and IPv6 Cloudflare Ranges. Copy and paste every entry under the IPv4 list into the blank Lightsail firewall fields. When done, it should like this:
- Click Save.
- Perform the same steps as above for the HTTPS edit button (second arrow shown at the bottom of this pic).
- Once the IPv4 firewall is completed, follow the steps above for both the HTTP and HTTPS edit buttons under the IPv6 Firewall section. Copy the IPv6 ranges from Cloudflare into these sections.
We’ve tightened up both the Cloudflare and Lightsail firewalls! Now traffic is limited to the domain name only, and it can only be browsed via Cloudflare’s proxied DNS entries.
11. Run through a final checklist
We’re pretty close to being finished! Here are some final steps in my personal workflow:
- Plugin Installations:
- Make sure you add the above entry to wp-config.php to avoid being prompted for an FTP login when trying to install plugins.
- WP Mail SMTP: Install and configure this WordPress plugin.
- Lightsail does not include a mail server in it’s Bitnami instance. For business email, you’ll need a paid account like Google Workspace, Microsoft Exchange, or Zoho mail to deliver email.
- Any form of email notifications, including contact forms, will need this plugin. Details on configuring it can be found during the install or on this page.
- If you are not the primary contact of the site, and you don’t want your client’s receiving weekly digests from WP Mail SMTP, check the box under Settings > MISC > Disable email summaries weekly delivery.
- Caching Plugins:
- Install and configure a caching plugin.
- NOTE: I have had difficulties getting WP Super Cache to play nice with Bitnami’s .htaccess requirements. Even with manual entries to wordpress-htaccess.conf it may not work correctly.
- If successful, suggested settings for WP Super Cache (recommended) can be found here.
- NOTE: I have had difficulties getting WP Super Cache to play nice with Bitnami’s .htaccess requirements. Even with manual entries to wordpress-htaccess.conf it may not work correctly.
- Install and configure a caching plugin.
- Duplicator Pro:
- Setup your Duplicator Pro plugin to perform regular backups. Details on setup can be found here.
- Lightsail Automatic Snapshots:
- Lightsail offers automatic backups via Snapshots. These are not free, but they are very cheap. Snapshots allow a very quick deployment of a previous backup.
- Automatic snapshots are daily, and you can only keep up to 7 days worth of snapshots automatically.
- Any snapshot can be saved as a manual snapshot. I recommend creating a manual snapshot when you are all done to retain a “clean” install of your site.
- Because anything beyond 7-day retention of backups requires manual saves, I use both Automatic snapshots AND Duplicator Pro.
- More details from AWS on Lightsail snapshots can be found here.
- WP Migrate (find & replace):
- WP Migrate is a WordPress plugin whose free version allows unrestricted Find & Replace functionality on the database.
- I usually run a find and replace on the database to convert all http:// links to https://www links on the site. May be overkill as the SSL certificate we setup automatically redirects these links.
- Fix Flashing of Unstyled Content (Divi users only):
- Follow Mark Hendriksen’s simple steps to add a script to the Divi header.
- Note that Divi users using Cloudflare’s Rocket Loader functionality may have small flickers of white on page loads. I plan to address that in another post, my current fix is to not use Rocket Loader.
- Wordfence (highly recommended):
- Firewalls protect the front and back doors, Wordfence guards the lobby. Install this free WordPress plugin. Details available here.
- Allow Wordfence’s learning mode to stay on for 7 days. If you’ve migrated, you may need to re-enable this setting.
- Whitelist Cloudflare’s IPs within Wordfence.
- Update all WordPress Plugins.
- Verify all plugin/theme licenses are still setup properly after the migration.
- Clear all Caches, both Cloudflare and Plugins.
- Buy yourself (and me) a coffee and relax!
0 Comments