Deploying Padrino Applications On Heroku
This article is part of an ongoing series about my exploration of the Padrino web framework. If you want to read more about it please check out padrinobook.com. You sniff around in the sources of the book under GitHub.
I was always asking myself how I can use cloud services like heroku to deploy Padrino applications without having an own server.
In this post I’m going to show you how you can a simple “Hello Padrino” app on heroku - ones without and ones with database interactions.
(Note: This post is tested with padrino 0.12.0, and heroku-toolbelt/3.4.1)
Installing Heroku
$ gem install heroku
Fetching: heroku-3.4.2.gem (100%)
! The `heroku` gem has been deprecated and replaced with the Heroku Toolbelt.
! Download and install from: https://toolbelt.heroku.com
! For API access, see: https://github.com/heroku/heroku.rb
Successfully installed heroku-3.4.2
Parsing documentation for heroku-3.4.2
Installing ri documentation for heroku-3.4.2
Done installing documentation for heroku after 1 seconds
1 gem installed
Hmm, the method above is working but I highly recommend you to follow the installations instructions from toolbelt.heroku.com page:
$ wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
To check if everything went well, you can run the following command:
$ heroku version
heroku-toolbelt/3.4.1 (i686-linux) ruby/1.9.3
Hello World
Creating a new app:
$ padrino generate project hello-world-heroku
create
create .gitignore
create config.ru
create config/apps.rb
create config/boot.rb
create public/favicon.ico
create public/images
create public/javascripts
create public/stylesheets
create tmp
create .components
create app
create app/app.rb
create app/controllers
create app/helpers
create app/views
create app/views/layouts
create Gemfile
create Rakefile
skipping orm component...
skipping test component...
skipping mock component...
skipping script component...
applying slim (renderer)...
apply renderers/slim
insert Gemfile
skipping stylesheet component...
identical .components
force .components
force .components
=================================================================
hello-world-heroku is ready for development!
=================================================================
$ cd ./hello-world-heroku
$ bundle
=================================================================
The next part is to create a route in app/app.rb
:
module HelloWorldHeroku
class App < Padrino::Application
...
get "/" do
"Hello Padrino On Heroku"
end
end
end
Next, you need to setup your account on heroku.com:
Next you need to click on “Create a new app”:
Initialize an empty git repository, make an initial commit, and add the heroku remote:
$ cd hello-world-heroku
$ git init && git add . && git commit -m "Initial commit"
$ git remote add heroku git@heroku.com:hello-world-padrino.git
When everything is setup in the right way, you need to push:
$ git push --set-upstream heroku master
Initializing repository, done.
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (15/15), 7.88 KiB | 0 bytes/s, done.
Total 15 (delta 0), reused 0 (delta 0)
-----> Ruby app detected
-----> Compiling Ruby/Rack
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using 1.5.2
New app detected loading default bundler cache
Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
Fetching gem metadata from https://rubygems.org/.........
Fetching additional metadata from https://rubygems.org/..
Using minitest (4.7.5)
Using i18n (0.6.9)
Using rake (10.1.1)
Using atomic (1.1.14)
Using tzinfo (0.3.38)
Using multi_json (1.8.4)
Using mime-types (1.25.1)
Using rack (1.5.2)
Using tilt (1.4.1)
Using bundler (1.5.2)
Installing polyglot (0.3.3)
Using thread_safe (0.1.3)
Installing thor (0.17.0)
Installing url_mount (0.2.1)
Using treetop (1.4.15)
Installing temple (0.6.7)
Installing moneta (0.7.20)
Using mail (2.5.4)
Installing rack-protection (1.5.2)
Installing http_router (0.11.0)
Installing slim (2.0.2)
Installing activesupport (4.0.2)
Installing sinatra (1.4.4)
Installing padrino-core (0.12.0)
Installing padrino-helpers (0.12.0)
Installing padrino-mailer (0.12.0)
Installing padrino-cache (0.12.0)
Installing padrino-admin (0.12.0)
Installing padrino-gen (0.12.0)
Installing padrino (0.12.0)
Your bundle is complete!
Gems in the groups development and test were not installed.
It was installed into ./vendor/bundle
Bundle completed (13.40s)
Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> WARNINGS:
You have not declared a Ruby version in your Gemfile.
To set your Ruby version add this line to your Gemfile:
ruby '2.0.0'
# See https://devcenter.heroku.com/articles/ruby-versions for more information.
-----> Discovering process types
Procfile declares types -> (none)
Default types for Ruby -> console, rake, web
-----> Compressing... done, 15.3MB
-----> Launching... done, v4
http://hello-world-padrino.herokuapp.com/ deployed to Heroku
To git@heroku.com:hello-world-padrino.git
* [new branch] master -> master
Branch master set up to track remote branch master from heroku.
If you now call hello-world-herokuapp.com you can see it and your done.
You can find the code for this application on GitHub padrino-hello-world-heroku
Database Deployments With Heroku
Let’s create a new application:
$ padrino g project hello-world-heroku-postgres -d activerecord -a postgres
create
create .gitignore
create config.ru
create config/apps.rb
create config/boot.rb
create public/favicon.ico
create public/images
create public/javascripts
create public/stylesheets
create tmp
create .components
create app
create app/app.rb
create app/controllers
create app/helpers
create app/views
create app/views/layouts
create Gemfile
create Rakefile
applying activerecord (orm)...
apply orms/activerecord
insert Gemfile
insert Gemfile
insert app/app.rb
create config/database.rb
skipping test component...
skipping mock component...
skipping script component...
applying slim (renderer)...
apply renderers/slim
insert Gemfile
skipping stylesheet component...
identical .components
force .components
force .components
=================================================================
hello-world-heroku-postgres is ready for development!
=================================================================
$ cd ./hello-world-heroku-postgres
$ bundle
=================================================================
Go to your app and select under “Resources” the “Get Add-ons” link and chose the “Heroku Postgres” addon with the help:
You can also run the following command which does the same:
$ heroku addons:add heroku-postgresql
Adding heroku-postgresql on hello-world-heroku-postgres... done, v3 (free)
Attached as HEROKU_POSTGRESQL_TEAL_URL
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql` to view documentation.
Hmmm, let’s go into the help:
$ heroku addons:docs heroku-postgresql
It will open the URL https://devcenter.heroku.com/articles/heroku-postgresql. Calling:
$ heroku config | grep HEROKU_POSTGRESQL
HEROKU_POSTGRESQL_TEAL_URL: postgres://yxkscmfxkhsvfd:hnGMVRPWmBQ06Bi3ujqP21Orl4@ec2-79-125-21-60.eu-west-1.compute.amazonaws.com:5432/dev751q4jd401b
gives us the host URL, the user, the port, as well as the password. You can get the same information under the URL https://postgres.heroku.com/databases.
Since we now have the information about our database, it’s time to edit config/database.rb
:
ActiveRecord::Base.configurations[:production] = {
:adapter => 'postgresql',
:database => 'dev751q4jd401b',
:username => 'yxkscmfxkhsvfd',
:password => 'hnGMVRPWmBQ06Bi3ujqP21Orl4',
:host => 'ec2-79-125-21-60.eu-west-1.compute.amazonaws.com',
:port => 5432
}
Now, it’s time to push our app on heroku:
$ git push heroku master
Initializing repository, done.
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (20/20), done.
Writing objects: 100% (22/22), 9.43 KiB | 0 bytes/s, done.
Total 22 (delta 4), reused 0 (delta 0)
-----> Ruby app detected
-----> Compiling Ruby/Rack
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using 1.5.2
New app detected loading default bundler cache
Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
Fetching gem metadata from https://rubygems.org/.........
Fetching additional metadata from https://rubygems.org/..
Using rake (10.1.1)
Using i18n (0.6.9)
Using minitest (4.7.5)
Using tzinfo (0.3.38)
Using builder (3.1.4)
Using activerecord-deprecated_finders (1.0.3)
Using arel (4.0.2)
Using rack (1.5.2)
Using mime-types (1.25.1)
Using polyglot (0.3.4)
Using tilt (1.4.1)
Installing thor (0.17.0)
Using bundler (1.5.2)
Using pg (0.17.1)
Installing multi_json (1.9.0)
Installing url_mount (0.2.1)
Installing moneta (0.7.20)
Using treetop (1.4.15)
Installing temple (0.6.7)
Using mail (2.5.4)
Installing atomic (1.1.15)
Installing rack-protection (1.5.2)
Installing slim (2.0.2)
Installing http_router (0.11.1)
Installing sinatra (1.4.4)
Installing thread_safe (0.2.0)
Installing activesupport (4.0.3)
Installing activemodel (4.0.3)
Installing padrino-core (0.12.0)
Installing padrino-mailer (0.12.0)
Installing padrino-gen (0.12.0)
Installing padrino-helpers (0.12.0)
Installing activerecord (4.0.3)
Installing padrino-cache (0.12.0)
Installing padrino-admin (0.12.0)
Installing padrino (0.12.0)
Your bundle is complete!
Gems in the groups development and test were not installed.
It was installed into ./vendor/bundle
Bundle completed (18.14s)
Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> WARNINGS:
You have not declared a Ruby version in your Gemfile.
To set your Ruby version add this line to your Gemfile:
ruby '2.0.0'
# See https://devcenter.heroku.com/articles/ruby-versions for more information.
-----> Discovering process types
Procfile declares types -> (none)
Default types for Ruby -> console, rake, web
-----> Compressing... done, 16.1MB
-----> Launching... done, v6
http://hello-world-heroku-postgres.herokuapp.com/ deployed to Heroku
To git@heroku.com:hello-world-heroku-postgres.git
* [new branch] master -> master
Now let’s create a model:
$ padrino g model user name:string email:text
apply orms/activerecord
create models/user.rb
create db/migrate/001_create_users.rb
Before pushing our changes we need to run the migrations:
$ heroku run rake db:migrate
Running `rake db:migrate` attached to terminal... up, run.1057
== CreateUsers: migrating ====================================================
-- create_table(:users)
-> 0.0234s
== CreateUsers: migrated (0.0236s) ===========================================
Now we need to create some data with the following query:
INSERT INTO users (name, email) VALUES ('Matthias', 'matthias@wikimatze.de');
Next we need to edit our view app/app.rb
:
module HelloWorldHeroku
class App < Padrino::Application
...
get "/" do
user = Users.find(1)
"Hello #{user.name}\n Your email is: #{user.email}"
end
end
end
After pushing the changes, you can call http://hello-world-heroku-postgres.herokuapp.com and see the lovely output.