18
18

More than 1 year has passed since last update.

もう逃げない。基礎から学ぶDocker入門 / Docker上に構築したRailsをHeroku(本番環境)にデプロイ(公開)する(9/9)

Last updated at Posted at 2021-09-26

はじめに

今まで、全然理解できていなくて逃げてたDockerに関して、しっかり理解していこうと思います。

コレまで、便利なんだろうなと思いながらも、逃げてました。

なので、開発環境では使いこなせるスキルにまでは理解したいと思います。

あと、暗記してたDockerコマンドを1つ1つ理解していきます。

以下のような順番で勉強していきます。

本番環境はHerokuを使う

今回はHeroku上に、Dockerコンテナを起動させて、Webアプリケーションを公開していきます。

スクリーンショット 2021-09-26 19.57.51.png

HerokuはサーバやOSやミドルウェアを自動で構築・管理してくれるサービスです。

以前の記事で作成したRailsのアプリをHeroku上に本番公開していきます。

Docker上に構築したRailsをHeroku(本番環境)にデプロイ(公開)するまでの流れ

  • 準備
  • Herokuにログイン
  • Herokuアプリを作成
  • HerokuにMySQLを追加し設定する
  • Dockerfileを開発環境用と本番用に用意
  • Dockerイメージをビルド・リリース

準備

Herokuのログイン(もしくはアカウント登録)とDBはMySQLを使うので無料範囲ではありますが、クレカを紐づける必要があります。

続いて、Heroku CLIのインストールをしておきます。

Herokuにログイン

ローカルのターミナルからHerokuにログインできるようにしておきます。

heroku login

ブラウザ経由でログインが完了。

スクリーンショット 2021-09-26 21.33.06.png

続いて、Herokuコンテナレジストリにログインします。

heroku container:login

Login Succeeded

SucceededでたらOKです。

Herokuアプリを作成

続いて、Herokuアプリ、Herokuは運用したいサービスをアプリという単位で管理しています。

heroku create rails-docker-ryosuketter

https://rails-docker-ryosuketter.herokuapp.com/ | https://git.heroku.com/rails-docker-ryosuketter.git

コレで完成です。

HerokuにMySQLを追加し設定する

Herokuでは、DBはアドオンという形式で追加できます。

その中でもMySQLの場合はほとんどが有料ですがcleardbアドオンのigniteというプランはタダなのでそれを使います。

注意 igniteプランのMySQLのバージョンは5系 しかしコレまでの開発環境ではMySQLは8系で作ってました 本当は揃えた方がいいですが、今回はバージョン違いで困らないので、バージョンは揃えません

アドオンを追加します。

追加のコマンド

heroku addons:create cleardb:<プラン名> -a <アプリ名>

実際のコマンド

heroku addons:create cleardb:ignite -a rails-docker-ryosuketter

Creating cleardb:ignite on ⬢ rails-docker-ryosuketter... free
Created cleardb-cylindrical-02285 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

コレで無事アドオンを追加できました。

次に、DBの設定をしておきます。

本番環境のRailsの接続先を変えます。

環境によって変えたいので、環境変数にして渡すようにします。

before

production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>

after

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'] %>

hostも追加されていますね。これで、環境変数の設定が完了しました。

あとは、Herokuに環境変数を渡せば接続できると思います。

DBの接続先情報はHerokuで確認できます。

heroku config -a rails-docker-ryosuketter

=== rails-docker-ryosuketter Config Vars
CLEARDB_DATABASE_URL: mysql://b86d7f293af671:3f7958e7@us-cdbr-east-04.cleardb.com/heroku_b04f71f6e232c42?reconnect=true

herokuにDBの情報を登録していきます。

$ heroku config:add APP_DATABASE='heroku_b04f71f6e232c42' -a rails-docker-ryosuketter
Setting APP_DATABASE and restarting ⬢ rails-docker-ryosuketter... done, v5
APP_DATABASE: heroku_b04f71f6e232c42

$ heroku config:add APP_DATABASE_USERNAME='b86d7f293af671' -a rails-docker-ryosuketter
Setting APP_DATABASE_USERNAME and restarting ⬢ rails-docker-ryosuketter... done, v6
APP_DATABASE_USERNAME: b86d7f293af671

