What’s the best way to deploy a PHP app onto Amazon’s EC2?

What's the best way to deploy a PHP app onto Amazon's EC2? by @scalr

Answer by Sebastian Stadil:

Deploying some code is easy and is addressed by Angus Li pretty well.

Where things get complicated is when you want to deploy new code that requires a new database schema, and perhaps a different version of php, mysql, or both, when you want to do it on hundreds or thousands of machines, and when you want to do it live.

Fortunately you are using Amazon EC2, so I have a few tricks for you. We thought about this pretty hard while designing the Deployments feature at SCALR, here's our analysis.

Deploying code

The first way of doing this is to update your existing servers. Simply replace your code directly, possibly via a pull / update request from your code repository, into your app directory.

This works in most cases, but if your application contains many new files (a large diff), then the update can take time during which your app might malfunction.

If so, simply put the new version in another directory and create a symlink (ln -s source_file link_name) to it. This method also gives you time to install any additional software / libraries that are dependencies of the new version. Just make sure you create the symlink after you are done installing stuff.

This method has its limits too, which are apparent when you have dependencies incompatible with your previous app version, like upgrading PHP (programming language) versions. To get around that, lets take a look at preparing environments.

Preparing the environment

There's a whole category of software called Configuration Management that helps you with preparing environments. Essentially, they let you write code that determines what an individual server should look like. My favorites are Chef (Ruby) and Puppet (DSL). This is waaay better than writing bash scripts, and really shines when the number of servers you have goes over 20.

(Scalr is integrated with Chef so you can assign runlists to be executed at instance start).

For smaller infrastructure these tools can be a bit overkill. An easier albeit less scalable method is simply to ssh into a server, make your changes, and take a snapshot into a new machine image. You then use this new image to create servers which will replace those of your previous image.

(in Scalr, you can remove a server from DNS to prepare it)

At scale, this method is possible with a few modifications, as the Netflix (product) engineering team has shown, which also doesn't have the open heart surgery constraints of operating on production infrastructure. Simply clone your entire setup (be careful to clone your data too). This is a new way of doing this that has been made possible thanks to Amazon Web Services.

(Scalr allows you to easily clone your infrastructure)

Once you have the clone, you can take your time and make any changes you want. If your new version doesn't require a different database schema, then you can additionally instruct your load balancer to send a portion of your traffic to the clone, while you carefully watch your error rates for any increase that would warrant a rollback of traffic.

Preparing the database

But lets say you do need to make a database schema update (ALTER TABLE). While this sounds easy, in practice it can get quite hard. First, it takes an increasing amount of time with your database size, and locks your table for the duration. Second, you'll have to coordinate that change across all the shards and read replicas you might have. Third, you run the risk of having a thread die in the middle of the update, leaving you in a broken state (PostgreSQL allows you to perform updates as a transaction, but MySQL still doesn't with 5.6).

As part of your deployment, you'll want to include a sql script that will make the desired changes to your schema. You have three options for this:

  1. Include the script in your application to be executed by it. This is easier since you already have the logic to connect to the database(s) with your password.
  2. Execute the script directly on the database servers. Gives you more control.
  3. Take a look at Facebook's OnlineSchemaChange at http://www.facebook.com/notes/mysql-at-facebook/online-schema-change-for-mysql/430801045932 for a seemingly great way to do this

Post-deploy monitoring

During that critical time that follows a deployment, you need to watch your monitors very carefully for increased error rates– avoid deploying right before leaving work. You'll also want to monitor resource consumption for possible memory leaks, infinite loops, and other recurring issues.

In case of disaster, you'll want to rollback. Depending on how extensively you changed the environment, this ranges from easy to bloody-murder-difficult. At worst, you might need to make a reverse schema change, revert to a previous machine image, and re-deploy your application.


The Scalr open source project has a feature called "Deployments" that helps you deploy code and manage the whole above process. This includes:

  • Deploying code from a repository
  • Running pre- and post- deploy scripts to prepare the environment
  • Replacing instances of an old machine image with instances of an updated one ("snapshot replace future").
  • Cloning entire setups
  • Configuring Chef runlists to be executed on instance initialization

I hope this helps you and perhaps future readers. If it does, please consider an upvote! If not, please suggest an edit.



What's the best way to deploy a PHP app onto Amazon's EC2?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s