Deploying Rails 3.1 Applications to Engine Yard Cloud
Note: This guest post hails from Michael Latta of TechnoMage. TechnoMage has been building software systems for over 30 years. They focus on complex web development projects and iOS application development. TechnoMage is also an Engine Yard partner.
New Projects
If you are creating a new project starting with Rails 3.1, there is not much to worry about that is new. The main questions are the same, but the considerations are a bit new:
- Which test framework?
- Which database?
- Which js framework?
- Coffescript or not?
- Sass or not?
Existing Projects
You have already made all the above decisions for existing projects, but you may want to consider changing some based on the same considerations, so read on.
##Asset Pipeline Many of the updates in Rails 3.1 work together to provide a faster and more effective application. The core of this is the asset pipeline. And it has one of the largest impacts on operations and deployment of Rails 3.1 apps.
If you were an early adopter of Rails 3.1 on Engine Yard Cloud and added deploy hooks to precompile your assets, you will need to remove them as the Engine Yard recipes now do this for you and use a shared directory to hold current and previous deployment assets. This is to allow live deployment with Unicorn to survive the transition. There are new deploy hooks to allow you to synchronize any custom logic with the asset deployment process.
The new recipes place all compiled assets in the shared/assets directory and symlinks them to the project directory. This allows the symlink to be changed to ‘last_assets’ during the deployment process to keep the prior deployment live in the case of overlapping Unicorn deployment. The new hooks are ‘before_compile_assets’ and ‘after_compile_assets’.
Assets are compiled into their final form during deployment and their file names reference the hash computed at this time. See the following section on CoffeeScript, jQuery, Sass, and ERB for some comments on the changes you need to deal with in referencing your assets in this new world.
##Query Optimizations and PostgreSQL
A large performance enhancement is part of Rails 3.1 in the use of prepared queries. In MySQL unfortunately, this does not generate much benefit as the implementation in MySQL is sub-par. In PostgreSQL it is a significant improvement. If this is a new project you may want to use --database=postgresql
; you will need PostgreSQL installed on your development machine.
Streaming
When using Unicorn in Engine Yard you can take advantage of the http streaming support in Rails 3.1. This allows the response headers and body to be deliver before the response is fully formed. In particular for assets such as images this can be a significant response time difference, and you can see images load top to bottom in Safari which is a bit cool on its own. if you are delivering even larger assets like video or large documents this is a must have feature, and will influence your choice of app server.
Migrations
There are really no deployment impacts from the change in migration syntax, the main advantage is to developers during development.
Coffescript, jQuery, Sass, and ERB
With Rails 3.1 the asset pipeline defaults to supporting CoffeeScript, jQuery and Sass in generated assets and in the Asset Pipeline. You do not need to use CoffeeScript, you can rename the files to .js and stay with raw javascript, and similarly use .css for raw css files.
One of the more critical aspects of using the Asset Pipeline is that references to assets have changed. You can no longer just use the file name of the asset as in ‘image_tag “test.png”’ you need to account for the compiled asset name which is computed using a hash at deployment time. There is a new helper method ‘asset_path’ which will generate the correct path when building the request. But, since this is a Rails helper method you need to pass the assets like Sass or CSS or js or coffee files through ERB to do the path creation at request time. The asset compile process supports this as well so it is not being processed on every request (except in development). Add .erb to the file name extensions and the asset pipeline will do the right thing passing the source file through ERB then to the next pre-processor and the next as needed. See the Rails 3.1 Release Notes for more. While ordinary file references do work in the Engine Yard environment (because the files are copied to the assets directory as well as being compiled), their use is less desirable as you do not get browser cache activity based on content like you do with hash based names.
If you choose to use the new pre-processors you will get compiled assets for the generated files (css, js). One of the large benefits of this approach is that you end up with one compressed asset file for all your styles and js rather than a bunch of separate asset files. This provides more efficient caching and fewer browser round trips to load assets, affording faster page load times when combined with request streaming.
The following css example places the rails icon to the left of the element with .header
class. The path to the asset is computed using ERB to reference the hash based file name created at deploy time.
.header {
background-image: url('< %= asset_path 'rails.png' %>');
background-repeat: no-repeat;
padding-left: 60px;
}
Deploying on Engine Yard Cloud
As of this writing PostgreSQL support on Engine Yard is in beta so you will need to sign up for that feature if you wish to use that database for your Rails 3.1 application and the prepared statement support. If you enabled PostgreSQL support you will have the option under create or edit environment to select the database stack you wish for your environment. Note that it is not the application but the environment that selects the database stack. Your rails application does not need modification to change databases, because Engine Yard generates the database.yml at deploy time. You will need the appropriate gem in your gemfile, and can in fact have both MySQL and PostgreSQL gems referenced (mysql2 and pg).
You create an application as usual with the Engine Yard Cloud web interface indicating it is a Rails 3 application. Then create the desired environment options (Unicorn if you wish to use streaming). If you use Unicorn be sure to have the Unicorn gem in your gemfile as Unicorn will only use gems from the gemfile not from the system. Then boot your desired instance or cluster.
Deploy Something
In summary, Rails 3.1 is here and relatively painless to use with Engine Yard Cloud. The main features of 3.1 yield better performance, better structure, and more efficient applications. Moving to 3.1 is highly recommended. Even if you are not ready to deploy your production app to Rails 3.1 get to know it, kick the tires, and deploy something.
Share your thoughts with @engineyard on Twitter