$ heroku config:add APP_DATABASE_PASSWORD='3f7958e7' -a rails-docker-ryosuketter
Setting APP_DATABASE_PASSWORD and restarting ⬢ rails-docker-ryosuketter... done, v7
APP_DATABASE_PASSWORD: 3f7958e7

$ heroku config:add APP_DATABASE_HOST='us-cdbr-east-04.cleardb.com' -a rails-docker-ryosuketter
Setting APP_DATABASE_HOST and restarting ⬢ rails-docker-ryosuketter... done, v8
APP_DATABASE_HOST: us-cdbr-east-04.cleardb.com

環境変数が設定されているか確認

heroku config -a rails-docker-ryosuketter

=== rails-docker-ryosuketter Config Vars
APP_DATABASE:          heroku_b04f71f6e232c42
APP_DATABASE_HOST:     us-cdbr-east-04.cleardb.com
APP_DATABASE_PASSWORD: 3f7958e7
APP_DATABASE_USERNAME: b86d7f293af671
CLEARDB_DATABASE_URL:  mysql://b86d7f293af671:3f7958e7@us-cdbr-east-04.cleardb.com/heroku_b04f71f6e232c42?reconnect=true

確認できました。:relaxed:

Dockerfileを開発環境用と本番用に用意

処理が本番とローカルで若干違うのでそれぞれごとに設定していきます。

projectのTOP階層にstart.shというファイルを一旦作成します。

ここに、本番環境特有の処理を書いておきます。

次に、Dockerfileを修正します。環境変数を設定したいので

before

Dockerfile
FROM ruby:2.7

# Yarnのレポジトリを有効化。レポジトリのGPGキーをcurlコマンドを使って取得する(debianはubuntuと互換性がある)
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -

# YarnのAPTパッケージレポジトリを自分のシステムに追加。teeコマンドを使って書き込み。
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

# レポジトリがシステムに加えられたらパッケージリストをアップデートしてからYarnをインストールする
RUN apt-get update -qq
RUN apt-get install -y nodejs yarn

# Dockerコンテナ上の作業ディレクトリ
WORKDIR /app

# ローカル開発環境の./src配下の内容をDockerコンテナ上の/appにコピー
COPY ./src /app

# gemファイルのインストール
RUN bundle config --local set path 'vendor/bundle' && bundle install

after

Dockerfile
FROM ruby:2.7

# 環境変数の設定
ENV RAILS_ENV=production

# Yarnのレポジトリを有効化。レポジトリのGPGキーをcurlコマンドを使って取得する(debianはubuntuと互換性がある)
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -

# YarnのAPTパッケージレポジトリを自分のシステムに追加。teeコマンドを使って書き込み。
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

# レポジトリがシステムに加えられたらパッケージリストをアップデートしてからYarnをインストールする
RUN apt-get update -qq
RUN apt-get install -y nodejs yarn

# Dockerコンテナ上の作業ディレクトリ
WORKDIR /app

# ローカル開発環境の./src配下の内容をDockerコンテナ上の/appにコピー
COPY ./src /app

# gemファイルのインストール
RUN bundle config --local set path 'vendor/bundle' && bundle install

# ローカル開発環境のstart.shの内容をDockerコンテナ上の/start.shにコピー
COPY start.sh /start.sh
# Docker側の下記のファイルに実行権限を渡すので権限を変更する
RUN chmod 744 /start.sh
# 実行
CMD ['sh', '/start.sh']

Dockerファイルはif文の条件を書きにくいのでshでやらせています。

ですが、本番環境用の処理をさせたいので、このファイルを作成しました。

本番環境の時だけ下記の処理を実行させる必要があるので記載しました。

bundle exec rails assets:precompile

最後はRailsでサーバを起動させています。

Dockerファイルでは、実務でも本番環境にだけ特定の処理をさせたい時は.shファイルにその処理をさせる方法はよくあるらしい。

もしくは、環境ごとDockerファイルを分ける方法もあるみたいです。

では、本番環境でassets:precompileが を させたいので、以下のコマンド(環境変数の追加)を実行します。

