WordPress-Server-Ubuntu-24.04
8 Migrating WordPress to a Diffrent Server

Guide to Migrating a WordPress Site to another Ubuntu 24.04 instance

Initial Steps:

  1. Update the Package List:

    First, update and upgrade the packages on both the old and new servers:

    sudo apt update && sudo apt dist-upgrade -y

Install Required Packages on the New Server:

  1. Install Apache, MySQL, and PHP (LAMP stack):

    On the new server (DigitalOcean or AWS EC2):

    sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql php-xml php-mbstring php-curl -y

Obtain an SSL Certificate

To secure your site with HTTPS, you'll need an SSL certificate. We will use Certbot, a free tool provided by Let’s Encrypt, to manage the SSL certificates. First, install Certbot:

sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update
sudo apt install certbot python3-certbot-nginx
---
 
### **Setting Up Permissions for `/var/www` and Web Files:**
 
**Note**  
This section covers the recommended permissions setup for web directories and files on a Linux server, specifically for `/var/www` and `/var/www/example.com`. Ensure these permissions are applied during file migration and server setup to maintain security and proper functionality.
 
---
 
#### **Permissions Setup for `/var/www` and `/var/www/example.com`:**
 
1. **`/var/www` Directory:**
   - **Owner:** `root`
   - **Group:** `www-data`
   - **Permissions:** `755`
 
   Commands:
 
   ```bash copy
   sudo chown root:www-data /var/www
   sudo chmod 755 /var/www
  1. /var/www/example.com Directory:

    • Owner: www-data
    • Group: www-data
    • Permissions for directories: 755
    • Permissions for files: 644

    Commands:

    sudo chown -R www-data:www-data /var/www/example.com
    sudo find /var/www/example.com -type d -exec chmod 755 {} \;
    sudo find /var/www/example.com -type f -exec chmod 644 {} \;

Nginx Configuration:

  1. Add the Site to Nginx:

    You can either create a new config based on Chapter 3 or copy the existing configuration. It's recommended to copy the existing configuration for consistency. Also, if permissions need to be changed temporarily as we did earlier, you can do the same.

    On the old server, if permission changes are needed and folder moving is required :

    sudo chown user:user /etc/nginx/sites-available/example.com
    sudo cp /etc/nginx/sites-available/example.com ~/

    Copy the configuration file from the old server:

    scp -r user@example.com:~/example.com ~/

    Move the file to the Nginx configuration directory and set ownership:

    sudo mv example.com /etc/nginx/sites-available
    sudo chown root:root /etc/nginx/sites-available/example.com

    Enable the site by creating a symlink:

    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Reference for Nginx file ownership and permissions so we can set it back when needed:

Nginx File Ownership and Permissions

Overview

Files and directories in /etc/nginx/ should be owned by root to maintain system security.

Permissions and Ownership

Directories

  • Path: /etc/nginx/, /etc/nginx/sites-available/, /etc/nginx/sites-enabled/

  • Owner: root

  • Group: root

  • Permissions: 755

    sudo chown root:root /etc/nginx
    sudo chmod 755 /etc/nginx

Files

  • Path: /etc/nginx/nginx.conf, /etc/nginx/sites-available/example.com

  • Owner: root

  • Group: root

  • Permissions: 644

    sudo chown root:root /etc/nginx/nginx.conf
    sudo chmod 644 /etc/nginx/nginx.conf
    sudo chown root:root /etc/nginx/sites-available/example.com
    sudo chmod 644 /etc/nginx/sites-available/example.com

Summary

  • Directories: 755 permissions for root ownership
  • Files: 644 permissions for root ownership

SSL Certificates:

  1. Copy SSL Certificates:

    On the old server, if you encounter issues with scp and need to unlink symbolic links temporarily, follow these steps:

    Unlink symbolic links:

    sudo rm /etc/letsencrypt/live/example.com/chain.pem
    sudo rm /etc/letsencrypt/live/example.com/fullchain.pem
    sudo rm /etc/letsencrypt/live/example.com/privkey.pem

    Change ownership and copy the SSL certificates to your home directory:

    sudo chown user:user /etc/letsencrypt/live/example.com
    sudo cp /etc/letsencrypt/archive/example.com/*.pem

    Ensure your SSH user has access:

    sudo chown user *.pem

    Copy the certificates to the new server:

    scp -r user@example.com:~/*.pem ~/

    Once transferred, on the old server, restore the symbolic links and change ownership back to root:

    sudo ln -s /etc/letsencrypt/archive/example.com/chain1.pem /etc/letsencrypt/live/example.com/chain.pem
    sudo ln -s /etc/letsencrypt/archive/example.com/fullchain1.pem /etc/letsencrypt/live/example.com/fullchain.pem
    sudo ln -s /etc/letsencrypt/archive/example.com/privkey1.pem /etc/letsencrypt/live/example.com/privkey.pem
    sudo chown root:root /etc/letsencrypt/live/example.com

On the new Server:

we will create the /etc/letsencrypt path and move the certs there and change owner to root then a symbolic link so it's the same setup:

 sudo mkdir -p /etc/letsencrypt/live/example.com/
 sudo  mkdir -p /etc/letsencrypt/archive/example.com/
 sudo mv ~/*.pem /etc/letsencrypt/archive/wpdev.yourbestbuystore.com/
 sudo chown -R root:root /etc/letsencrypt/
 sudo ln -s /etc/letsencrypt/archive/example.com/chain1.pem /etc/letsencrypt/live/example.com/chain.pem
 sudo ln -s /etc/letsencrypt/archive/example.com/fullchain1.pem /etc/letsencrypt/live/example.com/fullchain.pem
 sudo ln -s /etc/letsencrypt/archive/example.com/privkey1.pem /etc/letsencrypt/live/example.com/privkey.pem

Now we will change the permissions:

sudo find /etc/letsencrypt/ -type d -exec chmod 755 {} \;
sudo find /etc/letsencrypt/ -type f -exec chmod 644 {} \;

Note: The permissions of a symlink don’t impact access; they only indicate the symlink's own attributes. Access to the actual file is determined by the file’s permissions. If the target file has 644 permissions, users can read it but only the owner can write to it, regardless of the symlink's permissions.

As we kept the same folder structure we do not need to update the Nginx configuration on the new server as the certificate paths we copied over are the same.

Test the Nginx configuration:

sudo nginx -t

Reload Nginx:

sudo service nginx reload

Spoof DNS for Testing:

  1. Spoof DNS:

    Add an entry to your /etc/hosts file to test the new server:

    sudo vim /etc/hosts

    Add:

    NEW_SERVER_IP    example.com

    Save the file and refresh the site. You should see “Error establishing a database connection” if the database is not yet migrated.

    Note: After updating the DNS, you will need to SSH to the new server using its IP address.


File Migration Steps:

  1. Backup the Database on the Old Server:

    Use mysqldump to back up the database:

    mysqldump --no-tablespaces -u DB_USER -p DB_NAME > ~/backup.sql

    Enter the password when prompted.

  2. Copy the Site Files:

    Temporarily change ownership of the files for migration:

    sudo chown -R your_user:your_user /var/www/example.com
    cp -R /var/www/example.com/ ~/
    sudo chown -R root:root /var/www/example.com

    Use scp to transfer files from the old server to the new server:

    scp -r user@old_server_ip:/home/user/example.com ~/

    After transferring, adjust ownership and move the files:

    sudo chmod 755 example.com/
    sudo chown root:www-data example.com/
    sudo mv example.com/ /var/www/

Database Restoration on New Server:

  1. Restore the Database on the New Server:

    After transferring the backup file (backup.sql), restore it on the new server:

    mysql -u DB_USER -p DB_NAME < ~/backup.sql

Set Up MySQL for the First Time on the New Server

  1. Run the Secure Installation Script

    sudo mysql_secure_installation

    Follow the prompts to set the root password and secure your installation.

  2. Create a New Database and User

    Log into MySQL as the root user:

    sudo mysql -u root -p

    Then, create a new database and user:

    CREATE DATABASE wordpress;
    CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'secure_password';
    GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress_user'@'localhost';
    FLUSH PRIVILEGES;
  3. Check MySQL User Permissions

    Ensure that the DB_USER has the correct permissions:

    SHOW GRANTS FOR 'DB_USER'@'localhost';

Troubleshooting mysqldump Error (Access denied for user)

If you encounter an error with mysqldump such as:

mysqldump: Got error: 1045: Access denied for user 'DB_USER'@'localhost' (using password: YES) when trying to connect
  1. Verify MySQL User Permissions

    Log into MySQL:

    sudo mysql -u DB_USER -p

    Check the permissions:

    SHOW GRANTS FOR 'DB_USER'@'localhost';
  2. Reset MySQL User Password if Necessary

    If you forgot the password, log in as root and reset it:

    ALTER USER 'DB_USER'@'localhost' IDENTIFIED

BY 'new_password'; FLUSH PRIVILEGES;


3. **Ensure the Correct Password is Used with `mysqldump`**

When using `mysqldump`, avoid typing the password in the command:

```bash copy copy
mysqldump --no-tablespaces -u DB_USER -p DB_NAME > ~/export.sql

