About the Celadon Cedar Stack
Table of Contents
Cedar is a runtime stack on Heroku, and is the successor to Bamboo.
Supported Languages and Frameworks
Ruby
Node.js
Clojure
Java
- Java on Cedar getting started guide
- Spring MVC Hibernate on Cedar getting started guide
- Play! on Cedar getting started guide
Python
Scala
Stack Software Versions
- OS: Ubuntu Server 10.04 (Lucid Lynx)
- Ruby: MRI 1.9.2
- Bundler: 1.1pre5
- Node.js: 0.4.7
- NPM: 1.0.6
- JVM: OpenJDK 6
Using Cedar
To create an app on the Cedar stack, use the --stack argument:
$ heroku create --stack cedar
Make sure you’re running version 2.1.0 or higher of the Heroku command-line tool to access the run and scale commands:
$ heroku update
Differences Between Bamboo and Cedar
Procfile for flexible process types
Cedar introduces a new way to think about scaling your app: the process model. This is a natural extension of the dynos/workers model available on the Bamboo stack, but generalized to allow you to use your own custom list of process types, specified in a Procfile.
This covers use cases such as running Resque instead of Delayed Job, using a clock process like resque-scheduler or clockwork, and using a webserver other than Thin (such as Goliath).
Read more about developing apps with Procfile and Foreman, and deploying to Heroku/Cedar.
One-off processes for rake and console
On Bamboo, heroku rake and heroku console were implemented as special-cased execution paths, with output delivered over HTTP. This approach has a number of weaknesses, such as timeouts and non-interactivity on rake tasks.
Cedar uses the heroku run command to launch one-off processes like rake and the irb attached to your terminal via a TCP character connection. For example, using it to run rake commands:
$ heroku run rake db:migrate
Running `rake db:migrate` attached to terminal... up, ps.1
(in /app)
Migrating to CreateWidgets (20110204210157)
== CreateWidgets: migrating ==================================================
-- create_table(:widgets)
-> 0.0120s
== CreateWidgets: migrated (0.0121s) =========================================
And for an interactive console to your Rails app:
$ heroku run console
Running `console` attached to terminal... up, ps.2
Loading production environment (Rails 3.0.3)
irb(main):001:0>
The console is a standard irb shell (invoked via rails console), fully isolated from your web dyno.
New HTTP stack (herokuapp.com)
On Cedar, an app named foo will have the default hostname of foo.herokuapp.com (instead of foo.heroku.com).
The herokuapp.com domain routes to a new HTTP stack which offers a much more direct routing path to your web processes. This allows for advanced HTTP uses such as chunked responses, long polling, and using an async webserver to handle multiple responses from a single web process. It does not include Varnish as a reverse proxy cache.
Read more about the new HTTP stack.
Code injection
The Aspen and Bamboo stacks both do a substantial amount of code injection, both at slug compile time and at runtime, to make your app “just work” on Heroku. While this is part of the “Heroku magic,” the downside to this is that code injection results in mysterious, hard-to-diagnose side-effects that can be extremely frustrating, or even prevent certain types of apps from running completely.
Cedar strives for purism: the code running in your local environment is as close as possible to what runs when deployed on Heroku. This solves a great deal of deployment and debugging pain.
The downside to less code injection is that in some places there will be slightly more configuration necessary. Some examples of this include needing to specify the pg gem in your Gemfile if you’re using the Heroku PostgreSQL database, and likewise with the newrelic_rpm gem if you’re using the New Relic add-on. This is a difficult trade-off, but it will save you debugging headaches in the long run, particularly for larger and more sophisticated applications.
When we do inject code, we do it at compile time; and call it out with a message so that you can inspect what code is being added to your app, should you desire. One example of this is rails_log_stdout, a plugin injected into Rails apps to cause their logs to go to stdout, as is required for routing logs into the logging system.
PostgreSQL gem
You must specify the pg gem in your Gemfile in order to use the shared or dedicated Heroku PostgreSQL database:
gem 'pg'
We highly recommend running Postgres in your development environment, to remove the chance for differences between SQLite or MySQL and Postgres from causing issues in your production environment. (Postgres is extremely easy to install locally with Homebrew, apt-get, or the Postgres one-click installer for Windows.)
However, if you prefer to only use the pg gem in your deployed app, you can wrap it in the production group:
group :production do
gem 'pg'
end
Your database credentials will still be configured automatically: at slug compile time, a config/database.yml that parse the DATABASE_URL from the environment will be written into your app.
Ruby webserver (Webrick vs Thin)
Because Cedar doesn’t inject any gem dependencies into your app, a vanilla Rails app will run on Webrick (the built-in webserver in the Ruby standard library). We highly recommend Thin for all apps. To use Thin, add it to your Gemfile:
gem 'thin'
and define it as a web process in your Procfile:
web: bundle exec thin start -p $PORT
Similar to the pg gem above, you can chose to put this only in your production gem group if you wish, but we recommend you use Thin in local development too.
Adding a database
A Heroku shared PostgreSQL database (shared-database:5mb) will be automatically added to your app in any of the following cases:
- The app is a Rails application
- The
pggem is specified in theGemfile
This detection and installation will happen only on the first push of your app. If you’d like to later add the free shared database manually, you can do so with:
$ heroku addons:add shared-database:5mb
Migrating From Bamboo to Cedar
Before migrating to Bamboo, you should make sure your app runs on Ruby 1.9.2. If your app is not already deployed successfully to bamboo-mri-1.9.2, you should do that first, and then come back and try Cedar.
Once you’re sure your app is fully compatible with Ruby 1.9.2, create an app on the Cedar stack and push to it. Currently, stack:migrate does not work for moving apps to Cedar.