Skip to content


The Amazon EC2 Blog Migration Project


I. Overview

This side project presents my procedure for migrating my WordPress blog from a web hosting provider running cPanel to an Amazon EC2 instance.

This project builds on the environment created in my previous blog post, “The Mobile Cloud Project, Part 1.1: Basic AWS”, where I presented an overview of Amazon Web Services and a procedure for creating virtual servers (Reserved and On-Demand instances) on Amazon EC2.


II. Consulting

I do my best to explain the concepts and techniques behind my projects. If you like my work and can use my expertise in your projects, I am available for consulting at a competitive rate.


III. Procedure

Once the Amazon EC2 instance was created and configured in my previous blog post, this migration procedure is actually fairly straightforward. From the point of view of a terminal console, an Amazon EC2 instance running Ubuntu Linux is very similar to any other Ubuntu server. The only difference is that certain tasks that were simplified behind a web hosting provider’s cPanel now need to be done explicitly on an EC2 instance.

This procedure assumes an existing WordPress blog at http://www.RayAcayan.com/blog (i.e. this blog), an existing EC2 instance running Ubuntu 9.10 (Karmic), an Elastic IP address associated with that instance, and a local Windows client with Putty and FileZilla configured to connect to both the old blog’s web hosting provider and the new blog’s EC2 instance. These were all configured in my previous blog post “The Mobile Cloud Project, Part 1.1: Basic AWS”.

1. Install packages on EC2 instance

  1. Connect to the EC2 instance using Putty.
  2. Install Apache2, MySQL, PHP, Ruby on Rails, Python, and Django packages with the following commands.
  3. $ sudo apt-get update
    $ sudo apt-get install apache2 mysql-server libapache2-mod-auth-mysql
    $ sudo apt-get install php5-mysql phpmyadmin
    $ sudo apt-get install build-essential libssl-dev libreadline5-dev zlib1g-dev
    $ sudo apt-get install libmysqlclient15-dev

    $ sudo apt-get install ruby-full rubygems1.9.1 rails libmysql-ruby

    $ sudo apt-get install python2.6 python3 python-django
    $ sudo apt-get install libapache2-mod-python python-mysqldb

