下記の記事をもとに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 "$@"
-
set -e
: この行はスクリプトがエラーを出した場合にすぐに終了するように設定します。これにより、何か問題が発生した場合にスクリプトがそのまま進行するのを防ぎます。 -
rm -f /myapp/tmp/pids/server.pid
: この行はRailsサーバーが生成するPIDファイルを削除します。このファイルはサーバーが稼働中であることを示すものですが、コンテナが不適切に終了した場合などに残ってしまい、そのままだと新たにサーバーを起動できなくなる可能性があります。そのため、コンテナ起動時にこのファイルを削除することで、常にクリーンな状態からサーバーを起動できるようにしています。 -
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"]
各行でやっていることは下記
-
FROM ruby:3.2.2
: Dockerイメージのベースとなるイメージを指定します。ここでは、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
: Yarnの公開鍵をダウンロードし、aptのリポジトリに追加します。これにより、後のステップでYarnを安全にインストールできます。 -
RUN apt-get update -qq
: パッケージリストを更新します。-qq
オプションは、出力を最小限に抑えるためのものです。 -
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に設定します。 -
RUN mkdir /myapp
:/myapp
というディレクトリを作成します。 -
WORKDIR /myapp
: 作業ディレクトリを/myapp
に設定します。これにより、以降のRUN
,CMD
,ENTRYPOINT
,COPY
,ADD
命令はこのディレクトリ内で実行されます。 -
COPY Gemfile /myapp/Gemfile
とCOPY Gemfile.lock /myapp/Gemfile.lock
: ホストマシンのGemfileとGemfile.lockをコンテナの/myapp
ディレクトリにコピーします。 -
ENV BUNDLER_VERSION 2.1.4
: Bundlerのバージョンを2.1.4に設定します。 -
RUN gem install bundler -v 2.1.4
: Bundlerをインストールします。 -
RUN bundle update --bundler
: Bundlerを更新します。 -
RUN bundle install
: Gemfileに記載されたgemをインストールします。 -
COPY . /myapp
: ホストマシンの現在のディレクトリ(.
)の全てのファイルをコンテナの/myapp
ディレクトリにコピーします。 -
COPY entrypoint.sh /usr/bin/
とRUN chmod +x /usr/bin/entrypoint.sh
: entrypoint.shをコンテナの/usr/bin/
ディレクトリにコピーし、実行可能にします。このスクリプトはコンテナが起動するたびに実行されます。 -
ENTRYPOINT ["entrypoint.sh"]
: コンテナが起動するときに実行されるコマンドを設定します。ここでは、上記でコピーしたentrypoint.sh
が実行されます。 -
EXPOSE 3000
: コンテナの3000番ポートを開放します。これにより、ホストマシンからコンテナの3000番ポートにアクセスできるようになります。 -
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