Moving your website to a new server without stopping the business
Moving your website to a new server can be done so that nobody notices. But it has more steps than it seems, and two places where it is easy to make a mistake. This guide gathers what we have learned from more than thirty migrations: when it pays off, what can go wrong, how to avoid it, and what needs to be done afterwards. It is written for the person who makes the decision. The technical instructions are at the end, in a separate section for whoever will carry them out.
When switching servers pays off and when it doesn’t
A small website with little content and few visits can run perfectly well on standard hosting. It usually costs less and can be managed from a control panel. Moving to your own cloud server pays off in these cases.
- The website has become slow or crashes when there are many visitors, and your provider can’t give it more power without switching to an entirely different plan.
- You need control over the server: which versions it runs, which tasks run and when, and who logs in.
- You want the website to withstand attacks and large images not to slow it down.
- You care where your data is physically stored. Here you choose the country, and our servers are within the European Union.
- You plan to grow and don’t want to have to migrate again within a year.
Compared with shared hosting, your own cloud server gives you three things. It has more power when you need it, and it can be scaled up in minutes. The price is fixed and known in advance. And you decide on every component. In return, someone has to maintain that server: updates, backups, security and error alerts. If nobody in your company is going to do it, the answer is not “don’t migrate.” It is “migrate with someone who maintains it for you.”
What can go wrong and how to avoid it
The website being down for a while
This is the most visible risk. It is avoided by building the new website completely and testing it before changing the address, and by preparing the address change the day before, so that it takes effect in minutes rather than hours. Done well, the downtime is just the minutes it takes for the change to spread. In our migrations, less than 15 minutes.
Something not working the same way
A plugin that needed something from the old server may fail. Or a different version of the server software. Or a setting that was not copied over. It is avoided with a prior review of the website and by testing the new site before changing the address. Failures show up while the address still points to the old site, so there is time to fix them.
Being slower than expected
A new server does not make a website fast on its own. A small server that builds every page on every visit can perform worse than the previous hosting. It is avoided in three ways: choosing the server based on what the website actually consumes today, not by guesswork; caching each finished page so it doesn’t have to be built again on the next visit; and serving images from servers spread around the world. After the migration, measure speed the same way as before and compare.
Security being poorly set up
A server of your own is your responsibility. There are three typical failures. The first is leaving open doors that aren’t needed. The second is logging in with an ordinary password. It is better to log in with an access key that exists only on your computer, which is much harder to steal. The third is a WordPress that hasn’t been updated.
It is avoided by leaving open only what is essential for the website to work and for you to maintain it. Access is always through that key file. Updates are enabled and a filter that blocks attacks is placed in front. And all passwords copied from the old website are changed.
The bill skyrocketing
The server price is fixed and known. What can grow is the traffic from the servers spread around the world and the storage space for images. This happens if you serve a lot of video or uncompressed images. It is avoided by setting spending alerts from day one and compressing images before uploading them. With us this doesn’t happen: the price is fixed and you know it from day one.
Would you prefer that we do the migration?
We have done more than thirty WordPress migrations, with downtime of only minutes. If you want us to take care of it, migrate your WordPress to PF Hosting explains how we do it and what we need from you. And if you would rather see a real example first, the WordPress migrations case study tells two stories. A digital magazine that was going down several times a day stopped crashing and now costs 30% less. And a promotional gifts company migrated in a week.
What the target server looks like
For almost all company websites and medium-sized shops we recommend the same setup. It is the one that best balances cost, speed and ease of maintenance.
- A server just for your website, with a fixed size and a fixed monthly price. It comes with WordPress already installed. If the website grows, you move to a bigger server without reinstalling anything.
- Images, videos and code, kept separately. They are stored in their own storage and served from servers spread around the world. Your server is free to do the one thing only it can do: build the pages.
- A filter in front that blocks attacks before they reach the website.
- Automatic helpers for one-off tasks, such as making the photos you upload lighter. You only pay for them when you use them, and they are optional.
How it is done, broadly speaking
The new website is built completely and thoroughly tested while the old one keeps running. Only then is the address changed. That way the downtime is minutes, not hours.
There are two routes. One uses a plugin that packages the files and the database. The other is manual. We prefer the manual route when the website has many images or special settings, because each step is controlled and you know what failed if something does. The seven steps, with their instructions, are in the final section.
Before you start, have this to hand
- A full backup of the current website, verified: downloaded and opened, not just “created.”
- Access to where your domain’s DNS records are managed. And arrange the day before for the address change to take effect within minutes.
- The list of active plugins, with their licenses, and of connected external services: payments, email, customer management.
- The WordPress and server software versions your website uses today, so you can check that the new site supports them.
- A notice to whoever needs to know, even though the goal is for nobody to notice anything.
After the migration
Outgoing email
The new server does not send email by itself. Forms, order notifications and password recovery stop arriving until a sending service is connected. It is set up once. If your company already uses business email, nothing changes: only the way WordPress sends email changes.
Backups
There are two different kinds of backup, and it is worth not confusing them.
The snapshot of the entire server is for going back if something breaks. One is taken manually before each change, and the automatic daily ones are enabled. It recreates the server exactly as it was that day. It also serves to move to a bigger server or to set up a test site.
The versions WordPress keeps are for recovering a specific text. If someone deletes a paragraph from a page, there is no need to touch the server.
It is also worth keeping copies outside the provider.
The first week
A migration does not end when the address changes. The first week is when the problems appear that the prior testing doesn’t reveal:
- Keep the old website running for a few days, without publishing to it. If something fails, going back means changing the address again. Once you are sure, cancel it and keep its last backup.
- Forms and email: send a message from each form and check that it arrives. It is the first thing to break and the last thing anyone reports.
- Scheduled tasks: have the server itself run them, not visitors. It is a five-minute change that prevents outages.
- Google: check that it still sees the website and that no errors have appeared. If the domain doesn’t change, nothing else is needed. If it does, every old address must redirect to the new one.
- Error alerts: ask whoever maintains the website to review them every day, even when everything looks fine. A recurring alert often announces the outage to come.
- A speed measurement to compare with the earlier one. If it hasn’t improved, the WordPress speed guide is the next step.
Your data, in the European Union
We host in the European Union. Your data, its backups and your images stay within the European Union, and we confirm it in writing.
The server cannot be reached from outside. Your website can only be reached by passing first through the filter that blocks attacks. We back up every day, and the team logs in through a private connection.
If your client or the law asks for more
Having a server in Europe is not enough on its own. It also matters how it is configured, who logs in, and whether you can tell who did what and when. Our service is set up with that in mind.
If you sell to the public administration, they may ask you to comply with the ENS, the security standards the administration requires. If you handle personal data, the GDPR, the European data protection law, requires you to know where it is and who accesses it. A well-maintained server in the European Union is a solid base for both. And we document what was done, for when someone from outside comes to review it.
What we use
What this guide uses. AWS is Amazon’s data centre network. The server is an Amazon Lightsail instance running Bitnami’s WordPress blueprint. Images go to a private S3 bucket and are served by Amazon CloudFront, with AWS WAF in front. Outgoing email can be sent through Amazon SES, which is contracted separately. Standalone tasks, when they are needed, run on AWS Lambda. To migrate the site we use rsync, mysqldump and WP-CLI, or a plugin such as All-in-One WP Migration, Duplicator, WP Migrate, UpdraftPlus or Migrate Guru.
What PF Hosting uses. Our product runs on our own servers in a European Union region, with no public address. It sits behind Amazon CloudFront and AWS WAF. Backups are taken daily, and updates are handled by our team. Email is not included: it is contracted separately.
For whoever will carry it out: the steps with commands
What follows is for the person who will run the migration. If that isn’t you, pass it on. Make a full backup before you start, and don’t change the DNS until you have tested the new site.
How it is set up
Amazon Lightsail for WordPress. Lightsail is the simplified version of AWS servers. It is an instance with a fixed amount of CPU, memory, disk and transfer, and a fixed monthly cost. Its WordPress blueprint (maintained by Bitnami) comes with Apache, PHP, MariaDB and WordPress installed and configured, with the site at /opt/bitnami/wordpress. If the site grows, you switch to a larger instance from a snapshot, without reinstalling anything.
S3 and CloudFront for static content. Images, videos, stylesheets and scripts are stored in a private Amazon S3 bucket. Amazon CloudFront, AWS’s CDN, serves them. It copies them to dozens of locations around the world and delivers each file from the one closest to the visitor. AWS WAF, a web application firewall, is enabled in front of CloudFront and filters malicious traffic before it reaches the site. For a step-by-step guide to setting up this CDN, see the WordPress speed guide.
Lambda for standalone tasks, not for WordPress. AWS Lambda runs code without a server and you pay per execution. It cannot host WordPress, which needs a server that is always on. It is useful for specific tasks around it: optimising and converting images uploaded to the bucket, minifying files or generating reports. It is an optional component, useful when the volume of images is large.
Tools for migrating the site
- All-in-One WP Migration: exports the whole site (database, media, plugins and themes) to a single file that is imported on the destination. The simplest option for small and medium sites.
- Duplicator: creates a complete package of the site plus an installer that deploys it on the new server. Widely used for cloning.
- WP Migrate: specialises in the database. It exports it while replacing the old URLs and paths with the new ones, the step people most often forget.
- UpdraftPlus: is a backup plugin that can also restore to another server. It is useful for migrating and for later backups.
- Migrate Guru: automates the full migration between two servers without going through your computer. Useful for large sites.
A plugin can replace steps 5 and 6 of the manual route that follows.
Step 1: assess the current site
Before migrating anything, see what you are going to migrate. How much space the database and the media folder take up. Which plugins are active and which can be deleted before the migration. Which theme the site uses and whether it has custom code. This is also the moment to clean up: a database without old revisions or spam transfers faster and starts up better on the destination. Note anything unusual: scheduled tasks, rules in .htaccess, folders outside WordPress.
Step 2: create the AWS account and choose the service
If you don’t have an AWS account, create one with an organisation email, not a personal one, and enable two-factor authentication on the root user. Then decide where WordPress will live. For a corporate site or a mid-sized shop, Lightsail; for large applications with several servers and load balancing, EC2. This guide follows the Lightsail route, which is the one we recommend and the one we use in our migrations. Choose a European Union region if your visitors and your data are in Europe.
Step 3: launch the instance
In the Lightsail console, click «Create instance»: a European Union region, Linux platform, «WordPress» blueprint. Choose the size based on the current site; you can scale up later, but not down without rebuilding the instance. Once it is running, assign it a static IP from the «Networking» tab. Without it, the IP changes on reboot and the DNS stops pointing to the site. Open the browser SSH client or connect from your terminal with the key Lightsail provides. The initial WordPress administrator password is in the bitnami_application_password file in the home folder.
Step 4: prepare the source site
On the current hosting, export the complete database to a .sql file (from phpMyAdmin or with mysqldump). Download the wp-content folder, which is where the themes, plugins and media live. The WordPress core does not need to be copied, as the instance already includes it. If the current and new sites will run side by side for a few days, note the date of this copy. Anything published after that will need to be exported again, or you can freeze publishing until the DNS change.
Step 5: transfer the files
On the Lightsail WordPress blueprint, the site lives in /opt/bitnami/wordpress, not in /var/www as on other servers. It is the path error that appears most often in migration tutorials. Copy your wp-content to the instance with SCP or rsync. Then restore the permissions Bitnami expects, with the user bitnami and the group daemon:
rsync -avz wp-content/ bitnami@IP-DE-LA-INSTANCIA:/opt/bitnami/wordpress/wp-content/
sudo chown -R bitnami:daemon /opt/bitnami/wordpress/wp-content
sudo find /opt/bitnami/wordpress/wp-content -type d -exec chmod 775 {} \;
sudo find /opt/bitnami/wordpress/wp-content -type f -exec chmod 664 {} \;
Step 6: create the database and import the copy
The instance comes with MariaDB and a database already created for the sample WordPress site. You can reuse it or create your own, which is what we do so that the name and user are your own. Log in to the database server with the password for bitnami_application_password:
mysql -u root -p
CREATE DATABASE mi_web;
CREATE USER 'mi_usuario'@'localhost' IDENTIFIED BY 'una-contraseña-larga';
GRANT ALL PRIVILEGES ON mi_web.* TO 'mi_usuario'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Upload the .sql file to the instance and import it. Then use WP-CLI, which the blueprint has installed. Replace the old domain with the new one throughout the database (or with the static IP while you test). WordPress stores absolute URLs in hundreds of places:
mysql -u mi_usuario -p mi_web < copia.sql
cd /opt/bitnami/wordpress
wp search-replace 'https://web-antigua.com' 'https://www.mi-web.com' --all-tables
Step 7: adjust wp-config.php, change the DNS and test
Make a copy of the configuration file and edit it with the details of the new database:
cd /opt/bitnami/wordpress
sudo cp wp-config.php wp-config.php.backup
sudo nano wp-config.php
define('DB_NAME', 'mi_web');
define('DB_USER', 'mi_usuario');
define('DB_PASSWORD', 'una-contraseña-larga');
define('DB_HOST', 'localhost');
Also check that the table prefix ($table_prefix) matches that of the imported database. Restart the services with sudo /opt/bitnami/ctlscript.sh restart. Test the site via the static IP. Better still: edit the hosts file on your computer so the domain points to the new IP, without touching the DNS yet. Check the home page, a post, a page with a form, the checkout process if there is one, and the admin panel. Once everything works, change the domain’s A record to the static IP. Enable HTTPS on the instance with Bitnami’s bncert-tool tool, which configures it and renews it automatically. If you lowered the DNS TTL a day in advance, the change takes effect within minutes.
Security and costs: the specific settings
In the Lightsail firewall, leave only ports 22, 80 and 443 open. Log in over SSH with a key only, never with a password. Turn on updates and put CloudFront with WAF in front of the site. Change the passwords of everything that was copied from the old site. On Lightsail the cost is fixed; what can grow is CloudFront transfer and S3 storage. Turn on billing alerts in AWS from day one.
Where the logs are
When something fails, the logs tell the story. In the Bitnami blueprint they are here:
- Apache access:
/opt/bitnami/apache/logs/access_log - Apache errors:
/opt/bitnami/apache/logs/error_log - PHP errors:
/opt/bitnami/php/logs/php-fpm.log
To view the last lines of one of them while you reproduce an error:
tail -n 100 -f /opt/bitnami/apache/logs/error_log
Outgoing email with SES
A Lightsail instance does not send email on its own. The natural option within AWS is Amazon SES. You verify the domain with a few DNS records and create SMTP credentials. Then you configure WordPress with a plugin such as WP Mail SMTP so that it sends through SES. Bear in mind that SES starts in sandbox mode, which only delivers to verified addresses, and you have to request removal from that mode. If the organisation already uses Google Workspace or Microsoft 365 for email, the MX records stay as they are. Only the sending from WordPress changes, which can go through SES or through your provider’s SMTP.
Backups with snapshots
Lightsail makes copies of the whole instance using snapshots. On the instance page, under the «Snapshots» tab, you create one manually with a descriptive name, and you turn on daily automatic snapshots. Lightsail keeps the most recent automatic snapshots; your console shows the exact number. A snapshot is restored by creating a new instance from it. That is also why it is useful for changing size or cloning a test environment. It is a server backup, not a content backup: to go back to an earlier version of a single post, WordPress revisions still do the job. To keep copies outside AWS, use a plugin such as UpdraftPlus to send them to another storage service. We have a dedicated post on WordPress backups on Lightsail, and another on setting up a test environment on Lightsail from a snapshot.
Scheduled tasks and Search Console
WordPress runs its tasks (scheduled posts, backups, sends) when someone visits the site. On your own server it is better to run them from the system cron, every five minutes, and to disable the internal mechanism in wp-config.php. It is a small change that avoids many outages caused by load spikes.
In Search Console, check that Google can still see the site, that the sitemap responds and that no crawl errors have appeared. If the domain doesn’t change, nothing else is needed. If it does, you have to declare the address change and redirect every old URL to its new one.
