Hosting WordPress Application on an EC2 Instance – AWS

In this post, we will deploy WordPress Application on an EC2 Amazon Linux AMI t2.micro instance following below steps:

Step 1: Set up Amazon EC2 instance following set-up-amazon-ec2-instance.

Step 2: Launch an EC2 instance following ec2-launch-linux-instance.

Step 3: As creating a wordpress application is not a part of this post, I already created one and zipped it as wordpress-app.zip which we will securely copy from local machine to an EC2 instance home directory (/home/ec2-user) using ec2-user as follows:

scp -i /Users/ArpitAggarwal/arpitaggarwal-key-pair.pem /Users/ArpitAggarwal/wordpress-app.zip ec2-user@ec2-54-218-30-7.us-west-2.compute.amazonaws.com:/home/ec2-user

arpitaggarwal-key-pair.pem refers to private key file.
ec2-54-218-30-7.us-west-2.compute.amazonaws.com refers to Public DNS name of EC2 instance.

Step 4: Export wordpress-app database, as follows:

cd /applications/MAMP/library/bin
./mysqldump -u root -p**** wordpress > /Users/ArpitAggarwal/export-wordpress-data.sql

/applications/MAMP/library/bin refers to MAMP local database store.
./mysqldump referes to command to get mysqldump.

Step 5: Copy export-wordpress-data.sql we created from local machine directory to EC2 instance home (/home/ec2-user) directory:

scp -i /Users/ArpitAggarwal/arpitaggarwal-key-pair.pem /Users/ArpitAggarwal/export-wordpress-data.sql ec2-user@ec2-54-218-30-7.us-west-2.compute.amazonaws.com:/home/ec2-user

Step 6: Login to your EC2 instance with private key file and Public DNS name using ssh:

ssh -i /Users/ArpitAggarwal/arpitaggarwal-key-pair.pem ec2-user@ec2-54-218-30-7.us-west-2.compute.amazonaws.com

Step 7: Change collation of your database by executing following commands in /home/ec2-user after login to an EC2 instance:

sed -i 's/utf8mb4/utf8/g' export-wordpress-data.sql
sed -i 's/utf8_unicode_ci/utf8_general_ci/g' export-wordpress-data.sql
sed -i 's/utf8_unicode_520_ci/utf8_general_ci/g' export-wordpress-data.sql

Step 8: Set up Linux, Apache, MySQL, PHP (LAMP) stack on an EC2 CentOS 6 instance and set the processes to run automatically when the server boots, executing below commands:

sudo yum install httpd
sudo yum install mysql-server
sudo yum install php php-mysql
sudo service mysqld start
sudo chkconfig httpd on
sudo chkconfig mysqld on

Step 9: Set a root MySQL password same as you have provided in your wordpess-app, executing below command and choosing specific option for all the prompt:

sudo /usr/bin/mysql_secure_installation

Step 10: Login to MySQL database on an EC2 instance and create DATABASE same as you have provided in your wordpess-app, for me it’s wordpress:

mysql -u root -p****
mysql> CREATE DATABASE IF NOT EXISTS wordpress;

Step 11: Import export-wordpress-data.sql to newly created database, as follows:

mysql -uroot -p**** wordpress < export-wordpress-data.sql

Step 12: Inflate wordpress-app.zip, Copy all the files to /var/www/html directory and create .htaccess file inside the same directory:

unzip wordpress-app.zip
sudo cp -R wordpress-app/* /var/www/html
cd /var/www/html
sudo touch .htaccess

Replace the content of .htaccess file with below:

# BEGIN WordPress
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Step 13: Edit httpd.conf placed in /etc/httpd/conf to set value of AllowOverride directive to All for the /var/www/html directory, as below:

<Directory "/var/www/html">
  Options Indexes FollowSymLinks
  AllowOverride All
  Order allow,deny
  Allow from all
</Directory>

Step 13: Restart apache to reflect all of the changes we did:

sudo service httpd restart

Now, access the wordpress-app from your browser using Public DNS name or Public IP of your EC2 instance as: http://ec2-54-218-30-7.us-west-2.compute.amazonaws.com/

Need to move WordPress site to a new Host?

It can be easily done by updating the option_value, post_content and guid of the application directly in the MySQL database executing below scripts:

UPDATE wp_options SET option_value = 'http://new-host/' WHERE option_name = 'home';
UPDATE wp_options SET option_value = 'http://new-host/' WHERE option_name = 'siteurl';
UPDATE wp_posts SET post_content = REPLACE(post_content,'http://old-host/','http://new-host/');
UPDATE wp_posts SET guid = REPLACE(guid,'http://old-host/','http://new-host/');
Advertisements

Running Web Application in Linked Docker Containers Environment

In post Dockerizing Web Application with Puppet we hosted web application in a single container, this time we will host a web application in a linked docker container environment – one in which our database (mysql) resides leveraged by our web application hosted in another docker container.

Before start, let’s have a brief about Linking Docker containers and how it helps us.

Linking or connecting Docker containers?
Linking Docker containers allows containers to discover each other and securely transfer information between them. Linking set up a conduit between containers allowing recipient container securely access source container preventing exposing the source container to the network.

In this post, recipient container is the spring-application-container which we created in this post and source container is the database container which we create now.

Let’s start with creating database container and linking it with  spring-application-container, following below steps:

Step 1: Create directory with any name for me it’s database-container inside directory docker (created in this post), as follows:

$ cd docker
$ mkdir database-container
$ cd database-container
$ touch Dockerfile

Step 2: Copy the below content in docker/database-container/Dockerfile:

FROM ubuntu:latest
MAINTAINER arpitaggarwal "aggarwalarpit.89@gmail.com"
RUN apt-get install -q -y mysql-server
RUN apt-get install -q -y mysql-client
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
EXPOSE 3306

RUN sed -i -e”s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/” /etc/mysql/my.cnf specified above is to set the MYSQL bind-address to 0.0.0.0 because it usually only listens on 127.0.0.1 by default.

Step 3: Build the newly created database-container as follows:

$ cd database-container
$ docker build --no-cache=true -t database .

database specified above refers to name of a database-container image.

Step 4: Start database-container assigning a name “db” and MYSQL Server installed as a service inside database-container, as follows:

$ docker run -P -it --name db database /bin/bash

Step 5: Modify the existing spring-application-container Dockerfile to copy the new application to the container which is using database hosted on database-container, as follows:

FROM ubuntu:latest
MAINTAINER arpitaggarwal "aggarwalarpit.89@gmail.com"
RUN apt-get -y update
RUN apt-get -q -y install git
RUN sudo apt-get install -y ruby
RUN apt-get install -y ruby-dev
RUN apt-get -y update
RUN apt-get install -y make
RUN apt-get install -y build-essential
RUN apt-get install -y puppet
RUN gem install librarian-puppet
ADD Puppetfile /
RUN librarian-puppet install
RUN puppet apply --modulepath=/modules -e "include java8 class { 'tomcat':version => '7',java_home => '/usr/lib/jvm/java-8-oracle'}"
RUN apt-get remove -y make puppet build-essential ruby-dev
COPY /spring-mysql/target/spring-mysql.war /var/lib/tomcat7/webapps/
EXPOSE 8080

Step 6: Build the the application inside a docker directory, this time spring-mysql cloned from github:


$ cd docker
$ git clone https://github.com/arpitaggarwal/spring-mysql.git
$ cd spring-mysql
$ mvn clean install

Step 7: Next, start spring-application-container linking it with database-container as follows:

$ docker run -p 8080:8080 -it --name webapp --link db spring-application-container /bin/bash

–link flag specified above create a secure link between spring-application-container with the database-container and exposes connectivity information for the source container to the recipient container in two ways:

a). Environment variables.
b). Updating the /etc/hosts file.

Now we can use exposed environment variables or the entries from host to access the db container. Also, If we restart the source container, the linked containers /etc/hosts files will be automatically updated with the source container’s new IP address, allowing linked communication to continue.

In our application, we used the host entry mechanism to read the IP address of source container, using Java InetAddress.

Step 8: Our application will try to access the mysql database with user as “test” and password as “test” and use the employee table to store the employee details submitted from applicationso let’s create it:

$ mysql --user=root mysql
$ CREATE USER 'test'@'%' IDENTIFIED BY 'test’;
$ GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION;
$ FLUSH PRIVILEGES;
$ CREATE DATABASE  test;
$ USE TEST;
$ CREATE TABLE employee (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), age VARCHAR(30));

Step 9: Get your Docker container IP Address, using docker-machine:

docker-machine ip your_vm_name

Next, create employee submitting name and age from application and refresh the screen to retrieve it from database at url http://container-ip-address:8080/spring-mysql

The complete source code is hosted on github.