Herokuでsinatraアプリを公開する手順


目的

sinatraからのHerokuへの公開時、最初によく使いそうな基本的な操作と知識をまとめる

前提

  • Mac High Sierra
    • windowsでやる場合はvagrant上で
  • ruby 2.4.1 (rubyが入っていない場合は、下部参照を確認) (バージョンが変わらない場合は、下部参照を確認)
  • sqlite3 3.19.3
  • postgres (PostgreSQL) 10.4
  • sinatraアプリがすでにできていることを想定
    • 起動ファイルは heroku_study.rb

Sinatraの導入
https://qiita.com/yukihigasi/items/ffce19609ad8d935b7b0
sinatraでアプリを作る
https://qiita.com/yukihigasi/items/284418046b8aac55d05b

手順

アプリの修正

  • アプリケーションの内容自体は問わないが、本手順作成では、先日の「sinatraでアプリを作る」のアプリをベースに、ルーティングを行なっていた起動時に呼び出すsitatra_study.rbというファイルをheroku_study.rbに名称変更している
  • Herokuはsqlite3に対応していないため、本番環境ではPostgreSQLを使う、という定義を追加し、postgresqlをインストールしておく

  • 端末にposgtresqlをインストール(macの場合)

brew install postgresql
  • gemをインストール
sudo gem install pg -v '0.18.2'

Herokuへのログイン

  • CLIの導入

    • ログイン後、以下のページで言語を選択、rubyを選択する
  • 画面に従い、cliのインストールを行う

  • インストールが完了したら、

$heorku login

コマンドを実行し、メールアドレス、パスワードを入力し、ログインします。

Procfileの作成

  • herokuにてアプリを実行するために必要な設定ファイルを準備する
  • プロジェクトルート上に以下のように作成する
web: bundle exec ruby heroku_study.rb -p $PORT
  • 今回webアプリケーションなのでweb:と記載する
  • 起動コマンドbundle exec ruby {起動ファイル名}.rb を定義する
  • 最後に、ポートを指定する。$PORTと指定すると、Herokuがポートを自動的に設定する-p $PORT

  • プロジェクトをgit管理する

    • もしまだプロジェクトをgit管理していなければ、gitを導入しcommitする
    • プロジェクトのルートにて、 git init
    • git add -Aとりあえず全部addし
    • git commit -m 'initial commit' で一旦git管理はok

Heroku上にアプリケーションを作成する

  • herokuコマンドを実行し、heroku常に、これからアプリを載せるサーバを用意する
  • heroku createを実行する
$ heroku create
Creating app... done, ⬢ calm-{...}
https://calm-{...}.herokuapp.com/
 | https://git.{...}.git

Rakeタスク・マイグレーションの準備

  • sqlite3で開発していた場合、sqlite3はheroku対応されていないため、他のDBに変更する必要があります。この時、DDLを流したりなどで、マイグレーションを行う仕組みができている必要があります。 少し長くなりますが、Rakeタスクをアプリに追加し、マイグレーションを行い、heroku上にDBを作成していくプロセスを行います
  • database(PostgreSQL)の準備

    • もしまだposgresqlを環境にインストールしていなければ、インストールする
    • brew install postgresql (macの場合)
  • Gemの追加

    • Gemfileにpgを追加し、Bundle installする
    • まだ入っていなければ、ActiveRecordを追加
    • sinatraでマイグレーションを行うために、sinatra-activerecordを導入する
    • sqlite3はdevelopmentの場合だけに適用することを明示する
Gemfile
gem 'pg'
gem 'activerecord'
gem 'sinatra-activerecord'
gem 'sqlite3', groups: %w(test development), require: false
  • また、環境ごとにDBを分けるため、gemfileを以下のように修正する
source 'https://rubygems.org'
gem 'sinatra', :github => 'sinatra/sinatra'
gem 'rake'
gem 'sinatra-contrib'
gem 'activerecord'
gem 'rack_csrf', '~> 2.5'
gem "sinatra-activerecord"
group :development do
  gem 'sqlite3'
end
group :production do
  gem 'pg'
  gem "activerecord-postgresql-adapter"
end
group :test do
  gem 'rspec'
  gem 'rack-test'
end

  • ローカル上にgemを落とすため、--pathを指定してbundle installする
  • bundle exec
bundle install --path=vendor/bundle

GitHub
https://github.com/janko-m/sinatra-activerecord#setup

  • なのですが、あとでデプロイ後に、heroku logsで起動ログを確認したところ、vender/bundleは入れない方が良い、というワーニングが出ていたので、.gitignoreで、vendor以下をリポジトリから除外しました
.gitignore
/vendor/

config.ru を作成

  • アプリケーションルートで、以下のファイルを作成し、起動ファイルでrequireする
  • まず最初にconfig.ruファイルがherokuから呼び出される。ここからアプリケーションが実行される
    • tipsとして、アプリに問題がある場合、heloku logsで最初にエラーの始まりとして表示されるのは、config.ruが出てくる、そこからネストして具体的なエラーの原因が絞り込まれる、というログの出方をしていた
config.ru
require './{起動ファイルの拡張子なし}'
run Sinatra::Application

  • sinatraの場合、このアプリがsinatraであることを伝えるために必要
  • 今回の場合require './heroku_study' になる

Rakefileを作成する

  • プロジェクトのルートに、以下のファイルを作成します
  • これにより、rakeタスクdb:create_migration db:migrateが追加されます