Enter the password when prompted.

Here’s how you can integrate the steps for migrating with minimum downtime into your existing Markdown documentation:

## **Guide to Migrating a WordPress Site to another Ubuntu 24.04 instance**
 
### **Initial Steps:**
 
1. **Update the Package List:**
 
   First, update and upgrade the packages on both the old and new servers:
 
   ```bash
   sudo apt update && sudo apt dist-upgrade -y

Install Required Packages on the New Server:

  1. Install Apache, MySQL, and PHP (LAMP stack):

    On the new server (DigitalOcean or AWS EC2):

    sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql php-xml php-mbstring php-curl -y

Setting Up Permissions for /var/www and Web Files:

Note
This section covers the recommended permissions setup for web directories and files on a Linux server, specifically for /var/www and /var/www/example.com. Ensure these permissions are applied during file migration and server setup to maintain security and proper functionality.


Permissions Setup for /var/www and /var/www/example.com:

  1. /var/www Directory:

    • Owner: root
    • Group: www-data
    • Permissions: 755

    Commands:

    sudo chown root:www-data /var/www
    sudo chmod 755 /var/www
  2. /var/www/example.com Directory:

    • Owner: www-data
    • Group: www-data
    • Permissions for directories: 755
    • Permissions for files: 644

    Commands:

    sudo chown -R www-data:www-data /var/www/example.com
    sudo find /var/www/example.com -type d -exec chmod 755 {} \;
    sudo find /var/www/example.com -type f -exec chmod 644 {} \;

Nginx Configuration:

  1. Add the Site to Nginx:

    You can either create a new config based on Chapter 3 or copy the existing configuration. It's recommended to copy the existing configuration for consistency. Also, if permissions need to be changed temporarily as we did earlier, you can do the same.

Migrating with Minimum Downtime

On busy sites, it's likely that the database will have changed since performing the previous export. To ensure data integrity, we need to prevent the live site from modifying the database while we carry out the migration. Follow these steps:

  1. Update the Live Site to Show a ‘Back Soon’ Message:

    Create a back-soon.html file with the following content:

    <!doctype html>
    <html>
        <head>
            <title>Back Soon</title>
            <style>
              body { text-align: center; padding: 150px; }
              h1 { font-size: 50px; }
              body { background-color: #e13067; font: 20px Helvetica, sans-serif; color: #fff; line-height: 1.5 }
              article { display: block; width: 650px; margin: 0 auto; }
            </style>
        </head>
        <body>
            <article>
                <h1>Back Soon!</h1>
                <p>
                    We're currently performing server maintenance.<br>
                    We'll be back soon!
                </p>
            </article>
        </body>
    </html>

    Save this as index.html, upload it to the web root of your old server, and update Nginx to serve this file instead of index.php:

    sudo nano /etc/nginx/sites-available/example.com

    Ensure that the index directive is set as follows:

    index index.html index.php;

    Reload Nginx to apply the changes:

    sudo service nginx reload

    Your live site will now display the ‘Back Soon’ message. Note that if you're using Nginx FastCGI caching, any cached pages will still be served from the cache, but requests to admin-ajax.php and the WordPress REST API will fail.

  2. Export the Live Database from the Old Server:

    Perform the database export as outlined in the previous sections.

  3. Import the Live Database to the New Server:

    Import the database backup to the new server as previously described.

  4. Switch the DNS to Point to the New Server:

    Update your DNS records to point to the new server's IP address. Be aware that DNS queries are cached, so some users might still be routed to the old server until their DNS cache expires.

    If

using Cloudflare or similar DNS providers, set a low TTL (e.g., 300 seconds) a few days before migration to expedite propagation.


Finishing Up

  1. Add a Unix Cron Job:

    Ensure that automatic backups are running as scheduled.

  2. Generate a New SSL Certificate Using Let’s Encrypt:

    Use the certbot command to generate a new certificate for your new server.

    sudo certbot --nginx -d example.com -d www.example.com
  3. Verify Everything is Working:

    • Test the site thoroughly.
    • Confirm that the new server handles traffic correctly and all functionalities are intact.

    Once everything is verified and working, you can remove the temporary ‘Back Soon’ page from your old server.

  4. Cleanup:

    Remove any temporary files or configurations used during migration:

    rm ~/example.com

    Update your Nginx configuration to reflect any permanent changes needed.

Important: Ensure you restore any original permissions or symbolic links if they were temporarily changed during the migration.

For AWS EC2 users, remember to adjust security groups to allow traffic on the appropriate ports (80 for HTTP, 443 for HTTPS).


Additional Note for AWS EC2 Users:

  • Instance Size: Ensure the instance has adequate resources for your site’s traffic.
  • Security Groups: Configure security groups to allow necessary traffic (HTTP/HTTPS).
  • Elastic IP: Use an Elastic IP to maintain a consistent IP address for your instance.