rails7+dockerで開発環境構築

目次

マーケター、エンジニアを月1時間からジョインできるプラットフォーム

airteamは月1時間からマーケターやエンジニアに相談できるプラットフォーム。 雇うのはハードル高いけどプロをチームに入れたい。そんな経営者のためのサービスです。 相談にのる方も募集しています。

タスクなしだから月一時間からジョイン可能

作業はなくオンライン相談メイン。 月1時間からさっと経験者に継続的に相談できます。

多様な経験者を雇用するより何倍も早くチームに

あらゆるジャンルの経験者がいるので あなたのチームのノウハウの選択肢が広がります。

NDAはすでに締結済み、契約もスムーズ

契約の煩雑なやりとりはなく、NDAはすでに締結済み、書面のやりとりはありません。

下記の記事をもとにrails7+postgresの環境をdockerで構築していきます。

「Quickstart: Compose and Rails」
https://docs.docker.com/compose/rails/

「もう環境構築で悩まない!Dockerを使ってRails環境構築!」
https://www.youtube.com/watch?v=BZS8AHF3TTo

「DockerでのRuby on Rails環境構築を一つずつ詳解する」
https://qiita.com/daichi41/items/dfea6195cbb7b24f3419

全体像

全体像は下記

  • プロジェクトのフォルダを作り、下記fileを作成
    • Dockerfile
    • Gemfile
    • Gemfile.lock
    • entrypoint.sh
    • docker-compose.yml
  • dockerfileにてwebサーバーとdbをそれぞれコンテナビルド
  • rails読み込む用のgemfile、gemfilerockを作成。これをもとに作業ディレクトリにrailsnewされる。
  • $ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
  • docker-compose build
  • docker-compose upで起動
  • docker-compose run web rake db:createでdb作成

file設置

Gemfile

source 'https://rubygems.org'
gem 'rails', '~> 7.0.6'

railsのversionは入れたいversionに変更

Gemfile.lock

Gemfile.lockは空でおいておく。dockerfile起動時にgemfileをもとにここに追記されていく。

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. set -e: この行はスクリプトがエラーを出した場合にすぐに終了するように設定します。これにより、何か問題が発生した場合にスクリプトがそのまま進行するのを防ぎます。
  2. rm -f /myapp/tmp/pids/server.pid: この行はRailsサーバーが生成するPIDファイルを削除します。このファイルはサーバーが稼働中であることを示すものですが、コンテナが不適切に終了した場合などに残ってしまい、そのままだと新たにサーバーを起動できなくなる可能性があります。そのため、コンテナ起動時にこのファイルを削除することで、常にクリーンな状態からサーバーを起動できるようにしています。
  3. exec "$@": この行はスクリプトに渡された引数(この場合、DockerfileのCMDで指定されたコマンド)を実行します。このコマンドが実行されると、Railsサーバーが起動します。

docker-compose.yml

version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./docker/pg:/var/lib/postgresql
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: localhost
      POSTGRES_DB: test_db
  web:
    stdin_open: true
    tty: true
    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

Dockerfile

FROM ruby:3.2.2

