Help us understand the problem. What is going on with this article?

Rails 5 (非beta) + Heroku で作る、無料APIサーバ

More than 3 years have passed since last update.


Rails 5でのプロジェクト作成

Rails 5の使用


$ mkdir fetch_rss_and_post_hateblog
$ cd fetch_rss_and_post_hateblog
$ echo "gem 'rails', '~>5.0'" > Gemfile
$ mkdir .bundle
$ echo '---                                                                                                                  
BUNDLE_PATH: vendor/bundle
BUNDLE_BIN: ./.bin' > .bundle/config
$ sudo yum install -y sqlite-devel # 必要に応じてapt-getなど
$ bundle install


$ rails new . --api
$ echo "development:
  secret_key_base: `rake secret`

  secret_key_base: `rake secret`

  secret_key_base: <%= ENV[\"SECRET_KEY_BASE\"] %>" > config/secrets.yml


$ gibo osx ruby rails vim >> .gitignore
$ git init
$ git remote add origin git://
$ git push origin master


RSSを取ってきて、title, URL, descriptionを返すAPIサーバを作ってみます。

$ rails g controller post


$ cd app
$ ls
channels  controllers  jobs  mailers  views


はてブのRSSフィードを RSS:Parser#parse で取れない件は、 はてなのAPIを使う際に503エラーが出る問題と解決策を参考にしました。

def fetch
  url = ''
  ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
  rss = open(url, 'User-Agent' => ua)
  feed = RSS::Parser.parse(rss)
  items = do |i|
    { link:, title: i.title, desc: i.description, date: i.dc_date }
  render json: items
Rails.application.routes.draw do
  get '/fetch', to: 'posts#fetch'


$ rails s -b


  link: "",
  title: "トラブルには技術的原因と、マネジメント的原因がある : タイム・コンサルタントの日誌から",
  desc: "【要約と私感】“マネジメント的原因” = 仕組みの原因。手っ取り早く直すには技術的要因を取り除けば良いけど、仕組みがダメならまた似たような失敗をうむ。",
  date: "2016-07-10T15:33:53.000+09:00"
  link: "",
  title: "AWS料金早見表(サーバレスアーキテクチャ) - Qiita",
  desc: "一度自分で一通りやってみたい感ある。",
  date: "2016-07-10T15:27:49.000+09:00"
}, ...]



Getting Started with Rails 5.x on Herokuを参考に進めていきます。


herokuは PostgreSQL を推奨しているので、それに合わせる。

group :production do
  gem 'pg'

heroku toolbeltをインストール。

$ wget -O- | sh
$ echo 'PATH="/usr/local/heroku/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile


$ heroku login
heroku-cli: Installing CLI... 21.83MB/21.83MB
Enter your Heroku credentials.
Password (typing will be hidden):
Logged in as


$ heroku create
Heroku CLI submits usage information back to Heroku. If you would like to disable this, set `skip_analytics: true` in /home/kit/.heroku/config.json
Creating app... done, ⬢ XXXXX-YYYYY-12345 |

origin の他に、リモートリポジトリ heroku が追加されます。

$ git remote show heroku
* remote heroku
  Fetch URL:
  Push  URL:
  HEAD branch: (unknown)

早速、 Heroku へプッシュしてみます。

