はじめに
今まで、全然理解できていなくて逃げてたDockerに関して、しっかり理解していこうと思います。
コレまで、便利なんだろうなと思いながらも、逃げてました。
なので、開発環境では使いこなせるスキルにまでは理解したいと思います。
あと、暗記してたDockerコマンドを1つ1つ理解していきます。
以下のような順番で勉強していきます。
- Dockerの概要(1/9)
- Dockerの基本操作(イメージの作成, コンテナの起動, 停止, 削除)(2/9)
- Dockerの基本操作(ログの出力, コンテナの中でプロセスを実行する方法, 使用していない Docker オブジェクトの削除)(3/9)
- Dockerfileを使用したサーバー構築(座学編)(4/9)
- Dockerfileを使用したサーバー構築(実践編)(5/9)
- Docker Composeの概要(座学編)(6/9)
- Docker Composeのよく使う基本操作(7/9)
- Docker Composeを使ってRailsの環境を構築する(8/9)
-
Docker上に構築したRailsをHeroku(本番環境)にデプロイ(公開)する(9/9)
今ここ
本番環境はHerokuを使う
今回はHeroku上に、Dockerコンテナを起動させて、Webアプリケーションを公開していきます。
HerokuはサーバやOSやミドルウェアを自動で構築・管理してくれるサービスです。
以前の記事で作成したRailsのアプリをHeroku上に本番公開していきます。
Docker上に構築したRailsをHeroku(本番環境)にデプロイ(公開)するまでの流れ
- 準備
- Herokuにログイン
- Herokuアプリを作成
- HerokuにMySQLを追加し設定する
- Dockerfileを開発環境用と本番用に用意
- Dockerイメージをビルド・リリース
準備
Herokuのログイン(もしくはアカウント登録)とDBはMySQLを使うので無料範囲ではありますが、クレカを紐づける必要があります。
続いて、Heroku CLIのインストールをしておきます。
Herokuにログイン
ローカルのターミナルからHerokuにログインできるようにしておきます。
heroku login
ブラウザ経由でログインが完了。
続いて、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
...
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
確認できました。
Dockerfileを開発環境用と本番用に用意
処理が本番とローカルで若干違うのでそれぞれごとに設定していきます。
projectのTOP階層にstart.sh
というファイルを一旦作成します。
ここに、本番環境特有の処理を書いておきます。
次に、Dockerfile
を修正します。環境変数を設定したいので
before
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
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に変更(伸ば)しておきましょう。
できた。
続いて、ローカルの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に合わせたページを作成してそれを表示させたら完成です!
(今はアクセスできません)
お疲れ様でした!
さいごに
4連休を利用して、Dockerを理解できるようにがんばりました。
最終的に、4日で9記事書くことができました。
記事作成が目的ではなく、あくまでも開発環境で使いこなせるスキルにすること。丸暗記してたDockerコマンドを1つ1つ理解して使えるようになることが目的です。
実務でいきなりバリバリに使えるようになるのはムズいかもしれません。
ですが、かつての自分は概要の理解も無いし、実際に手も動かしていなかったです。
この4日を通じて一定の理解を得たので実務に以下していきます。
とりあへず完走した自分を褒めたい。
アウトプット100本ノック実施中