RUN wget --quiet -O - /tmp/pubkey.gpg 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 -qq
RUN apt-get install -y nodejs postgresql-client yarn npm && npm install n -g && n 16.18.1
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
ENV BUNDLER_VERSION 2.1.4
RUN gem install bundler -v 2.1.4
RUN bundle update --bundler 
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. FROM ruby:3.2.2: Dockerイメージのベースとなるイメージを指定します。ここでは、Ruby 3.2.2がプリインストールされたイメージを使用します。
  2. RUN wget --quiet -O - /tmp/pubkey.gpg 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: Yarnの公開鍵をダウンロードし、aptのリポジトリに追加します。これにより、後のステップでYarnを安全にインストールできます。
  3. RUN apt-get update -qq: パッケージリストを更新します。-qqオプションは、出力を最小限に抑えるためのものです。
  4. RUN apt-get install -y nodejs postgresql-client yarn npm && npm install n -g && n 16.18.1: 必要なパッケージ(Node.js、PostgreSQLクライアント、Yarn、NPM)をインストールします。その後、NPMを使ってn(Node.jsのバージョン管理ツール)をインストールし、Node.jsのバージョンを16.18.1に設定します。
  5. RUN mkdir /myapp: /myappというディレクトリを作成します。
  6. WORKDIR /myapp: 作業ディレクトリを/myappに設定します。これにより、以降のRUN, CMD, ENTRYPOINT, COPY, ADD命令はこのディレクトリ内で実行されます。
  7. COPY Gemfile /myapp/GemfileCOPY Gemfile.lock /myapp/Gemfile.lock: ホストマシンのGemfileとGemfile.lockをコンテナの/myappディレクトリにコピーします。
  8. ENV BUNDLER_VERSION 2.1.4: Bundlerのバージョンを2.1.4に設定します。
  9. RUN gem install bundler -v 2.1.4: Bundlerをインストールします。
  10. RUN bundle update --bundler: Bundlerを更新します。
  11. RUN bundle install: Gemfileに記載されたgemをインストールします。
  12. COPY . /myapp: ホストマシンの現在のディレクトリ(.)の全てのファイルをコンテナの/myappディレクトリにコピーします。
  13. COPY entrypoint.sh /usr/bin/RUN chmod +x /usr/bin/entrypoint.sh: entrypoint.shをコンテナの/usr/bin/ディレクトリにコピーし、実行可能にします。このスクリプトはコンテナが起動するたびに実行されます。
  14. ENTRYPOINT ["entrypoint.sh"]: コンテナが起動するときに実行されるコマンドを設定します。ここでは、上記でコピーしたentrypoint.shが実行されます。
  15. EXPOSE 3000: コンテナの3000番ポートを開放します。これにより、ホストマシンからコンテナの3000番ポートにアクセスできるようになります。
  16. CMD ["rails", "server", "-b", "0.0.0.0"]: コンテナが起動した後に実行されるデフォルトのコマンドを設定します。ここでは、Railsサーバーを起動します。-b 0.0.0.0オプションにより、サーバーはすべてのネットワークインターフェースでリッスンします。

macのm1チップかどうかでも微妙に挙動が変わるので注意。上記だとm1,m2でもいける。詳しくは下記

https://qiita.com/hamuki72718/items/328b09308f73f5ace397

rails new

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

bundle install

docker-compose build

dockerをbuildした際にbundle installされる

dbの書き換え

下記に変更してdbとの接続情報を設定。

config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: localhost
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  url: <%= ENV['CI_DATABASE_URL'] %>
  database: myapp_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

db:create & db:migrate

下記2つのコマンドでdbを作成。docker-compose upでwebサーバーを起動させてそのwebでrails db:createでdb作成

docker-compose up
docker-compose run web rails db:create

localhost:3000

localhost:3000を叩くとサイトが見れます。

つまずきポイント

could not translate host name “db” to address: Name or service not

「could not translate host name “db” to address: Name or service not」というエラーが出たらdb周りの設定が違う可能性が高い

database.ymlを下記にしたら解決

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: localhost
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

Webpacker::Manifest::MissingEntryError

docker-compose upで立ち上げた際に「Webpacker::Manifest::MissingEntryError」とエラーが

https://zenn.dev/kantafukazawa/articles/8697bc02c23829

webpackがinstallされていないことが原因で上記の記事のようにdockerでwebpackをinstallするか、つど、docker-compose run webでdocker内部でinstallするかがある。今回はdocker内でinstallするのを採用

docker-compose run web rails webpacker:install

Overwrite /myapp/config/webpacker.yml? (enter "h" for help) [Ynaqdhm]
Overwrite /myapp/babel.config.js? (enter "h" for help) [Ynaqdhm] y

上書きするかと質問がくる。これは最新のwebpackにするためにy。

あとはdocker-compose up