$ git push heroku master
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 828 bytes | 0 bytes/s, done.
Total 6 (delta 4), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.3.0
remote: ###### WARNING:
remote:        You have the `.bundle/config` file checked into your repository
remote:        It contains local state like the location of the installed bundle
remote:        as well as configured git local gems, and other settings that should
remote:        not be shared between multiple checkouts of a single repo. Please
remote:        remove the `.bundle/` folder from your repo and add it to your `.gitignore` file.
remote: -----> Installing dependencies using bundler 1.11.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Fetching gem metadata from
remote:        Fetching version metadata from
remote:        Fetching dependency metadata from
remote:        Installing rake 11.2.2
remote:        Installing concurrent-ruby 1.0.2
remote:        Installing i18n 0.7.0
remote:        Installing thread_safe 0.3.5
remote:        Installing minitest 5.9.0
remote:        Installing builder 3.2.2
remote:        Installing erubis 2.7.0
remote:        Installing mini_portile2 2.1.0
remote:        Installing pkg-config 1.1.7
remote:        Installing nio4r 1.2.1 with native extensions
remote:        Installing rack 2.0.1
remote:        Installing websocket-extensions 0.1.2
remote:        Installing arel 7.0.0
remote:        Installing mime-types-data 3.2016.0521
remote:        Installing method_source 0.8.2
remote:        Using bundler 1.11.2
remote:        Installing puma 3.4.0 with native extensions
remote:        Installing thor 0.19.1
remote:        Installing tzinfo 1.2.2
remote:        Installing nokogiri 1.6.8 with native extensions
remote:        Installing websocket-driver 0.6.4 with native extensions
remote:        Installing rack-test 0.6.3
remote:        Installing sprockets 3.6.3
remote:        Installing mime-types 3.1
remote:        Installing activesupport 5.0.0
remote:        Installing mail 2.6.4
remote:        Installing globalid 0.3.6
remote:        Installing activemodel 5.0.0
remote:        Installing activejob 5.0.0
remote:        Installing activerecord 5.0.0
remote:        Installing rails-dom-testing 2.0.1
remote:        Installing loofah 2.0.3
remote:        Installing rails-html-sanitizer 1.0.3
remote:        Installing actionview 5.0.0
remote:        Installing actionpack 5.0.0
remote:        Installing actionmailer 5.0.0
remote:        Installing actioncable 5.0.0
remote:        Installing railties 5.0.0
remote:        Installing sprockets-rails 3.1.1
remote:        Installing rails 5.0.0
remote:        Installing pg 0.18.4 with native extensions                                                                           
remote:        Bundle complete! 9 Gemfile dependencies, 41 gems now installed. 
remote:        Gems in the groups development and test were not installed.
remote:        Bundled gems are installed into ./vendor/bundle.
remote:        Bundle completed (19.95s)
remote:        Cleaning up the bundler cache.
remote: ###### WARNING:
remote:        You have the `.bundle/config` file checked into your repository
remote:        It contains local state like the location of the installed bundle
remote:        as well as configured git local gems, and other settings that should
remote:        not be shared between multiple checkouts of a single repo. Please
remote:        remove the `.bundle/` folder from your repo and add it to your `.gitignore` file.
remote: ###### WARNING:
remote:        No Procfile detected, using the default web server.
remote:        We recommend explicitly declaring how to boot your server process via a Procfile.
remote: -----> Discovering process types
remote:        Procfile declares types     -> (none)
remote:        Default types for buildpack -> console, rake, web, worker
remote: -----> Compressing...
remote:        Done: 23.1M
remote: -----> Launching...
remote:        Released v6
remote: deployed to Heroku
remote: Verifying deploy... done.
 * [new branch]      master -> master

途中で、 sqlite3.h is missing みたいなメッセージが出たり、 「詳しくは を見てね」的なメッセージが出たなら、 Gemfilegroup :development の中に gem 'sqlite' を押し込めましょう。

group :development do
  # Use sqlite3 as the database for Active Record
  gem 'sqlite3'