heroku config:add RAILS_SERVE_STATIC_FILES='true' -a rails-docker-ryosuketter

Setting RAILS_SERVE_STATIC_FILES and restarting ⬢ rails-docker-ryosuketter... done, v9
RAILS_SERVE_STATIC_FILES: true

追加されましたね。

heroku config -a rails-docker-ryosuketter
=== rails-docker-ryosuketter Config Vars
APP_DATABASE:             heroku_b04f71f6e232c42
APP_DATABASE_HOST:        us-cdbr-east-04.cleardb.com
APP_DATABASE_PASSWORD:    3f7958e7
APP_DATABASE_USERNAME:    b86d7f293af671
CLEARDB_DATABASE_URL:     mysql://b86d7f293af671:3f7958e7@us-cdbr-east-04.cleardb.com/heroku_b04f71f6e232c42?reconnect=true
RAILS_SERVE_STATIC_FILES: true

続いて、herokuをデプロイした時にPORT番号をサーバがバインドするのですが、それがデフォルトだと60sと指定されています。

それだと、タイムアウトしてしまうエラーが起こりやすいので、今のうちにその設定を120sに変更(伸ば)しておきましょう。

スクリーンショット 2021-09-26 23.25.33.png

スクリーンショット 2021-09-26 23.27.18.png

できた。

続いて、ローカルのwebサーバを削除します。

なぜか?

ローカルでwebサーバが起動しているとherokuでwebサーバが起動しない可能性があるらしい。

docker-compose down

[+] Running 6/6
 ⠿ Container rails_docker_web_run_d27f4d8e6fab  Removed                                           3.8s
 ⠿ Container rails_docker_web_run_102cb7842969  Removed                                           0.2s
 ⠿ Container rails_docker_web_1                 Removed                                           1.1s
 ⠿ Container rails_docker_web_run_27c0fb3bd90f  Removed                                           0.2s
 ⠿ Container rails_docker_db_1                  Removed                                           2.4s
 ⠿ Network rails_docker_default                 Removed                                           0.4s

念の為、以下のファイルも削除しましょう。

rm src/tmp/pids/server.pid

これで、Dockerfileを開発環境用と本番用に用意が完了しました。

Dockerイメージをビルド・リリース

まず、Dockerイメージをビルドして、コンテナレジストリにpushしていきます。

heroku container:push web -a rails-docker-ryosuketter

latest: digest: sha256:c455d738b066901456f59967b176ea84c0559cda0c575b231f62b5ea2302f385 size: 3888
Your image has been successfully pushed. You can now release it with the 'container:release' command.

コレで、Dockerイメージをビルドして、コンテナレジストリにプッシュするところまで完成しました。

続いて、コンテナレジストリにあげたイメージから、herokuの方にDockerコンテナをリリースしていきます。

heroku container:release web -a rails-docker-ryosuketter

Releasing images web to rails-docker-ryosuketter... done

これで、Dockerのコンテナをherokuにリリースできました。

続いて、DBのマイグレーションをしていきます。

heroku run bundle exec rake db:migrate RAILS_ENV=production -a rails-docker-ryosuketter

Running bundle exec rake db:migrate RAILS_ENV=production on ⬢ rails-docker-ryosuketter... up, run.5407 (Free)

では、herokuのアプリを開いていきます。

リリースしたherokuのアプリケーションを見てみます。

heroku open -a rails-docker-ryosuketter

最後にrouteに合わせたページを作成してそれを表示させたら完成です!

(今はアクセスできません)

お疲れ様でした!

:clap_tone1:

さいごに

4連休を利用して、Dockerを理解できるようにがんばりました。

最終的に、4日で9記事書くことができました。

記事作成が目的ではなく、あくまでも開発環境で使いこなせるスキルにすること。丸暗記してたDockerコマンドを1つ1つ理解して使えるようになることが目的です。

実務でいきなりバリバリに使えるようになるのはムズいかもしれません。

ですが、かつての自分は概要の理解も無いし、実際に手も動かしていなかったです。

この4日を通じて一定の理解を得たので実務に以下していきます。

とりあへず完走した自分を褒めたい。

:relaxed:

アウトプット100本ノック実施中

18
18
1

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
18
18