64
69

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

知識0から始めるRails on Docker

Last updated at Posted at 2019-01-26

#はじめに

Railsの勉強を始めようと思ったが、どうせならDockerを使って仮想環境で開発したい。
しかしどちらも実務で使ったことがないためよくわからない(というかRubyすら触ったことがない)。

ということで、一から調べてみた。RailsとDockerの欲張りセット。
筆者はMacBookProを使っているため、MacOS向けの記事となります。

tl;td

  • Rubyにまつわる各用語の確認、ローカル環境でRailsの導入・起動方法の確認
  • 手動でDocker上でのRailsの導入・起動方法の確認
  • dockerfileにRailsの導入・起動情報を文書化して格納し、docker-composeから呼び出して起動

対象読者

  • わたし
  • これからRailsを勉強しようという方
  • これからDockerを勉強しようという方

ロードマップ(超簡易版)

最終目標:Dockerによる仮想環境上でRails serverを起動し、開発できるようにする
※RailsのデフォルトサーバーはPumaです。この記事ではデフォルトのままなのでPumaを使いますが、便宜上「Rails server」と呼称します。

  • Railsをローカル環境で起動する
    • ローカル環境にRubyを導入する
    • ローカル環境にRailsを導入する
    • Railsプロジェクトを作成し、Rails serverを起動
  • Docker環境を構築して仮想環境でRails serverを起動する
    • ローカル環境にDockerを導入する
    • DockerでRubyを使える仮想環境を構築する
    • 仮想環境でRails serverを起動する
  • dockerfiledocker-composeを使ってコマンド一つでRails serverを起動する
    • dockerfileを作成する
    • docker-compose.ymlを作成し、起動する

Railsをローカル環境で起動する

これについては各所でがっつり解説されているので、ここでは流れ・用語の説明と参考資料の紹介にとどめます。
なお、この章の目的はRubyにまつわる各用語とRails serverの起動までの流れについて確認することが目的なので、既にバッチリの方は飛ばしてください。
参考資料:Ruby初学者のRuby On Rails 環境構築【Mac】

ローカル環境にRubyを導入する

流れ
Homebrewの導入(更新)-> rbenvの導入 -> Rubyの導入

ざっくりHomebrew解説

ざっくりrbenv解説

ローカル環境にRailsを導入する

流れ
Bundlerの導入 -> BundlerでGemfileの作成 -> Gemfileの編集 -> Gemの取得(Railsの導入)

ざっくりGem解説

ざっくりBundler解説

Railsプロジェクトを作成し、Rails serverを起動

流れ
Railsからプロジェクトを作成 -> Rails serverの起動 -> 接続確認

Docker環境を構築して仮想環境でRails serverを起動する

ローカル環境にDockerを導入する

Docker公式から最新版を取得しましょう。
アカウントの登録が必要です。

なお、Dockerの基礎的な仕組みやコマンドなどについては、以下の参考資料がおすすめです。

参考資料:Dockerでプログラマが最低限知るべきことが、最速でわかるチュートリアル
docker

参考資料:【図解】Dockerの全体像を理解する -前編-

ざっくりDocker解説

  • 仮想環境の構築・管理を行うツール
  • 擬似的に様々な環境を構築することができ、ローカル環境と本番環境との差異を減らすことができる
  • 「本番環境で急に動かなくなった問題」や「環境構築面倒すぎる問題」の救世主……らしい

DockerでRubyを使える仮想環境を構築する

参考資料:RailsアプリをDockerで開発するための手順

ここからが本題です。
まずは利用するイメージを決めます。Docker Hubにrubyという便利なイメージが用意されているので、ありがたく使わせていただきましょう。

rubyイメージの取得
$ docker pull ruby

イメージが取得できたら早速run……する前に、このイメージについて調べましょう。

イメージの情報を出力
$ docker inspect ruby

コマンドを実行すると大量の文字が吐き出されます。
目眩がするかもしれませんが、頑張って大事な記述を確認しましょう。注目するのは以下の場所です。

