3
0

More than 1 year has passed since last update.

ローカルで作成したdocker イメージをherokuにデプロイする方法(備忘録)

Last updated at Posted at 2022-01-24

はじめに

Dockerで開発環境を作成し、ローカルで開発したアプリケーションをherokuを使ってデプ
ロイする際に、当初うまくいかなかったので、その手順について、備忘録としてここに
残します。

herokuとは

Heroku はアプリの構築、提供、監視、スケールに役立つクラウドプラットフォーム

引用:Heroku とは | Heroku

Cf. クラウドプラットフォームとは

クラウド型プラットフォームとは、アプリケーション実行やデータ保存ができる基盤を、WEB上で展開しているものです。

引用:IT業界初心者必見!クラウド型プラットフォームとは? | ITコラムdeパイプドビッツ|パイプドビッツ公式HP(pi-pe.co.jp)

1.デプロイ事前準備

前提条件
  • macOSで開発
  • Heroku の無料アカウントを取得済み
  • Ruby2.7を使用している。
  • Bundlerインストール済み
  • Git インストール済み(HerokuCLIを利用するために必要)
1-1 Heroku Command Line Interface(HerokuCLI)のインストール
$brew install heroku/brew/heroku

これで、ターミナルからherokuをコマンドラインで操作できるようになりました。

1-2ターミナルからHerokuにログイン
$heroku login
heroku: Press any key to open up the browser to login or q to exit
› Warning: If browser does not open, visit
› https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com

何かキーを押すようにと指示されるので、そのままキーを押します。ブラウザが自動で開
くので、”log in”ボタンをクリックしてください。
ターミナル上に”login succeeded”と表示されれば、ログイン成功です。
これで、ターミナル上で、gitとherokuコマンドを正しく扱うことができるようになります

参考:Getting Started on Heroku with Ruby | Heroku DevCenter

2.Heroku上にアプリケーションを作成。

Herokuにdockerイメージをデプロイする方法は2つあります。

  • コンテナレジストリ を使用して、事前にビルドされた Docker イメージを Heroku にデ プロイする方法。
  • heroku.yml を使用して、 Docker イメージをビルドして、Heroku にデプロイする方法 。 今回は、前者の方法を使用したので、前者の方法について記載します。
2-1 Heroku コンテナレジストリにログイン
$heroku container:login

これで、ローカルで作成したdockerイメージをheroku コンテナレジストリにアップする
ことができるようになりました。

2-2 Herokuでアプリケーションを作成
$heroku create アプリケーション名
Creating アプリケーション名... done, stack is heroku-20
https://アプリケーション名.herokuapp.com/ | https://git.heroku.com/アプリケーション名.git

