Dockerとdocker-composeについて学習し既存のRailsアプリをDocker化したので、その手順をまとめたいと思います。完成版はこちらです。
前提
- Dockerの基礎知識については学習済みと仮定します。
- 今回使用する既存のRailsプロジェクト名は
rails-docker
になります。 - DBはpostgresのversion12を使用します。
- ホストのファイルシステムとコンテナのファイルシステムを同期させます。
手順
大まかに以下のようになります。
-
database.yml
の編集 - プロジェクト直下にDocker関係のファイル作成
-
Dockerfile
の編集 -
compose.yaml
の編集 - docker-composeで起動
-
localhost:3000/
にアクセスできるか確認
database.yml
の編集
以下のように記述します。password
のところは環境変数を設定します。
# PostgreSQL. Versions 9.3 and up are supported.
#
# Install the pg driver:
# gem install pg
# On macOS with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On macOS with MacPorts:
# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem "pg"
#
default: &default
adapter: postgresql
encoding: unicode
host: db
user: postgres
port: 5432
password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: myapp_development
# The specified database role being used to connect to postgres.
# To create additional roles in postgres see `$ createuser --help`.
# When left blank, postgres will use the default role. This is
# the same name as the operating system user running Rails.
#username: myapp
# The password associated with the postgres role (username).
#password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
# domain sockets, so uncomment these lines.
#host: localhost
# The TCP port the server listens on. Defaults to 5432.
# If your server runs on a different port number, change accordingly.
#port: 5432
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# log, notice, warning, error, fatal, and panic
# Defaults to warning.
#min_messages: notice
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: myapp_test
# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
# production:
# url: <%= ENV["MY_APP_DATABASE_URL"] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
database: myapp_production
username: myapp
password: <%= ENV["MYAPP_DATABASE_PASSWORD"] %>
プロジェクト直下にDocker関係のファイル作成
Dockerfile
とcomposeyaml
(docker doscによると現在はdocker-compose.yml
よりもこちらの方が推奨されているようです)を作成します。
rails-docker $ touch Dockerfile compose.yaml
Dockerfileの編集
最終的に以下のようになりました。作成の過程を残すため、不要な行はコメントアウトしてます。nodejs
とyarn
はインストール不要みたいなのですが、この部分を消した場合の挙動は確認していないです。コメントにも書いていますが、WORKDIR
は指定したフォルダがなければ自動で生成してくれます。COPY . /rails-docker-app
の箇所は、ホストとコンテナを同期するようにcompose.yaml
で記述するので不要だと認識しています。間違えていたらご教示いただきたいです。
FROM ruby:3.2.2
# Rails 7 では Webpacker が標準では組み込まれなくなった影響で yarn や Node.js のインストールが不要
# https://mseeeen.msen.jp/rails-docker/
RUN apt-get update && apt-get install -y nodejs postgresql-client yarn
# 指定したフォルダがなければ自動で生成されるので下記は不要
# RUN mkdir /rails-docker-app
WORKDIR /rails-docker-app
COPY Gemfile Gemfile.lock /rails-docker-app/
RUN bundle install
# COPY . /rails-docker-app
最初は何かの記事を参考に
COPY Gemfile Gemfile.lock /rails-docker-app/
の行を
COPY Gemfile Gemfile.lock /rails-docker-app/Gemfile/
としており、その状態でdocker build .
をすると以下のようにエラーになりました。
$ docker build .
[+] Building 105.6s (10/10) FINISHED
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 368B 0.0s
=> [internal] load metadata for docker.io/library/ruby:3.2.2 5.1s
=> [auth] library/ruby:pull token for registry-1.docker.io 0.0s
=> [1/5] FROM docker.io/library/ruby:3.2.2@sha256:6a31af10aa94d7e5f6a4e2e45e8d96e070040a36e4f2cb9527c0f874b4ce2c97 73.0s
=> => resolve docker.io/library/ruby:3.2.2@sha256:6a31af10aa94d7e5f6a4e2e45e8d96e070040a36e4f2cb9527c0f874b4ce2c97 0.0s
=> => sha256:6a31af10aa94d7e5f6a4e2e45e8d96e070040a36e4f2cb9527c0f874b4ce2c97 1.86kB / 1.86kB 0.0s
=> => sha256:fd85f595c0b8dbfae34e0b27a56ae60a926e488049ab524a2cd7331d0a3173a7 8.16kB / 8.16kB 0.0s
=> => sha256:785ef8b9b236a5f027f33cae77513051704c0538bff455ff5548105c954c3b1c 49.56MB / 49.56MB 16.2s
=> => sha256:5a6dad8f55ae6c733e986316bd08205c8b2c41640bf8d08ff6e9bbcb6884304f 24.03MB / 24.03MB 4.1s
=> => sha256:af8ae0243e3283e06a65d2aa63fd3ed16d831ef5d06a89c1fd8d2b99f1d46782 1.79kB / 1.79kB 0.0s
=> => sha256:bd36c7bfe5f4bdffcc0bbb74b0fb38feb35c286ea58b5992617fb38b0c933603 64.11MB / 64.11MB 30.5s
=> => sha256:4d207285f6d296b9806bd00340437406c25207412c52fcfcbf229a5ecff7bf94 211.03MB / 211.03MB 36.6s
=> => sha256:db7d1c55965713c66c40e0cecf0c3aeb6f795937a3740aac7eac02a2dac97d62 200B / 200B 17.1s
=> => sha256:2c71b22972029a377f7c2fee19fdeae654e3cd4609137a8d8cc226f6e3584d12 34.69MB / 34.69MB 30.6s
=> => extracting sha256:785ef8b9b236a5f027f33cae77513051704c0538bff455ff5548105c954c3b1c 18.5s
=> => sha256:c9adccf9b3c6473a6b3917e9ba46e829e83806fb12427d0a0c98fadbbd47f804 177B / 177B 31.7s
=> => extracting sha256:5a6dad8f55ae6c733e986316bd08205c8b2c41640bf8d08ff6e9bbcb6884304f 1.4s
=> => extracting sha256:bd36c7bfe5f4bdffcc0bbb74b0fb38feb35c286ea58b5992617fb38b0c933603 5.1s
=> => extracting sha256:4d207285f6d296b9806bd00340437406c25207412c52fcfcbf229a5ecff7bf94 23.6s
=> => extracting sha256:db7d1c55965713c66c40e0cecf0c3aeb6f795937a3740aac7eac02a2dac97d62 0.0s
=> => extracting sha256:2c71b22972029a377f7c2fee19fdeae654e3cd4609137a8d8cc226f6e3584d12 1.5s
=> => extracting sha256:c9adccf9b3c6473a6b3917e9ba46e829e83806fb12427d0a0c98fadbbd47f804 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 7.78kB 0.0s
=> [2/5] RUN apt-get update && apt-get install -y nodejs postgresql-client yarn 25.7s
=> [3/5] WORKDIR /rails-docker-app 0.1s
=> [4/5] COPY Gemfile Gemfile.lock /rails-docker-app/Gemfile/ 0.1s
=> ERROR [5/5] RUN bundle install 1.2s
------
> [5/5] RUN bundle install:
#0 1.204 Could not locate Gemfile
------
Dockerfile:7
--------------------
5 | WORKDIR /rails-docker-app
6 | COPY Gemfile Gemfile.lock /rails-docker-app/Gemfile/
7 | >>> RUN bundle install
8 | # COPY . /rails-docker-app
9 |
--------------------
ERROR: failed to solve: process "/bin/sh -c bundle install" did not complete successfully: exit code: 10
WORKDIR /rails-docker-app
で作業ファイルを指定しているのにGemfileフォルダにコピーしたために起こったエラーだと思われます。
compose.yamlの編集
最終的に以下のようになりました。
version: "3.9"
volumes:
db-data:
services:
web:
build: .
ports:
- "3000:3000"
environment:
- "POSTGRES_PASSWORD=postgres"
tty: true
stdin_open: true
depends_on:
- db
links:
- db
volumes:
- .:/rails-docker-app
command: ["rails", "s", "-p", "3000", "-b", "0.0.0.0"]
db:
image: postgres:12
volumes:
- "db-data:/var/lib/postgresql/data"
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- .:/rails-docker-app
の行はホストとコンテナを同期させるために入れています。
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
の行は、ターミナルの実行結果が消えてしまったので詳しく書けないのですが、無しで実行するとDBのコンテナが作られなかったので、参考
の動画などを見て記述しました。
command: ["rails", "s", "-p", "3000", "-b", "0.0.0.0"]
の行は、最初
command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
としていたのですが、最初の2つはなくても立ち上がりました。
docker-composeで起動
いろいろ試行錯誤し、最終的に以下のように立ち上げました。dcはdocker-composeのことです(エイリアスを設定しています)。先述しましたがターミナルの実行結果が消えてしまったのでこれしか掲載できないです。すみません。
$ dc up -d --build
[+] Building 3.8s (11/11) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 530B 0.0s
=> [internal] load metadata for docker.io/library/ruby:3.2.2 3.7s
=> [auth] library/ruby:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 61B 0.0s
=> [1/5] FROM docker.io/library/ruby:3.2.2@sha256:6a31af10aa94d7e5f6a4e2e45e8d96e070040a36e4f2cb9527c0f874b4ce2c97 0.0s
=> CACHED [2/5] RUN apt-get update && apt-get install -y nodejs postgresql-client yarn 0.0s
=> CACHED [3/5] WORKDIR /rails-docker-app 0.0s
=> CACHED [4/5] COPY Gemfile Gemfile.lock /rails-docker-app/ 0.0s
=> CACHED [5/5] RUN bundle install 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:e94ddca34673f30ab6238bbbed22753d8b8154d94c6ac23af25cce0a34f3a8c7 0.0s
=> => naming to docker.io/library/rails-docker-web 0.0s
[+] Running 2/2
✔ Container rails-docker-db-1 Running 0.0s
✔ Container rails-docker-web-1 Running
問題なさそうです。
localhost:3000/
にアクセスできるか確認
以下にアクセスし、アプリが起動するか確認します。
http://localhost:3000/
画像のようになっていれば成功です。
初めてアクセスした場合はデータベースがないというエラーが出るので、rails db:create
をするかデータベースを作成するボタンが出てくるのでそれを押します(画像撮っとけばよかった)。