こんにちは!
今回はDockerでRails環境を構築する方法についてまとめます。
はじめに
- クイックスタートガイドに基づいて解説
手順
- Dockerfile、Gemfile、Gemfile.lock、docker-compose.ymlの作成
- docker compose run web rails new . --force --database=postgresql
- Dockerfileの修正
- config/database.ymlの設定
- docker compose build
- docker compose run web rails db:create
- docker compose up -d
手順① Dockerfile、Gemfile、Gemfile.lockの作成
Dockerfile
FROM ruby:3.3.0 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock RUN bundle install ADD . /myapp
- これはクイックスタートガイドのDockerfileの内容
- 適宜バージョンアップなどをして調整する
- ホスト側のカレントディレクトリにDockerfileを作成
FROM ruby:3.3.0
- ベースにするイメージを指定
- DockerHubを確認し、最新のruby:3.3.0を指定
RUN apt-get update --qq && apt-get install -y
- コンテナ内で実行されるコマンドを指定
apt-get update -qq
- インストール可能なパッケージの一覧をアップデートする
--qq
はログの表示を抑えるapt-get install -y
- インストールするパッケージを指定する
-y
は確認ダイアログを全てYesで進めるbuild-essential
- 開発に必要なビルドツールなどのパッケージ
- gccやmakeなどが含まれる
libpq-dev
- PostgreSQLに接続するために必要なパッケージ
nodejs
- webpackなどを利用するため必要
RUN mkdir /myapp
- コンテナ内に
/myapp
ディレクトリを作成
WORKDIR /myapp
- 基準となるディレクトリを絶対パスで指定
- 以降の操作はこのディレクトリが基準になる
Gemfile /myapp/Gemfile
- 以降の操作はこのディレクトリが基準になる
Gemfileを
/myapp/Gemfile
に追加(コピー)するADD
とCOPY
はほぼ同じ機能ADD
には圧縮ファイルを解凍する機能などが含まれており、COPY
を使う方が推奨される
ADD 追加元 追加先
で指定する
ADD Gemfile.lock /myapp/Gemfile.lock
- 上と同じ
RUN bundle install
- 先ほどコピーしたGemfileを使用してコンテナ内でGemをインストールする
ADD . /myapp
- ホスト側のカレントディレクトリの内容を全て
/myapp
に追加(コピー)する
Gemfile
- ホスト側のカレントディレクトリにGemfileを用意する
source 'https://rubygems.org' gem 'rails', '>= 7.1.3'
- railsのバージョンを最新にした
Gemfile.lock
- ホスト側のカレントディレクトリに空のGemfile.lockを用意する
docker-compose.yml
version: '3' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=secret web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - db
version
- docker-composeのバージョンを指定
services
- 使用するコンテナの内容を定義
db
- dbコンテナの内容を定義
image
- 使用するイメージを指定
volumes
- バインドマウントを指定
environment
- 環境変数でPostgreSQLのパスワードを指定
POSTGRES_USER
: 指定しなかった場合はデフォルトでpostgres
となるPOSTGRES_DB
: 指定しなかった場合はデフォルトでpostgres
となる
web
- webコンテナの内容を定義
build
- 既存のイメージを使わない場合は、buildにDockerfileが置いているディレクトリのパスを指定
command
- コンテナ内で実行するコマンドを指定
volumes
- バインドマウントを指定
ports
- コンテナと外部のポートをマッピングする
depends_on
- 依存関係を指定し、起動順序を調整する
手順② docker compose run web rails new . --force --database=postgresql
docker compose run web rails new . --force --database=postgresql
- docker composeのwebコンテナで
rails new . --force --database=postgresql
コマンドを実行 --force
上書きの指定--database=postgresql
使用するデータベースの指定- 何も指定しないとsqliteとなる
- この時点で、Dockerfileが本番環境の内容で上書きされる
手順③ Dockerfileの修正
- 本番環境の内容で上書きされたDockerfileを、最初に作成したDockefileの内容に再度上書きする
- 本番環境用のDockefileはDockerfile.prodなどの名前で保存しておくとよい
手順④ config/database.ymlの設定
config/database.yml
を編集し、データベースへの接続設定を行う
config/database.yml
default: &default adapter: postgresql pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: db user: postgres password: secret
host
- 接続するdbのコンテナ名を指定
- docker-compose.ymlで
db:
と指定していればdbを記載
- docker-compose.ymlで
user
- postgreSQLのユーザー名を指定
- docker-compose.ymlで指定していなければ、デフォルトのpostgres
password
- postgreSQLのパスワードを指定
- docker-compose.ymlで環境変数に指定したパスワードを記載
手順⑤ docker compose build
- rails newのタイミングで、Gemfileも新しくなっているので、再度buildしてDockerイメージを作成する
手順⑥ docker compose run web rails db:create
docker compose run web rails db:create
- docker composeのwebコンテナで
rails db:create
コマンドを実行 rails db:create
config/database.ymlを元にデータベースを作成する
WSL2の場合のエラー
- WSL2で上記コマンドを実行すると、以下のエラーが出る
could not translate host name "db" to address: Temporary failure in name resolution Couldn't create 'myapp_development' database. Please check your configuration. bin/rails aborted! ActiveRecord::ConnectionNotEstablished: could not translate host name "db" to address: Temporary failure in name resolution (ActiveRecord::ConnectionNotEstablished)
- WSL2でない実機のUbuntuなどでは問題なく動作するので、dbの指定箇所の間違いなどではなさそう
- docker compose logsで確認すると以下のエラーが出ている
test-db-1 | chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted test-db-1 | The files belonging to this database system will be owned by user "postgres". test-db-1 | This user must also own the server process. test-db-1 | test-db-1 | The database cluster will be initialized with locale "en_US.utf8". test-db-1 | The default database encoding has accordingly been set to "UTF8". test-db-1 | The default text search configuration will be set to "english". test-db-1 | test-db-1 | Data page checksums are disabled. test-db-1 | test-db-1 | initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
- パーミッション関係のようだが、いい解決策が見つからなかった
- バインドマウントをせずに、名前付きボリュームにすると動作した
- docker-compose.ymlの変更箇所抜粋
db: volumes: - postgres_volume:/var/lib/postgresql/data volumes: postgres_volume:
手順⑦ docker compose up -d
docker compose up -d
- docker compose で立ち上げ
http://localhost:3000
でアクセス
おわりに
今回はDockerでRails環境を構築する方法についてまとめました。今回のDockerの環境構築を通じて、大分Dockerを実際に使うことに慣れてきました。前回Dockerを学んだときはDockerの仕組みを理解することで精いっぱいでしたが、今回の構築作業を通してDockerが使える道具になったと思います。
62/100