Docker&Rails6の環境を構築してみる。


本記事について(お断り)

この記事は、しがないプログラミング初心者がお勉強よろしくプログラミング・技術に触れるべく、行ったことの備忘録として書き綴ったものです。ご了承ください。
ご指摘は甘んじて受け入れます🙇‍♂️

目的

ここではひとまず自分で必要なファイルの準備から、Railsのアプリケーションを起動できるまでを目指します。

参考

今回の作業は下記の記事を参考にさせていただいてます。とても勉強になりました。ありがとうございます。
Quickstart: Compose and Rails | Docker Documentation
https://qiita.com/kodai_0122/items/795438d738386c2c1966#2-2-bundle-install
https://qiita.com/at-946/items/2fb75cec5355fad4050d

環境構築手順

1.準備

1-1フォルダの作成

まずは作業を行うためのフォルダを任意に作成します。
作成したフォルダに移動しておきます。

$ mkdir myapp
$ cd my app

1-2Dockerfileの作成

フォルダ内にDockerfileを作成します。
公式ページ内:クイックスタートを参考にバージョンだけ変えて作成しました。

Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

1−3Gemfileの作成

ここではインストールするRailsのバージョンを6に指定します。あわせてGemfile.lockも作成しておきます。中身は何も書かなくてOKです。

Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6'
$ touch Gemfile.lock

1-4entrypoint.shの作成

コンテナが起動した時に、Railsのserver.pidを毎回削除してくれる様です。(英語得意ではないので書いてあること違ってたらすいません)よくこのファイルが残っててコンテナの中身を消しにいくの大変だった思い出。

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

1-5docker-compose.ymlの作成

docker-compose.ymlは、魔法の様なファイルです。必要なアプリ(web、dbアプリ)を構成するサービスやそのイメージをまとめて実行してくれます。(英語得意ではないn自分がこのファイルを使ってみての感覚で話してるとこもあるので、誤解を招く様な表現があったらすみません)

docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

ここでは、DB(PostgreSQL)、webの二つを実行してもらう様記載します。

ここまでできたら、ファイルの準備は完了です。

2.プロジェクトのビルド

2-1rails new

docker-compose run コマンドを使って、rails newしていきます。

$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle

これで、myappフォルダの中に見慣れたフォルダ構成ができてきます。
ターミナルの最後で、以下の様にメッセージを出してきます。

Could not find gem 'pg (>= 0.18, < 2.0)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.

bundle installしてねというメッセージでした。

2-2bundle install

Dockerfileでbundle installする様記述してあるため、イメージをビルドする際に勝手にやってくれます。

$ docker-compose build

2-3DB接続設定

Railsのconfg/database.ymlを、以下に書き換えます。

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test
.
.
.

2-4Dockerコンテナ起動

$ docker-compose up

するとなんだか色々エラーだと言われました。

db_1   | Error: Database is uninitialized and superuser password is not specified.
.
.
.
web_1  | /usr/local/bundle/gems/webpacker-4.2.2/lib/webpacker/configuration.rb:95:in `rescue in load': Webpacker configuration file not found /myapp/config/webpacker.yml. Please run rails webpacker:install Error: No such file or directory @ rb_sysopen - /myapp/config/webpacker.yml (RuntimeError)

上のエラーは、PostgreSQLのパスワードが必要なために出てきたメッセージです。confg/database.ymlに追記しておきます。

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password  # <= この部分
  pool: 5

もう一つのエラーは、Rails6からWebpackerがデフォルトで導入されるため、Webpackerのインストールを求めるものでした。
で、そのWebpackerのインストールにはyarnやNode.jsのインストールが必要だそうです。

それらに対応するため、Dockerfileを編集する必要があります。

Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
# yarnインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y yarn
# Node.jsインストール
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
  apt-get install nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

それではWebpackerをインストールしてみます。

$ docker-compose stop
$ docker-compose down
$ docker-compose run web bundle exec rails webpacker:install
.
.
Webpacker successfully installed 🎉 🍰

無事Webpackerのインストールに成功しました。
もう一度、コンテナを起動します。

$ docker-compose up

2-5DB作成

DBを作成します。これで完了です。

$ docker-compose run web rails db:create
Starting myapp_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'

2−6アクセスしてみる
ブラウザでhttp://localhost:3000/にアクセスしてみます。お馴染みの画面が出迎えてくれ無事成功しました!


Yay!

まとめ

DockerでRails6の環境を作成してみました。
実際やってる時は、作業フォルダの名前とDockerfileに指定しているフォルダ名が違ったりして、色々と他にも手こずってました。他の方の一助になれば幸いです。