Heroku に Rails アプリをアップ

Created by Terence Lee, @hone02

Heroku の準備

Heroku のアカウントを作成しよう

アカウントの作成はもちろん無料です。

ユーザ登録画面からアカウントを作成しましょう。

「First name」に名前、「Last name」に苗字、「Email」にメールアドレス、「Role」でHobbyistを選択、国を選択、言語として Ruby を選択して最後に「I’m not a robot」にチェックを入れて「Create Free Account」ボタンを押します。

しばらくすると入力したメールアドレスに「Confirm your account on Heroku」という件名のメールが届くので、本文中の activate 用の URL をクリックします。

heroku で用いるパスワードを入力してアカウントの作成は完了です。

Heroku CLI をインストールしよう

Heroku でコマンドライン操作を行うためのアプリケーションである、Heroku CLI をインストールします。

Heroku CLI

このページの「Download and install」という段落から、自分のノートパソコンのOSに合わせてインストールしましょう。

Macの場合

Ruby, Railsのインストール時にHomebrewをインストールしているはずなので、Homebrewを使ってインストールできます。

brew install heroku/brew/heroku
Windows(WSL)の場合

Ubuntuを起動して、次のコマンドを入力しましょう。

curl https://cli-assets.heroku.com/install.sh | sh

Coachへ: Heroku CLIのページ を見るとUbuntuではsnapを使う手順を説明していますが、WSLではsnapの利用が困難であるため、Other installation methodsで紹介されている上記のコマンドでインストールします。

Windows(コマンドプロンプト)の場合

64-bit あるいは 32-bit と書かれたリンクをクリックしてダウンロードしてください。

(自分のWindowsが32bit版64bit版かは、コントロールパネルから確認できます。Microsoftのこちらの記事を参考に、確認してみてください)

ダウンロードが済んだら、heroku-windows-amd64.exe(あるいは、heroku-windows-386.exe) をダブルクリックし、表示される指示に従ってインストールしてください。

(環境により拡張子が表示されませんが、異常ではありません)

codenvy.ioの場合

codenvy.io上のターミナルから次のコマンドを入力しましょう。

curl https://cli-assets.heroku.com/install.sh | sh

Heroku にコマンドラインでログインしよう

Heroku Toolbelt を無事インストールできたら、ターミナル(Mac)またはコマンドプロンプト(Windows)を起動して、次のコマンドを入力しましょう。

heroku login

heroku: Press any key to open up the browser to login or q to exit: と言われますのでEnterキーを押してください。するとブラウザでherokuのページが開かれます。 メールアドレスとパスワードの入力を求められたら先ほど登録したメールアドレスとパスワードを入力します。

ブラウザに以下の画面が表示されればherokuの準備はこれで終了です。

Coachより: Heroku か、従来のサーバーか、デプロイの利点について話してみましょう。

アプリの準備

バージョン管理システム

作成したコードをバージョン管理システムに追加します。ターミナル上で次のコマンドを入力しましょう。:

echo public/uploads >> .gitignore
git add .
git commit -m "initial commit"

Coachより: バージョン管理システムと git について説明するちょうどいいタイミングです。.gitignore の説明と上記のファイルを管理対象外にしたい理由についても説明しましょう。

データベースのアップデート

まず、 Heroku で動くデータベースが必要です。いつものデータベースとは違います。 Gemfile を次のように変更しましょう。 :

gem 'sqlite3', '~> 1.4'

group :development do
  gem 'sqlite3', '~> 1.4'
end
group :production do
  gem 'pg'
end

そして、ターミナル上で次のコマンドを実行してセットアップしてください。

bundle install --without production
git add .
git commit -m "Added pg gem and updated Gemfile.lock"

Coachより: RDBMS とそうでないものについて話してみましょう。Heroku 上の PostgreSQL の制限についても少し取り上げてみてください。

アプリのデプロイ

アプリのcreate

Heroku のアプリを作りましょう。
まずは世界に1つだけのアプリの名前を考えましょう!

名前が決まったら、ターミナルでコマンドを実行します。
例えば、アプリの名前を”my-first-app”と決めた場合、ターミナルで次のコマンドを実行してください。 :

heroku create my-first-app

次のようなものが見られます。 :

Creating ⬢ my-first-app... done
http://my-first-app.herokuapp.com/ | https://git.heroku.com/my-first-app.git

もし、決めたアプリの名前が既に使われていたら、以下のようなメッセージが表示されます。 :

Creating ⬢ my-first-app... !
 ▸    Name myfirst-app is already taken

この場合は、もう一度アプリの名前を考えてなおしてみてください。

コードをpush

