herokuロゴ画像はHerokuより。
Getting Started with Rails 5.x on Herokuを参考に進めていきます。
準備
herokuは PostgreSQL を推奨しているので、それに合わせる。
group :production do gem 'pg' end
heroku toolbeltをインストール。
$ wget -O- https://toolbelt.heroku.com/install.sh | sh $ echo 'PATH="/usr/local/heroku/bin:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile
ログインします。予めアカウントはWebから作っておく。
$ heroku login heroku-cli: Installing CLI... 21.83MB/21.83MB Enter your Heroku credentials. Email: email@example.com Password (typing will be hidden): Logged in as email@example.com
アプリケーションを作成~デプロイ
$ 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 https://XXXXX-YYYYY-12345.herokuapp.com/ | https://git.heroku.com/whispering-YYYYY-12345.git
origin の他に、リモートリポジトリ heroku
が追加されます。
$ git remote show heroku * remote heroku Fetch URL: https://git.heroku.com/XXXXX-YYYYY-12345.git Push URL: https://git.heroku.com/XXXXX-YYYYY-12345.git 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: 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: https://devcenter.heroku.com/articles/bundler-configuration remote: 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 https://rubygems.org/.......... remote: Fetching version metadata from https://rubygems.org/... remote: Fetching dependency metadata from https://rubygems.org/.. 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: 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: https://devcenter.heroku.com/articles/bundler-configuration remote: 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: https://devcenter.heroku.com/articles/ruby-default-web-server remote: remote: -----> Discovering process types remote: Procfile declares types -> (none) remote: Default types for buildpack -> console, rake, web, worker remote: remote: -----> Compressing... remote: Done: 23.1M remote: -----> Launching... remote: Released v6 remote: https://XXXXX-YYYYY-12345.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/XXXXX-YYYYY-12345.git * [new branch] master -> master
途中で、 sqlite3.h is missing
みたいなメッセージが出たり、 「詳しくは https://devcenter.heroku.com/articles/sqlite3
を見てね」的なメッセージが出たなら、 Gemfile
の group :development
の中に gem 'sqlite'
を押し込めましょう。
group :development do # Use sqlite3 as the database for Active Record gem 'sqlite3' end
必要に応じて、DBのマイグレーションを行います。
$ 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)
これでおしまい。うまくいっていれば、ログ中に出てきたhttp://example.herokuapp.com/でアクセスできる。
デバッグ
プロセス状態
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: https://devcenter.heroku.com/articles/dyno-sleeping === 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://hogehogehoge:foobarbaz@ec2-NNN-NNN-NNN-NNN.compute-M.amazonaws.com:PPPP/fugapiyo LANG: en_US.UTF-8 RACK_ENV: production RAILS_ENV: production RAILS_LOG_TO_STDOUT: enabled RAILS_SERVE_STATIC_FILES: enabled SECRET_KEY_BASE: foobarbazhogefugapiyo
# 環境変数のうち、指定したものだけを表示 $ heroku config:get LANG en_US.UTF-8
# 環境変数をセット $ 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) irb(main):001: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 console
や heroku run rake db:migrate
などのコマンドを実行する One-off Dyno
と呼ばれる Dyno
の実行も、利用量に含まれるので注意。
以前は「18時間稼働&6時間スリープ」のような制限がありましたが、今は上記の制限に代わりました。