はじめに
今回は初めてDockerを使って環境構築してみたので、そのまとめを残していきたいと思います。
こちらのリポジトリを参考に
- Ruby: 3.3.0
- Rails: 7.1.2
- wsl2
- Docker Desktopインストール済み
- composeでsecretsを使う
で環境構築しました。
環境構築のステップ
まずはファイルを6つ用意します。
- Dockerfile.dev
- compose.yaml
- Gemfile
- Gemfile.lock
- entrypoint.sh
- db_password
それぞれ中身を見ていきましょう。
まずはDockerfile.dev
から、名前はなんでもいいのですが、Rails7.1以降の仕様から.devをつけています。
# syntax=docker/dockerfile:1
FROM ruby:3.3.0
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
特に解説することはありません。サンプルをほぼそのまま使っています。
次に、compose.yamlです。
ファイル名はdocker-compose.yml
とかdocker-compose.yaml
とかでもいいのですが、こちらのcompose.yaml
が推奨とのことなので、こちらを採用しました。
version: '3'
services:
db:
image: postgres
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: /run/secrets/db_password
secrets:
- db_password
web:
build:
context: .
dockerfile: Dockerfile.dev
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
environment:
POSTGRES_PASSWORD: /run/secrets/db_password
secrets:
- db_password
volumes:
db-data:
secrets:
db_password:
file: db_password
公式ドキュメントでパスワードなどはsecrersを使うのが良いと書いてあったので、使ってみました。
変更点はsecrets
とvolumes
、それからbuildするDockerfileをDockerfile.dev
にしました。
次はGemfile
です。
source 'https://rubygems.org'
gem 'rails', '~>7.1.2'
バージョンを最新のものにしました。
「なんとなく1番新しいのがいいやろ」と思ってこのバージョンにしましたが、これのせいでとても苦労しました。
次のGemfile.lock
は空です。
次に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 "$@"
こちらも丸パクリです。
最後にdb_password
です。
password
中身はなんでもいいです。
それでは用意ができたら早速やっていきましょう!
まずはrails new
をしていきましょう。
docker compose run --no-deps web rails new . --force --database=postgresql --skip-bundle
再ビルドするので--skip-bundle
しときましょう。
次にビルドするのですが、ここでかなり苦戦しました。
普通にDockerfile
で進めているとここでエラーを吐きまくります。
自分は6時間ぐらいここでエラーと格闘しました笑
原因はRails7.1からの仕様でした。
2.1 新規RailsアプリケーションでDockerfileが生成されるようになった
新規Railsアプリケーションでは、デフォルトでDockerがサポートされるようになりました(#46762)。 新しいアプリケーションを生成すると、そのアプリケーションにDocker関連ファイルも含まれます。
これらのファイルは、RailsアプリケーションをDockerでproduction環境にデプロイするための基本的なセットアップとして提供されます。重要なのは、これらのファイルは開発用ではないことです。
開発用ではないことです。
開発用ではないことです。
開発用ではないんですよ!!
そりゃあエラー吐きまくるわ
ちなみにrails new
の時に--skip-docker
でDockerfileと.dockerignoreが作られなくなるので、こちらでもOKです。
私もせっかくなので、Dockerfileをつくってもらいました。
一応ここで作られたDockerfileはDockerfile.prod
にリネームしておきました。
新しいGemfile
が作られたのでイメージを再ビルドする必要があります。
docker compose build
次にconfig/database.yml
に変更を加えます。
default: &default
adapter: postgresql
encoding: unicode
+ host: db
+ username: postgres
+ password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
上記の3つを追加します。
これでPostgreSQLが起動できます。
docker compose up
最後にdbを作成しましょう。
別のターミナルで
docker compose run web rake db:create
http://localhost:3000
にアクセス
お疲れさまでした。
トラブルシューティング
私の環境だけかもしれませんが、よく
=> ERROR [web] resolve image config for docker.io/docker/dockerfile:1 0.7s
------
> [web] resolve image config for docker.io/docker/dockerfile:1:
------
failed to solve: error getting credentials - err: exit status 1, out: ``
このようなエラーがでていました。
このエラーが出たときは別のタブでwsl --shutdown
でwsl2をシャットダウンしてから再起動すると解決しました。同じようなエラーがでる方はよかったら試してみてください。
まとめ
Docker Composeを用いてRails7.1.2の環境構築をしてみましたが、かなり迷走しました。しかし、Dockerについての知識は深まったので良かったです。迷走したおかげで色々便利そうなリポジトリやVScodeの拡張機能とかがしれて逆に良かったです笑
Rails以外の環境構築がしたいかたはこちらのリポジトリを参考にしてください。
参考文献
- 結局一番参考になるのは公式ドキュメントでした。
- 答えは全てここに載っていました笑