ここで設定する、アプリケーション名については、heroku上でユニークな名前でなければいけません。
アプリケーション名に問題が無ければ、アプリケーションが作成されます。
この時、以下の2つのURLが生成されます。

  • 作成されたアプリケーションへのURL(https://アプリケーション名.herokuapp.com)
  • githubのリモートレポジトリへのURL(https://git.heroku.com/アプリケーション名.git)

3.データベースの設定

3-1 本番環境用のデータベース接続先の設定

実は、database.ymlファイルのproduction:の部分には、次のような説明書きが記載されています。

# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
#   production:
#     url: <%= ENV['MY_APP_DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#

この部分をちゃんと確認しないまま進めてしまい、この後、heroku上でrails db:migrateができないという問題に陥りました。。。。私の場合は、DATABASE_URLという環境変数を設定していなかったがために、以下のエラーが発生しました。

Mysql2::Error::ConnectionError: Unknown MySQL server host

この説明書きによると、railsにおける、本番環境のデータベースの接続先の設定方法は、以下の2つがあるようです。セキュリティーの観点からデータベースの接続先情報が外部から確認できない方法が取られています。

  • config/credentials.ymlを使う方法
  • DATABASE_URLという特別な環境変数に完全な接続先のURLを設定する方法

今回は後者の方法で設定しました。
ローカルのsrc/config/database.ymlファイルを本番環境用に次のように設定します。

production:
  <<: *default
  database: <%= ENV['APP_DATABASE'] %>
  username: <%= ENV['APP_DATABASE_USERNAME'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
  host: <%= ENV['APP_DATABASE_HOST'] %>
3-2 herokuに環境変数を登録

ここからは、公式のドキュメントを参考に進めていきます。

3-2-1 アプリケーションにデータべースをアドオンで追加
$heroku addons:create cleardb:ignite -a アプリケーション名
-----> Adding cleardb to sharp-mountain-4005... done, v18 (free)

データベースには、ClearDB MySQLを使用します。
ClearDB MySQLは、クラウド上で提供されている MySQL データベースです。今回は、学習用なので、無料プランのigniteを使用しています。

3-2-2 データべース接続先URLの確認

ターミナルでデータベースの接続先のURLを確認します。

$heroku config | grep CLEARDB_DATABASE_URL
CLEARDB_DATABASE_URL => mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true

データベースへの接続先のURLは、CLEARDB_DATABASE_URLという環境変数に格納されています。
URLについては、次のような構成になっています。

mysql://[ユーザー名]:[パスワード]@[MySQLのホスト名]/[サービスのインスタンス名]

ここで1点修正が必要です。現在、mysql2 gemを使用しているため。公式ドキュメントに記載のある通り、mysql:// をmysql2://と変更します。

If you’re using Ruby on Rails and the mysql2 gem, you will need to change the mysql:// scheme in the CLEARDB_DATABASE_URL to mysql2://

引用:ClearDB MySQL

既存の環境変数の上書きは、次のコマンドで行います。

$heroku config:set 環境変数=
$heroku config:set CLEARDB_DATABASE_URL=mysql2://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true
変更前 変更後
mysql:// mysql2://
3-2-3 herokuに環境変数の登録

それでは、ローカルのdatabase.ymlに設定した環境変数の値をherokuで登録していきます。
herokuに環境変数を登録するコマンドは次の通りです。

heroku config:add 環境変数名='値' -a アプリケーション名

下記のコマンドを一つずつ実行していきます。

heroku config:add APP_DATABASE='heroku_db' -a アプリケーション名

heroku config:add APP_DATABASE_USERNAME='adffdadf2341' -a アプリケーション名

heroku config:add APP_DATABASE_PASSWORD='adf4234' -a アプリケーション名

heroku config:add APP_DATABASE_HOST='us-cdbr-east.cleardb.com' -a アプリケーション名

次に、環境変数DATABASE_URLにCLEARDB_DATABASE_URLの値を代入します。ここが一番大事です。この設定をしていないとアプリケーションがデータベースと接続できずに、エラーが発生してしまいます。

$heroku config:add DATABASE_URL='mysql2://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true'
Adding config vars:
DATABASE_URL => mysql2://adffd...b?reconnect=true
Restarting app... done, v61.

最後に環境変数RAILS_SERVE_STATIC_FILESにtrueを設定します。

$heroku config:add RAILS_SERVE_STATIC_FILES='true' -a アプリケーション名

この環境変数を'true'で設定しておくことで、本番環境でassets:precompileが実行されるようになります。

cf. RAILS_SERVE_STATIC_FILESについて
config/environments/production.rb
  # Disable serving static files from the `/public` folder by default since
  # Apache or NGINX already handles this.
  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

Disable serving static files from the /public folder by default since
Apache or NGINX already handles this.

/public フォルダー配下の静的ファイルは、Apache or NGINXといったWEBサーバーに配信する責務があるため、rails(アプリケーションサーバー)では、デフォルトでは、配信できないようになっているようです。

今回は、railsでプリコンパイルした静的ファイルを扱いたいので、RAILS_SERVE_STATIC_FILESに値を設定しています。ちなみに、config.public_file_server.enabledがtrueになればいいので、RAILS_SERVE_STATIC_FILESの値は、なんでもいいです。

これで、必要な全ての環境変数をherokuに登録することができました!!

登録した環境変数は、下記コマンドで確認できます。

$heroku config -a アプリケーション名

4.dockerイメージのビルドとイメージのプッシュ

$heroku container:push web -a アプリケーション名

docker イメージをビルドして、コンテナレジストリにプッシュします。
コマンドを実行するディレクトリにdockerfileが存在することを確認してください。

cf.ローカル環境でdocker composeでWEBサーバーが起動している場合は、事前に終了してください。またpidファイルの削除も念の為に行ってください。
$docker compose down
$rm src/tmp/pids/server.pid

これをしていないと、herokuのWEBサーバーと設定がコンフリクトする可能性があるようです。

5.dockerイメージのリリース

$heroku container:release web -a アプリケーション名

コンテナレジストリのイメージをアプリケーションにリリースします。

6.db:migrateを実行する。

$heroku run bundle exec rake db:migrate RAILS_ENV=production -a アプリケーション名

マイグレーションファイルの内容からテーブルを作成、更新します。

7.Change Boot Timeout

ポート番号へのバインドはデフォルトで60秒で行われますが、herokuの無料プランのマシンパワーでは、60秒を超過してタイムアウトとなり、エラー発生の原因となることから、120秒にタイムアウト時間を延長しておきます。
https://tools.heroku.support/limits/boot_timeout

8.アプリケーションをブラウザで開く。

$heroku open -a アプリケーション名

以上で完了です!

参考ページ

引用:Heroku とは | Heroku
引用:IT業界初心者必見!クラウド型プラットフォームとは? | ITコラムdeパイプドビッツ|パイプドビッツ公式HP(pi-pe.co.jp)
参考:Getting Started on Heroku with Ruby | Heroku DevCenter
参考:Container Registry & Runtime (Docker Deploys) | Heroku Dev Center
参考:ClearDB MySQL | Heroku Dev Center

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0