2. Enable mod_rewrite on Apache

  1. The mod_rewrite module allows WordPress to use pretty permalinks on your blog, such as /category/postname/
  2. $ sudo a2enmod rewrite
    $ sudo nano /etc/apache2/sites-enabled/000-default
  3. Modify this file to show the following changes (i.e. change “None” to “All” to allow pretty permalinks, and add # comments to disable directory listing) then save this file.
  4. DocumentRoot /var/www/
    [...]
    Options FollowSymLinks
    AllowOverride All
    [...]
    # Options Indexes FollowSymLinks MultiViews
    # AllowOverride None
    # Order allow,deny
    # allow from all
  5. Restart Apache:
  6. $ sudo /etc/init.d/apache2 restart

3. Install WordPress on the EC2 instance

  1. Connect to the EC2 instance using Putty.
  2. Create the WordPress username and database on MySQL by entering the following commands:
  3. $ sudo mysql -u root -p <password>
    mysql> create database wordpress;
    mysql> create user <wp_username>;
    mysql> set password for <wp_username> = password(”<password>”);
    mysql> grant all on wordpress.* to <wp_username>@localhost identified by `<password>’;
    mysql> quit
  4. Enter the following commands at the Linux prompt to download and install WordPress:
  5. $ cd /var/www/blog
    $ sudo wget http://wordpress.org/latest.tar.gz
    $ sudo tar -xzvf latest.tar.gz
    $ sudo mv wordpress blog
  6. Go to http://<elastic ip>/blog/wp-admin/install.php to execute the WordPress install script.
  7. Download and install the WordPress themes and plugins that were in the previous blog (cPanel).

4. Copy WordPress files and database from the old blog to the new blog

  1. Open FileZilla client and connect to the web hosting provider’s server that is hosting the old blog. (See the provider’s instructions on how to do this.)
  2. Download all files in the old blog: ~/public_html/blog or /var/www/blog
  3. Open a second FileZilla client to connect to the new blog (EC2).
  4. Upload your custom files and directories to the /var/www/blog directory of the new blog.
  5. Make sure that you have also copied any hidden files (.htaccess) from the old blog to the new blog.
  6. Open the WordPress Dashboard on the old blog (cPanel), click “Export” in the “Tools” menu on the left, and save the .xml file.
  7. Open the WordPress Dashboard on the new blog (EC2), click “Import” in the “Tools” menu on the left, and upload the .xml file from the previous step.
  8. Install the “WP-DB-Backup” plugin on both the old and new blogs.
  9. On the old blog’s WordPress admin, click “Backup” on the “Tools” menu on the left and save the file as “oldwordpress.sql”.
  10. Connect to the EC2 instance via FileZilla and upload the “oldwordpress.sql” file.
  11. Connect to the EC2 instance via Putty.
  12. At the Linux prompt, enter “mysql wordpress < oldwordpress.sql –u root -p” to import the old WordPress database to the new one.
  13. Verify that the new blog is working at http://<elastic ip>/blog including links and styles.

5. Remap DNS to the new blog IP address on EC2

  • DNS needs to be configured to remap the blog’s domain name to the Elastic IP address of the new blog on EC2.
  1. Before proceeding, add an entry “<elastic ip> www.RayAcayan.com” to the local hosts file at C:\windows\system32\drivers\etc
  2. Verify that the blog is working properly using the normal URL http://www.RayAcayan.com
  3. At this point, only the local computer can access the new blog via URL because of the hosts file entry. The new IP address will need to be propagated to the rest of the Internet via an external DNS provider so that everyone else can access it.

  4. Select an external DNS provider such as http://www.easyDNS.com and purchase a DNS-only service for about $20/year.
  5. Add a DNS entry to map the hostname to the Elastic IP address of the new blog.
  6. Go to the domain registrar’s website where the old blog domain is currently registered.
  7. Change the name servers of the domain to point to the name servers of the external DNS provider.
  8. Wait several hours for the new DNS settings to propagate on the Internet. Enter “nslookup” at the command prompt. If the response is the elastic IP address of the EC2 instance, then the DNS propagation has completed.
  9. Remove the hosts file entry created in step 5.i. and run “ipconfig /dnsflush” at the command prompt. Verify that the blog is still reachable via the normal URL: http://www.RayAcayan.com/blog

6. Install Additional Applications

  1. Install Webalizer

  2. Webalizer is a web stats application offered by your web hosting provider’s cPanel. You will need to install it manually on your EC2 instance if you want to continue using it.

    1. Connect to the EC2 instance using Putty.
    2. Enter the following command to install and configure Webalizer on the EC2 instance:
    3. $ sudo apt-get install webalizer
      $ sudo nano /etc/webalizer/webalizer.conf
      Change the text “LogFile /var/log/apache2/access.log.1″ to “LogFile /var/log/apache2/access.log” then save the webalizer config file.
    4. Create a cron job to run webalizer every 30 minutes:
    5. $ sudo crontab -e
      (Add the following line to the crontab:)
      30 * * * * /usr/bin/webalizer

7. Configure Basic Security

  1. Secure the Apache web server with mod_security and Core Rule Set
  2. The “mod_security” Apache module is an open source intrusion detection and prevention engine for web applications. It protects the Apache web server from common attacks such as SQL injection, cross-site scripting, etc.

    1. Connect to the EC2 instance using Putty.
    2. Enter the following commands at the Linux prompt:
    3. $ sudo mkdir ~/install
      $ cd ~/install
      $ sudo wget http://www.modsecurity.org/download/modsecurity-apache_2.5.10.tar.gz
      $ sudo tar –xzvf modsecurity-apache_2.5.10.tar.gz
      $ cd modsecurity-apache_2.5.10/rules
      $ sudo cp *.conf /etc/apache2/conf.d
      $ sudo cp base_rules /etc/apache2/conf.d/modsecurity
      $ sudo cp optional_rules /etc/apache2/conf.d
      $ sudo mkdir /etc/apache2/logs
      $ sudo apt-get install libapache-mod-security
      $ sudo a2enmod mod-security
    4. Restart Apache:
    5. $ sudo /etc/init.d/apache2 restart

  3. Configure password-protection on the PHPMyAdmin directory
    1. Connect to the EC2 instance using Putty.
    2. Enter the following commands at the Linux prompt:
    3. $ sudo mkdir /usr/local/apache2
      $ sudo htdigest -c /usr/local/apache2/.htpasswd_phpmyadmin “PHPMyAdmin” phpmyadmin
      (Enter password)
      $ sudo cp /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled
      $ sudo nano /etc/apache2/apache2.conf
    4. Add the following text to the end of the apache2.conf file then save it:
    5. <Directory /usr/share/phpmyadmin/>
        Authtype digest
        AuthName “PHPMyAdmin”
        AuthUserFile /usr/local/apache2/.htpasswd_phpmyadmin
        require user phpmyadmin
      </Directory>
    6. For added security, insert the following lines inside the <Directory> tag above to only allow connections from certain IP addresses:
    7.   Order deny,allow
        Deny from all
        Allow from <static IP address>
    8. Restart Apache:
    9. $ sudo /etc/init.d/apache2 restart

  4. Configure password-protection on the WordPress Admin directory
    1. Connect to the EC2 instance using Putty.
    2. Enter the following commands at the Linux prompt:
    3. $ sudo mkdir /usr/local/apache2
      $ sudo htdigest -c /usr/local/apache2/.htpasswd_wp-admin “WordPress Admin” wp-admin
      (Enter password)
      $ sudo cp /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled
      $ sudo nano /etc/apache2/apache2.conf
    4. Add the following text to the end of the apache2.conf file then save it:
    5. <Directory /var/www/blog/wp-admin/>
        Authtype digest
        AuthName “WordPress Admin”
        AuthUserFile /usr/local/apache2/.htpasswd_wp-admin
        require user wp-admin
      </Directory>
    6. For added security, insert the following lines inside the <Directory> tag above to only allow connections from certain IP addresses:
    7.   Order deny,allow
        Deny from all
        Allow from <static IP address>
    8. Restart Apache:
    9. $ sudo /etc/init.d/apache2 restart

  5. Configure password-protection on the Webalizer directory
    1. Connect to the EC2 instance using Putty.
    2. Enter the following commands at the Linux prompt:
    3. $ sudo mkdir /usr/local/apache2
      $ sudo htdigest -c /usr/local/apache2/.htpasswd_webalizer “Webalizer Stats” webalizer
      (Enter password)
      $ sudo cp /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled
      $ sudo nano /etc/apache2/apache2.conf
    4. Add the following text to the end of the apache2.conf file then save it:
    5. <Directory /var/www/webalizer/>
        Authtype digest
        AuthName “Webalizer Stats”
        AuthUserFile /usr/local/apache2/.htpasswd_webalizer
        require user webalizer
      </Directory>
    6. For added security, insert the following lines inside the <Directory> tag above to only allow connections from certain IP addresses:
    7.   Order deny,allow
        Deny from all
        Allow from <static IP address>
    8. Restart Apache:
    9. $ sudo /etc/init.d/apache2 restart

 

IV. References

1. Amazon Web Services Technical Documentation
http://aws.amazon.com/documentation

2. Official Ubuntu Documentation
https://help.ubuntu.com

3. RubyOnRails.org
http://rubyonrails.org/download/

4. Python Programming Language — Official Website
http://www.python.org

5. The Django Project
http://www.djangoproject.com/

6. Moving WordPress
http://codex.wordpress.org/Moving_WordPress

7. easyDNS
http://www.easydns.com

8. OWASP ModSecurity Core Rule Set Project
http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project




0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.