さて、 Heroku にコードを送信しましょう。 ターミナルで次のコマンドを実行してください。 :

git push heroku master

そうすると、こんな出力が見られるはずです。 :

Counting objects: 134, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (115/115), done.
Writing objects: 100% (134/134), 35.29 KiB, done.
Total 134 (delta 26), reused 0 (delta 0)

remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.3
remote: -----> Installing dependencies using bundler 2.0.1
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: -----> Launching...
remote:        Released v6
remote:        https://my-first-app.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/my-first-app.git
 * [new branch]      master -> master

アプリのプッシュが終わってるのがわかりますか? “Launching…” というテキストのところです。プッシュが成功したら データベースのマイグレート へ進んで下さい。

Coachより: どのようなファイルがプッシュされ、どのようなファイルがされなかったか話してみてください。まだであればアップロードされるファイルについて話してみたり、config以下のいくつかのファイルについて可能な範囲で話してみてください。

・ pushで認証が要求された場合

もし下のように表示された場合は (Windowsでユーザー名が全角の場合に起きます) :

Username for 'https://git.heroku.com':

まず、CTRL-Cを押しコマンドを終了します。そして次のコマンドを実行してみて下さい。

heroku auth:token
d42d086f-b127-4cf0-a2a9-acaf13287213

ターミナルに表示された文字列をコピーして下さい。上の例では文字列は d42d086f-b127-4cf0-a2a9-acaf13287213 ですが、あなたの画面では違う文字列が表示されています。

そして、git push … コマンドを実行して下さい。

git push heroku master
Username for 'https://git.heroku.com':   ← 何も入力せず Enter
Password for 'https://git.heroku.com':   ← 上でコピーした文字列をペーストし Enter
・ その他のエラーの場合

画面表示を見ながらコーチと相談して問題を解決して下さい。

データベースのマイグレート

そして、ワークショップでローカルにやったように、データベースのマイグレートをする必要があります。 :

heroku run rails db:migrate

公共のネットワークなどを使った場合、ETIMEDOUT: connect ETIMEDOUT (IPアドレス):5000 というエラーが起きることがあります。エラーになった場合は実行するコマンドを heroku run:detached rails db:migrate に変更してみてください。

そのコマンドが実行されたら、インターネットからアプリを見ることができます。このアプリの例ではURLは、 http://my-first-app.herokuapp.com/ です。もしくは、クラウドIDE以外ならターミナルで次のコマンドを実行すれば、そのページを見に行くことができます。

heroku open

もし、これまでに出てきたコマンドの実行中に表示されるURLを見逃していた場合は、以下のコマンドを実行した時の Web URL の行(最後の行)を確認してください。

heroku apps:info

おわりに

Heroku のプラットフォームは癖がない訳ではありません。Heroku 上のアプリは ephemeral な(再起動で一部のファイルが揮発する)環境で動作しています。- これは(データベースに保存された情報と push した情報を除く)全てのファイルがアプリの再起動で消えてしまうという事です。(例えば、新しいバージョンのプログラムを push した場合)

Ephemeral ファイルシステム

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

(各 dyno は専用の ephemeral ファイルシステムを取得します。この領域には最新のデプロイしたプログラムもコピーされます。実行中のプロセスが dyno の生存期間にある間は、このファイルシステムを一時的なスクラッチパッドとして扱う事ができます。しかし、dynoが停止か再起動をした瞬間に出力されていたすべてのファイルはプロセスから見えなくなります)

App では、追加した Idea レコードにファイルを添付する事ができます。このファイルはアプリの public/uploads フォルダ以下に配置されます。以下の手順で Heroku での ephemeral ストレージの動作を確認できます:

  1. heroku open を実行してアプリを開きます
  2. 新しい Idea に画像を付けて追加します
  3. heroku restart を実行してアプリを再起動します
  4. 追加した Idea を再度表示し、このページを reload します - 画像は表示されなくなります
Ephemeral ストレージの回避策

これは実際のアプリにとっては明らかに不便ですが、有名なサイトでも使われてる回避策がちゃんとあります。

最も一般的な回避策はAmazon S3(Simple Storage Service)やRackspace CloudFilesのような外部ホストの資源を利用する事です。これらのサービスは(安価な - 通常 0.1$/GB 以下の)アプリから永続的に利用可能なストレージを ‘クラウド上に’ 提供します(つまりファイルをどこへでも提供し得えます)。

この機能は少しだけこのチュートリアルの範囲から外れますが、以下のようなリソースを参考に、目的にあった方法を見つける事ができるでしょう。

いつものように、わからない事がある場合や手助けが必要な場合は担当のコーチが対応してくれます。