"ContainerConfig": {
……
  "Env": [
                "PATH=/usr/local/bundle/bin:/usr/local/bundle/gems/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "RUBY_MAJOR=2.6",
                "RUBY_VERSION=2.6.0",
                "RUBY_DOWNLOAD_SHA256=acb00f04374899ba8ee74bbbcb9b35c5c6b1fd229f1876554ee76f0f1710ff5f",
                "GEM_HOME=/usr/local/bundle",
                "BUNDLE_PATH=/usr/local/bundle",
                "BUNDLE_SILENCE_ROOT_WARNING=1",
                "BUNDLE_APP_CONFIG=/usr/local/bundle"
            ],
……
RUBY_VERSION=2.6.0

Rubyのバージョンを示しています。Docker Hubでも確認できますが、イメージ本体にも情報がしっかり記されていますね。
このバージョンは重要なので覚えておきましょう。あるいはイメージをpullする段階で指定してあげてもいいでしょう。

BUNDLE_PATH=/usr/local/bundle

Bundlerのパスが指定されています。BundlerによるGemfileを使ったGem管理を行えることがわかりますね。

ではこのイメージからコンテナを起動しましょう。
適当な名前のディレクトリを作成し、ターミナルの作業フォルダとします。
以降はプロジェクト名をproject_nameとします。
project_name以外の名前でも構いません。本記事ではこの名前で統一するということです。

rubyイメージからコンテナを起動
$ docker run -i -t --name TEST -p 3000:3000 -v "$PWD":/usr/src/project_name ruby /bin/bash

まずは各オプションについて。

-i       :コンテナのSTDIN(標準入力)にアタッチ。標準入力に入力できる状態にするということ。
-t       :疑似ターミナル (pseudo-TTY) を割り当て。ターミナル画面で操作できるようにするということ。
--name   :コンテナの名前。今回は'TEST'を指定。
-p       :ポートの指定。今回は3000ポートを解放しています。
-v       :ボリュームの指定。[ホストPCのディレクトリ指定]:[コンテナ内のディレクトリ指定]。
/bin/bash:コンテナ起動後に実行するコマンド。今回はシェルを指定。

上記の説明は簡略したもので語弊を含むので、気になった項目は別途調べることをお勧めします。
-i-tの二つはセットで使う(-it)ことが多いので是非覚えておきましょう。
ボリュームについては概念が難しいですが、とりあえず[ホストPCで指定したディレクトリ]を[コンテナ内で指定したディレクトリ]として扱えるようにする、程度の理解でいいと思います。

参考資料:Dockerリファレンス

うまく起動できたら下のような状態になるはずです。

root@03eb04059b1f:/#

コンテナの中のターミナルを操作しているようなイメージですね。
コンテナの中から一旦抜ける時はcontrol + pq、再接続するときは$ docker attach [コンテナの指定]です。
exitでも抜けられますが、コンテナが停止してしまうため注意。停止した場合、ポートを閉じてしまうようです。
$ docker execでもコンテナに接続できます。ただし、プロセス接続するごとにプロセスが増えます。

仮想環境でRails serverを起動する

それでは今起動したコンテナでRails serverの準備をしましょう。
先ほどコンテナを起動した際に、コンテナ内のproject_nameディレクトリをボリュームとして指定しました。
指定したディレクトリが作成されているはずなので、そこまで移動しましょう。

Railsプロジェクトの確認
$ cd /usr/src/project_name

このディレクトリにRailsプロジェクトを作成していきます。
まずは何をするにもGemfileが必要なので、Bundlerを使って作成しましょう。

Gemfileの作成
$ bundle init

次にRailsを導入していきます。
Gemfileを編集する必要がありますが、これはコンテナ内で行う必要はありません。Gemifileを作成したディレクトリはコンテナ起動時にホストPC側のディレクトリとセットでボリューム指定したため、ホストPC側の指定したディレクトリにもGemfileが作成されています。このGemfileを編集するだけでOKです。

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

- # gem "rails"
+ gem "rails"
コンテナ内のGemfile確認に反映されているか確認
$ cat Gemfile

これでGemfileの準備ができたので、GemのインストールとRailsプロジェクトの作成を行いましょう。

Gemのインストール
$ bundle install
$ bundle exec rails new .

rails exec .は作業ディレクトリに対してRailsプロジェクトを作成します。
実行するとGemfileの上書き確認をされるので許可しましょう。

ローカル環境ではこの時点でRails serverを起動できましたが、rubyイメージから作成したコンテナではまだRails serverは起動できません。
ですが、なぜ起動できないか確認するためにも一度試してみましょう。

起動確認(失敗する).
$ bundle exec rails server
エラーメッセージ(最後のみ抜粋)
/usr/src/project_name/vendor/bundle/ruby/2.6.0/gems/execjs-2.7.0/lib/execjs/runtimes.rb:58:in `autodetect': Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

ExecJS::RuntimeUnavailableというエラーについて調べてみると、どうやらJavaScriptランタイムというものが必要のようです。
今回はnode.jsを導入することにしましょう。
参考資料:rails sコマンド実行時に「Could not find a JavaScript runtime.」とエラーが出る場合の対処法

rubyイメージではyumコマンドは対応していないようなので、apt-getを使ってインストールしましょう。
参考資料:apt-get - パッケージの操作・管理 - Linuxコマンド

node.jsのインストール
$ apt-get update
$ apt-get install nodejs

完了したら今度こそRails serverが起動できるはずです。

Rails_server起動
$ bundle exec rails server

http://localhost:3000/に接続して起動できているか確認しましょう。

dockerfile と docker-compose を使ってコマンド一つでRails serverを起動する

ここからは今まで行ってきたことを設定として文書化していきます。
先ほどまで使用していたコンテナはもう使わないので、$ exitで停止しておきましょう。
ただし、作成したRailsプロジェクトはそのままにしておいてください。

参考資料:Dockerfile リファレンス
参考資料:Compose ファイル・リファレンス
参考資料:RailsアプリをDockerで開発するための手順

dockerfile を作成する

まず、前の章で行ったことを整理しておきましょう。

  • rubyイメージからコンテナを作成(本記事ではバージョン2.6.0)
  • ポート3000:3000を開放し、ボリュームを指定してコンテナを起動
  • コンテナ内でRailsプロジェクトを作成
  • コンテナにnode.jsをインストール
  • Rails serverを実行

dockerfileを書くということは、これらの作業を文書化していくということです。

それではdockerfileを書いていきます。Railsプロジェクトを作成したディレクトリにdockerfileという名前でファイルを作成し、編集していきます。
まずは使用したイメージの情報です。

dockerfile
FROM ruby:2.6.0

:2.6.0はバージョン情報です。指定しなければ最新版が自動で選択されますが、固定させた方がいいでしょう。
これはRubyのバージョンと同じなので、もし違うバージョンからRailsプロジェクトを作成したならそのバージョンに合わせてください。

次にポートの開放とボリューム指定ですが、dockerfileではホストPCのディレクトリを指定することはできません(後でdocker-compose.ymlで指定します)。よって、ここではポートの開放だけを行います。

dockerfile
FROM ruby:2.6.0

EXPOSE 3000

ここでポートの開放を行なっても、runコマンドやdocker-compose.ymlで指定しなければ直接接続できないので注意してください。

次はコンテナ内でRailsプロジェクト作成ですが、これは後でボリューム指定により共有する予定なので必要ありません。
ですが、Gemfileが無くてはGemのインストールができず、railsコマンドが実行できません。
そこで、Gemfileだけをコンテナ内にコピーしてインストールすることにします。

dockerfile
FROM ruby:2.6.0

ENV APP_ROOT /usr/src/project_name 

WORKDIR ${APP_ROOT}

COPY Gemfile ${APP_ROOT}
COPY Gemfile.lock ${APP_ROOT}

RUN bundle install

EXPOSE 3000

各コマンドは以下の通りです。

ENV [key] [value] …… 環境変数の定義。
WORKDIR [ディレクトリ指定] …… 作業ディレクトリの指定
COPY [ソース指定] [保存先指定] …… ファイルのコピー。
RUN [コマンド] …… コマンドの実行。

これでコンテナ内でもrailsコマンドが利用できるようになります。

最後にnode.jsのインストールとRails serverの起動です。

dockerfile
FROM ruby:2.6.0

ENV APP_ROOT /usr/src/project_name 

WORKDIR ${APP_ROOT}

RUN apt-get update && \
    apt-get install -y nodejs

COPY Gemfile ${APP_ROOT}
COPY Gemfile.lock ${APP_ROOT}

RUN bundle install

EXPOSE 3000

CMD bundle exec rails server

Railse sever の起動がRUNではなくCMDなのは、コンテナの立ち上げが完了してから実行してほしいからです。
もしRUNで書いてしまうとそこで動作が止まってしまい、いつまでもコンテナが立ち上がらないということになってしまいます。

では、これでうまく動作するかどうか確認してみましょう。

dockerfileからイメージの作成と起動
$ docker build .

エラーが出ずにRails serverの起動までできればOKです。

docker-compose.yml を作成し、起動する

では、先ほど作成したdockerfileを使ってdocker-compose.ymlを作っていきましょう。
先ほどと同じく、Railsプロジェクトのディレクトリに作成し、以下の通りに編集してください。

docker-compose.yml
app:
  build: .
  ports: 
    - '3000:3000'
  volumes: 
    - .:/usr/src/project_name
app: …… アプリケーションの名前。今回はappとした。
build: …… docker-composeのパス指定。今回は同一ディレクトリにある。
ports: …… 開放するポートの指定。
volumes: …… ボリュームの指定。

これで完了です。では起動してみましょう。

docker-composeからの起動
$ docker-compose up -d

http://localhost:3000/に接続して、いつものアレが表示されたらOKです!
ちなみに、ホストPCのディレクトリを参照しているため、ファイルを編集すると即座に反映されます。Gemfileと同じですね。

おわりに

というわけで、起動できました。とりあえず動いたので満足。

64
69
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
64
69

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?