Tags
Src: https://www.otreva.com/blog/deploying-wordpress-amazon-web-services-aws-ec2-rds-via-elasticbeanstalk/
A common question we get asked is how do I ensure my WordPress application can scale with an influx of demand? What can I do do ensure high uptimes and great performance?
As a member of the AWS Partner Network, our typical response is to build an auto-scaling, self healing cloud application using AWS ElasticBeanstalk. AWS Elastic Beanstalk is an even easier way for you to quickly deploy and manage applications in the AWS cloud. You simply upload your application via GIT, and Elastic Beanstalk automatically handles the deployment details of capacity provisioning, load balancing, auto-scaling, and application health monitoring. But at the same time, you retain full control over the AWS resources powering your application and can access the underlying resources at any time via ElasticBeanstalk.
Sounds great right? We think so too.
The one consideration is that users have to understand the need for their application to be stateless. This means you can no longer upload photos to the server itself, you can’t install plugins on the server, and you don’t want anything to change on the server without it first being changed locally via your GIT repository. Luckily, there are a few plugins to help ease this pain, and they allow you to still use the default WordPress media uploader and browser yet instead of storing media on the server, you can configure an AWS S3 (Simple Storage Service) bucket to retain all the images off the server.
So why is stateless so important?
Auto-scaling, self-healing applications rely on this single understanding of stateless design. The reason an application must be stateless is because if it needs to scale up (add more servers behind it), it cannot be inconsistent between server instances. The application code on server instance A must be exactly the same as server instance B. This is why your repository should only contain your base PHP files, theme files, plugins and basic WordPress application files. Media like images, videos and PDFs should NEVER be kept in your GIT repository unless they are needed for your theme. So for example if you have a background image that is used throughout the site, that may be an exception that can live in your theme’s image folder inside the GIT repository. However images that go in blog posts, pages, etc should be hosted on a storage service like AWS S3. Once we upload the images to S3, we get a URL back that can live in the database which would be shared by all instances that are deployed. There are many more considerations to stateless application design which are outside the scope of this post.
Prerequisites:
- An AWS Account with Billing Setup
- GIT – Version Control System
- MySQL WorkBench (if migrating database – Not needed for fresh install)
- WordPress Install on Local Web Server
- WordPress wp-config.php file
- AWS ElasticBeanstalk command line tool
Step 1: Setup Local Web Server
This tutorial assumes you know how to install WordPress locally on your machine via a local web server like XAMPP, MAMP, LAMP or other apache based server. So once you have a folder setup and your files ready to be accessed by your local web server (localhost) you will be ready to proceed from here.
Copy all of the WordPress files into your local folder so they’ll be ready to be accessed by your local web server. Don’t setup a local database. At the time of this writing, we’re install WordPress 3.6.1. If you’ve done everything correctly so far, you should be able to access your files and see a screen like this:
Step 2: Configure AWS ElasticBeanstalk and WordPress for the Cloud
If you made it here, great. The next few steps will be slightly different from the typical WordPress install so try not to deviate.
Config AWS ElasticBeanstalk
- Login to your AWS Account and go to ElasticBeanstalk and click Create Application which should bring you to a screen similar to below. Name your application here:
- Next, select PHP as your platform and leave the environment type as Load Balancing, Autoscaling.
- Leave sample application selected for now:
- Give your environment a different name if you want and change the subdomain if you want and check the availability. We will later be creating a CNAME in your DNS for the Environment URL so it isn’t a huge deal for what you name it. It won’t be a public URL.
- Ensure you check create an RDS DB instance.
- The default settings on this page are probably fine for most installs and they can all be updated later so we won’t go into detail about them for now.
- Next we’ll need to configure our MySQL database here. Again most of the default values are OK to start and you can always update them later. Most WordPress sites we see need a database well below the 5GB minimum but it is a minimum for AWS RDS so use 5GB unless you have a larger database. Also pick a very secure username and password here and save them for the later steps. You can also pick multiple availability zones if this is an enterprise application that needs to ensure 100% uptime but be aware costs will tip $50 a month for DB usage only.
- Lastly, review everything and create the app. You should see a screen like below. Wait until the environment health is green to proceed to the next steps.
- Next, in the AWS console, go to Services > RDS. Since this is likely your first AWS RDS DB, you should be able to click security group on the left and see only one security group that looks something like “awseb-e-xxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx”. Edit that security group. You should see a best estimate of your IP Address that Amazon gives you in the small text in the yellow box. Enter that or your correct IP Address with subnet mask. This allows our local WordPress app to access our AWS RDS Cloud Database. We will be sharing one database between our local and AWS EC2 Cloud Environment for this tutorial.* Note: VPC Users Setup Security Differently
- Now while still in the RDS console, switch back to instances and copy the Endpoint field WITHOUT :3306. We’ll want this endpoint URL as well as the username and password we created above for the WordPress install. Also note the Database Name which is normally ebdb.
Step 3: Install WordPress
- Switch back to your browser and go to your configuration. We are now ready to create a configuration file.
- Fill in the database name as found in the RDS console, which is normally ebdb, the endpoint from above as Database Host (remember without :3306) as well as the username and password you created. You can leave the prefix as wp_.
- Now click install and you should be up and running! Finish the install just as any other WordPress Install
- But wait, we’re only halfway done!
Step 4: Local WP Conifg and GIT Repository setup
- Create a new file: local-config.php and put it in the root folder where wp-config.php is. Make sure to change to whatever your local hostname is below where you can access your install.
1
<?php define(
'WP_HOME'
,
'http://localhost/elasticbeanstalk'
); define(
'WP_SITEURL'
,
'http://localhost/elasticbeanstalk'
); ?>
- Open wp-config.php to edit. Add the following code just before define(‘DB_NAME’, ‘ebdb’); This allows us to browse our local code under our local hostname while still using a remote database. This step is very important.
123
if
(
file_exists
( dirname(
__FILE__
) .
'/local-config.php'
) ) {
include
( dirname(
__FILE__
) .
'/local-config.php'
);
}
- Create another file called .gitignore in the same location (root). This file will allow us to ignore files from our GIT repository that we need locally but that we don’t want in the repo.
12345678910111213141516171819202122
#################
## WordPress
#################
.git-rewrite/
local-config.php
.elasticbeanstalk/
*.local.*
*.remote.*
*.base.*
*.backup.*
*.orig*
#ElasticBeanstalk Configs we won't need in the repo
AWSDevTools/
AWSDevTools-OneTimeSetup.bat
AWSDevTools-RepositorySetup.bat
scripts/
AWSDevTools-RepositorySetup.sh
#These are to ignore media files which we again DON'T want in our GIT Repo.
wp-content/uploads/
wp-content/cache/
Step 5: Initialize your GIT repo
This assumes you already have GIT setup on your local machine.
- From the command line, CD to your local folder where all the website files are and make sure you are in the root where the wp-admin, wp-content, wp-includes folders are.
1
git init
- Add all the local WP Files to a GIT Repository. Note git will automatically ignore the files we put in our .gitignore file above.
1
git add *.*
- Finally commit them to the GIT Repository.
1
git commit -m
"Committing my initial WordPress site into this repo"
Step 6: Push this site up to AWS Beanstalk
Now we finally have our local site in our local GIT Repository and we’re ready to push it up to ElasticBeanstalk to make the site live. You should probably read this first to get a better understanding of what we’re about to do. We’re going to use a slightly slimmed down version of the above to help you get going.
- Create a folder in the root of our site called .elasticbeanstalk. Inside that folder we’ll make two files.
- config
123456
[
global
]
ApplicationName=YourApplicationNameFromAWSConsole
AwsCredentialFile=.elasticbeanstalk/aws_credentials
DevToolsEndpoint=git.elasticbeanstalk.us-east-1.amazonaws.com
EnvironmentName=EnvironmentNameFromAWSConsole
Region=us-east-1
- aws_credentials
These come from your AWS Console Account. Create a new user under IAM Console to get these:123[
global
]
AWSAccessKeyId=AKIAxxxxxxxxxxxxxxxxxxxxx
AWSSecretKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- config
- Go and download the AWS command line tools. Then copy the content inside the Windows folder of that download to your root folder where WP lives. If on Linux or OSX, use that folder instead.
- Add and commit everything we just did to the GIT Repository.
1
git add *.*
1git commit -m
"Adding AWS Configs"
- Finally let’s push the Repo up to Beanstalk.
1
git aws.push
- If all went well, you should be able to see the environment updating inside the AWS Console.
Done! Well with the deploy process.
Now your basic WordPress application is up on AWS but keeping it stateless means you must always install plugins locally, make changes locally to theme files, and otherwise change the sources code in the repo locally and then add, commit and push to AWS. However it allows us to use the power of AWS cloud infrastructure to create self-healing, auto-scaling apps. Although out of the context of this article, you can easily use plugins like Amazon S3 and CloudFront along with Amazon Web Services to send your media files to S3 and keep your codebase free of media. Upload the later plugin first.
Good luck and feel free to leave comments below with questions. If you’ve never installed WordPress on a basic shared server or local server, you may not want to attempt this until you have done that.