Migrating WordPress Install From Dreamhost to Linode

Migrating hosts has always been a tedious process for me, and I’ve often stayed on horrible hosting providers just because I’ve dreaded it. Linode (referral link) and similar providers at least have a wealth of information on how to set up your new hosts, but I still found myself jumping around a lot to remember how to do certain things. Hopefully, this post helps put (most) of the information in one place.

Experience level required: You have logged into your own Linux box and have done *something* useful.

Grabbing your content from Dreamhost

Login using the shell username associated with your domain name that you’re moving. Assume the domain name is example.com.

Grab the WordPress install complete with content using tar.

I’m using the domain name as part of the tar file name to keep things straight, but the name before the .tar file can be whatever works for you. (Note: you can be more surgical and just grab the content and have a fresh WordPress install, but then you’ll be chasing after even more loose ends.)

tar pcvf example.com.tar example.com

Dump your mysql database.

 

Open your wp-config.php for you domain and note your DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST.

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wp_example_com');
/** MySQL database username */
define('DB_USER', 'examplecom');
/** MySQL database password */
define('DB_PASSWORD', 'ASD9@!h12');
/** MySQL hostname */
define('DB_HOST', 'mysql.db.example.com');

Run the following mysqldump command line:

  • DB_NAME as the first argument
  • DB_HOST after the –host argument
  • DB_USER as the -u argument.
  • The -p argument will cause mysqldump to prompt you for a password.
  • Redirect output (> filename) to whatever file you want, but again, I’m using something like “domain.name.sql” for consistency and clarity in my move.
mysqldump wp_example_com –host mysql.db.example.com -u examplecom -p > example.com.sql

view raw
mysqldump command
hosted with ❤ by GitHub

Transfer your files down.

scp username@dreamhost_host_name:~/example.com.tar .
scp username@dreamhost_host_name:~/example.com.sql .

Sign Up for Linode

I’d appreciate you signing up through my referral link for Linode . I chose the Linode 2048 Standard Instance , Deployed an Ubuntu 16.04 LTS image to it, and started it up.

From there, you need to set up the LAMP stack. Note: these instructions will install PHP 7, and I found at least one plugin (Sociable?) that used deprecated calls in php and caused me a few 500 errors.

Add non-root user

Be sure to also follow Securing Your Server recommendations for automatic updates and such, but for our purposes:

adduser example_user
adduser example_user sudo

Upload Your Site to Linode

scp example.com.tar example_user@linode_instance_ip:~
scp example.com.sql example_user@linode_instance_ip:~

Enable .htaccess if you use any rewrites

/etc/apache2/apache2.conf (AllowOverride)  It’s possible you *don’t* need this if you have WordPress, but I haven’t had an install that didn’t.

<Directory /var/www/html/example.com/public_html/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

view raw
apache2.conf
hosted with ❤ by GitHub

Enable apache mods

sudo a2enmod ssl rewrite mpm_prefork

Add other PHP and related mods that your plugins may need

sudo apt-get install php7.0-mbstring

sudo apt-get install php7.0-gd sudo apt-get install php7.0-curl php7.0-json php7.0-cgi sudo apt-get install php7.0 php-pear libapache2-mod-php7.0 sudo apt-get install php7.0-mysql

Set up your virtual host

/etc/apache2/sites-available/example.com.conf

<Directory /var/www/html/example.com/public_html>
Require all granted
</Directory>
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin email@example.com
DocumentRoot /var/www/html/example.com/public_html
ErrorLog /var/www/html/example.com/logs/error.log
CustomLog /var/www/html/example.com/logs/access.log combined
</VirtualHost>

view raw
initial.vhost.conf
hosted with ❤ by GitHub

Create subdirs and set permissions properly

sudo mkdir /var/www/html/example.com

sudo mkdir /var/www/html/example.com/{logs,public_html} sudo chown -R www-data:www-data /var/www/html/example.com

Untar your content

Because of the way Dreamhost has their domain subdirectories set up, you’ll end up with two layers of example.com folders. (You could have also tarred from the folder, etc… but I just decided to keep this pattern.)

cd /var/www/html/example.com
sudo -u www-data tar xvf ~/example.com.tar .
cd example.com # from the tar file
sudo -u www-data mv .htaccess ../public_html
sudo -u www-data mv * ../public_html
ls -a # this should be empty now.
cd ..
pwd # be sure you're in /var/www/html/example.com
rm -rf example.com

Setup and Load Your DB

cd to the location of your sql dump.

CREATE DATABASE wp_example_com;
CREATE USER 'examplecom' IDENTIFIED BY '!@(87P@ss';
GRANT ALL PRIVILEGES ON wp_example_com.* TO 'examplecom';
USE wp_example_com;
SOURCE example.com.sql;

Change your wp-config.php for the DB setup

Your DB host is now localhost (unless you created a new DNS entry for your DB host)

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wp_example_com');
/** MySQL database username */
define('DB_USER', 'examplecom');
/** MySQL database password */
define('DB_PASSWORD', '!@(87P@ss');
/** MySQL hostname */
define('DB_HOST', 'localhost');

Enable your site

sudo a2ensite example.com

Add a DNS zone in Linode and change your DNS servers to point to Linode.

Add SSL

For more details start at “Install Let’s Encrypt to Create SSL Certificates

<Directory /var/www/html/example.com/public_html>
Require all granted
</Directory>
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost *:443>
SSLEngine On
# comment these three lines out
# sudo apache restart
# run letsencrypt
# sudo apache restart (reload seemed to get in a weird state)
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
ServerName example.com
ServerAlias www.example.com
ServerAdmin email@example.com
DocumentRoot /var/www/html/example.com/public_html
ErrorLog /var/www/html/example.com/logs/error.log
CustomLog /var/www/html/example.com/logs/access.log combined
</VirtualHost>

view raw
example.com-new.conf
hosted with ❤ by GitHub

I had to experiment a bit with the SSL configuration to get Let’s Encrypt to generate the keys and certs.

#first time setup only
sudo apt-get install git
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
# I had to restart apache with a stubbed *.443 section, do this, and then
# add the SSL* directives in.
sudo -H ./letsencrypt-auto certonly –standalone -d example.com

view raw
letsencrypt.sh
hosted with ❤ by GitHub

Lastly… I had to add renewal of the SSL certs to my crontab (sudo crontab -e)

0 0 1 * * /opt/letsencrypt/letsencrypt-auto certonly –quiet –standalone –renew-by-default -d example.com >> /var/log/letsencrypt/letsencrypt-auto-update.log

view raw
crontab
hosted with ❤ by GitHub