$ heroku run rake db:migrate
Running rake db:migrate on ⬢ XXXXX-YYYYY-12345... up, run.2785                                                               
D, [2016-07-12T16:25:40.173919 #3] DEBUG -- :    (11.2ms)  CREATE TABLE "schema_migrations" ("version" character varying PRIMARY KEY)
D, [2016-07-12T16:25:40.187941 #3] DEBUG -- :    (9.3ms)  CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
D, [2016-07-12T16:25:40.190308 #3] DEBUG -- :    (1.0ms)  SELECT pg_try_advisory_lock(1753797496500759360);
D, [2016-07-12T16:25:40.200901 #3] DEBUG -- :   ActiveRecord::SchemaMigration Load (1.1ms)  SELECT "schema_migrations".* FROM "schema_migrations"
I, [2016-07-12T16:25:40.206248 #3]  INFO -- : Migrating to CreatePosts (20160710102422)
D, [2016-07-12T16:25:40.208344 #3] DEBUG -- :    (0.7ms)  BEGIN
== 20160710102422 CreatePosts: migrating ======================================
-- create_table(:posts)
D, [2016-07-12T16:25:40.216973 #3] DEBUG -- :    (7.4ms)  CREATE TABLE "posts" ("id" serial primary key, "title" character varying, "url" character varying, "comment" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.0085s
== 20160710102422 CreatePosts: migrated (0.0087s) =============================

D, [2016-07-12T16:25:40.224358 #3] DEBUG -- :   SQL (1.1ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20160710102422"]]
D, [2016-07-12T16:25:40.227280 #3] DEBUG -- :    (2.6ms)  COMMIT
I, [2016-07-12T16:25:40.227414 #3]  INFO -- : Migrating to AddDateToPost (20160710152551)
D, [2016-07-12T16:25:40.228671 #3] DEBUG -- :    (0.7ms)  BEGIN
== 20160710152551 AddDateToPost: migrating ====================================
-- add_column(:posts, :date, :datetime)
D, [2016-07-12T16:25:40.230074 #3] DEBUG -- :    (1.0ms)  ALTER TABLE "posts" ADD "date" timestamp
   -> 0.0013s
== 20160710152551 AddDateToPost: migrated (0.0014s) ===========================

D, [2016-07-12T16:25:40.231584 #3] DEBUG -- :   SQL (0.8ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20160710152551"]]
D, [2016-07-12T16:25:40.233287 #3] DEBUG -- :    (1.5ms)  COMMIT
D, [2016-07-12T16:25:40.240319 #3] DEBUG -- :   ActiveRecord::InternalMetadata Load (0.9ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", :environment], ["LIMIT", 1]]
D, [2016-07-12T16:25:40.248994 #3] DEBUG -- :    (0.7ms)  BEGIN
D, [2016-07-12T16:25:40.251805 #3] DEBUG -- :   SQL (1.0ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key"  [["key", "environment"], ["value", "production"], ["created_at", 2016-07-12 16:25:40 +0000], ["updated_at", 2016-07-12 16:25:40 +0000]]
D, [2016-07-12T16:25:40.253633 #3] DEBUG -- :    (1.5ms)  COMMIT
D, [2016-07-12T16:25:40.254643 #3] DEBUG -- :    (0.8ms)  SELECT pg_advisory_unlock(1753797496500759360)




heroku ps で現在の状態を見ることができる。

$ heroku ps
Free dyno hours quota remaining this month: 1000h 0m (100%)
For more information on dyno sleeping and how to upgrade, see:

=== web (Free): bin/rails server -p $PORT -e $RAILS_ENV (1)
web.1: up 2016/07/13 01:25:02 +0900 (~ 2m ago)


ログを見るなら heroku logs--tail オプションを付けると、リアルタイムで見られる。

$ heroku logs
$ heroku logs --tail


# 環境変数の一覧
$ heroku config
=== XXXXX-YYYYY-12345 Config Vars
DATABASE_URL:             postgres://
LANG:                     en_US.UTF-8
RACK_ENV:                 production
RAILS_ENV:                production
RAILS_LOG_TO_STDOUT:      enabled
SECRET_KEY_BASE:          foobarbazhogefugapiyo
# 環境変数のうち、指定したものだけを表示
$ heroku config:get LANG                                                              
# 環境変数をセット
$ heroku config:set SECRET_KEY_BASE=`rake secret`                                     
Setting SECRET_KEY_BASE and restarting ⬢ XXXXX-YYYYY-12345... done, v8                                                       
SECRET_KEY_BASE: hogefugapiyofoobarbaz


$ heroku run rails console
Running rails console on ⬢ XXXXX-YYYYY-12345... up, run.4519
Loading production environment (Rails 5.0.0)


$ heroku restart
Restarting dynos on ⬢ XXXXX-YYYYY-12345... done

Heroku 無料枠の範囲

1つのサーバプロセスを立ち上げると、 1 dyno を使用するということになります。 1 dyno を1時間使用すると、 1 dyno hour を消費したことになります。

各アカウントに対し 550 dyno hours を、有効なクレジットカードを heroku に登録していれば、さらに 450 dyno hours(計 1000 dyno hours) を一月に付与されます。

31日間の可動に必要な dyno hours は単純計算で 744 dyno hours (= 24 hours * 31 days) ですが、 heroku run consoleheroku run rake db:migrate などのコマンドを実行する One-off Dyno と呼ばれる Dyno の実行も、利用量に含まれるので注意。



株式会社CUUSOO SYSTEMのCTO兼フルスタックエンジニアです。Rails, 機械学習, Androidが好きです。AIで株取引するやつやってます。 発言は個人の見解であり、所属する団体等の公式見解ではありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away