Rakefile
require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'
  • これで、rakeタスクが利用可能になります。利用可能なタスクは以下です。
$ bundle exec rake -T
rake db:create              # Creates the database from DATABASE_URL or config/datab...
rake db:create_migration    # Create a migration (parameters: NAME, VERSION)
rake db:drop                # Drops the database from DATABASE_URL or config/databas...
rake db:environment:set     # Set the environment value for the database
rake db:fixtures:load       # Loads fixtures into the current environment's database
rake db:migrate             # Migrate the database (options: VERSION=x, VERBOSE=fals...
rake db:migrate:status      # Display status of migrations
rake db:rollback            # Rolls the schema back to the previous version (specify...
rake db:schema:cache:clear  # Clears a db/schema_cache.yml file
rake db:schema:cache:dump   # Creates a db/schema_cache.yml file
rake db:schema:dump         # Creates a db/schema.rb file that is portable against a...
rake db:schema:load         # Loads a schema.rb file into the database
rake db:seed                # Loads the seed data from db/seeds.rb
rake db:setup               # Creates the database, loads the schema, and initialize...
rake db:structure:dump      # Dumps the database structure to db/structure.sql
rake db:structure:load      # Recreates the databases from the structure.sql file
rake db:version             # Retrieves the current schema version number

マイグレーション

  • マイグレーションファイルを以下で作成します
  • bundle exec rake db:create_migration NAME=create_users
  • マイグレーションファイルが作成されました
db/migrate/20180718105504_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
  end
end

  • テーブル定義
    • idは自動で準備される
    • nameカラム
    • code(外部キーを想定)
    • 以上の構成のテーブルを作成する
db/migrate/20180718105504_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t| 
      t.string :name
      t.string :code
    end
  end
end

DB(PostgreSQL)の接続設定

  • 起動ファイル(今回はheroku_study.app)に接続設定を追加
heroku_study.app
ActiveRecord::Base.establish_connection(
  ENV['DATABASE_URL'] )
  • DATABASE_URL この環境変数に、このDBがposgresであること、host、ポート、DB、一色の情報が乗った規定されたスキームの値が乗ってくるので、それを利用してhelok上では動作する

  • 本当は以下のように設定したかった。

    • ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/herdb.db')
    • こうして、herokuではpostgres、そうでなければ(ローカルでは)sqlite3にしたかった
    • しかし、deploy後に、画面がアプリケーションエラーとなり、heroku logs を確認すると、rack_upでクラッシュ、原因はdatabase configuration does not specify adapterとなった
    • DBの特定の設定がされていない、という内容だった。
    • 一旦、ローカルでは動かなくなってしまうがpostgresql一つを指定したところ、正常に動作した。この問題も、何らかの方法で解決したい
  • Rakeファイルにも設定を追加

Rakefile
require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'

ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/herdb.db')

このパス指定はなにか
https://apidock.com/rails/ActiveRecord/Base/establish_connection/class
SQLite3繋がらない問題
http://eri-twin.hateblo.jp/entry/2018/02/26/200248

herokuにpushする

  • その前に、変更を commitするのを忘れずに
  • git add . git commit -m "コメント"
git push heroku master
  • postgresqlを利用するためのアドオンをherokuに追加する
heroku addons:add heroku-postgresql

heroku上のDBをマイグレートする

heroku run rake db:migrate
  • これでアプリの準備はできているはずのため、情報を以下で確認する
$ heroku apps:info
=== calm-sample
Addons:         heroku-postgresql:hobby-dev
                heroku-postgresql:hobby-dev
Auto Cert Mgmt: false
Dynos:          web: 1
Git URL:        https://git.heroku.com/calm-samplegit
Owner:          [email protected]
Region:         us
Repo Size:      12 MB
Slug Size:      15 MB
Stack:          heroku-16
Web URL:        https://calm-sample.herokuapp.com/

うまくいかない場合は、以下のコマンドでログを確認する

  • heroku logs

参考

公式
https://jp.heroku.com/home
Heroku+Ruby+SinatraでReplyにオウム返しするLineBotを作った
https://qiita.com/fullmated/items/81d1a49ed3d49eda2285
ドットインストール
https://dotinstall.com/lessons/basic_heroku
Herokuに速攻デプロイするSinatraアプリテンプレートをつくる #1
http://totutotu.hatenablog.com/entry/2015/06/10/Heroku%E3%81%AB%E9%80%9F%E6%94%BB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%99%E3%82%8BSinatra%E3%82%A2%E3%83%97%E3%83%AA%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%92%E3%81%A4
Herokuに速攻デプロイするSinatraアプリテンプレートをつくる #2 PostgreSQL編
http://totutotu.hatenablog.com/entry/2015/06/10/Heroku%E3%81%AB%E9%80%9F%E6%94%BB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%99%E3%82%8BSinatra%E3%82%A2%E3%83%97%E3%83%AA%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%92%E3%81%A4_1
PostgreSQLの導入とマイグレーションを導入する
HerokuではSQLite3が使えない?!
https://qiita.com/MosamosaPoodle/items/7149aa66f1c087472777
MacにPostgreSQLをインストール
https://qiita.com/_daisuke/items/13996621cf51f835494b
MacのRailsアプリでPostgreSQLを使う方法
https://qiita.com/yh2020/items/8be3087004d100fe752b
Herokuにデプロイできない非エンジニアです。
https://qiita.com/Taak15/items/8a7325c302d0d1b019f5