5
5

More than 1 year has passed since last update.

Dockerfileとdocker-composeでRailsとPostgreSQLを設定

Last updated at Posted at 2023-06-21

はじめに

Rails学習の一歩として、最初に取り組んだのはコンテナ環境の構築でした。予想以上に時間と労力がかかりましたが、何とか構築することができ、その結果、Dockerのスキルが大いに向上しました。環境構築やDockerスキルの向上を目指している方々に、少しでも参考になれば幸いです。Railsを学び始めた時の書籍が、「Rails5」「PostgreSQL10」を用いた環境のため、そこに焦点を当て環境構築を行いました。

Dockerスキルアップのコツ

Dockerのスキルアップのコツは慣れです。同じコマンドや環境を何度も実行/構築することでスキルアップにつながります!暗記しようとせずに、慣れていきましょう!
また、これらはRailsやPostgresのバージョンが異なっていても、同様な考え方でコンテナ環境を構築できます。設定はバージョンごとに異なるかと思いますが、その都度調査することで、Dockerのスキルアップに繋がるため、ぜひチャレンジしてみてください!

準備

まずは、「ローカル環境のフォルダ」 「Dockerfile」 「docker-compose.yml」 「Gemfile」 「Gemfile.lock」を作成します。

ローカル環境のフォルダ

handsonというフォルダを作成し、その中にDockerfile、docker-compose.yml、Gemfile、Gemfile.lockを作成して、それぞれ後述のコードをコピペします。

Dockerfile

DockerfileはDockerイメージのビルド手順を定義します。

  1. FROM ruby:2.5.1
    • Ruby 2.5.1がインストールされたDockerイメージを指定します。
  2. RUN echo "deb http://archive.debian.org/debian/ stretch main" > /etc/apt/sources.list \ ...
    • Debianのパッケージリポジトリを設定し、build-essentialとnodejsをインストールします。build-essentialはCコンパイラなどのビルドに必要なパッケージをまとめたものです。nodejsはJavaScriptの実行環境です。
  3. RUN mkdir /app
    • Dockerコンテナ内に/appというディレクトリを作成します。
  4. WORKDIR /app
    • 作業ディレクトリを/appに変更して、以降の命令は/appから実行されます。
  5. COPY Gemfile /app/Gemfile COPY Gemfile.lock /app/Gemfile.lock
    • ホストのGemfileとGemfile.lockをコンテナの/appディレクトリにコピーします。
  6. RUN bundle install
    • Gemfileに記載されたgemをインストールします。
  7. COPY . /app
    • ホストの現在のディレクトリの全てのファイルをコンテナの/appディレクトリにコピーします。
FROM ruby:2.5.1
RUN echo "deb http://archive.debian.org/debian/ stretch main" > /etc/apt/sources.list \
    && echo "deb http://archive.debian.org/debian-security stretch/updates main" >> /etc/apt/sources.list \
    && apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

docker-compose.yml

docker-compose.ymlは複数のコンテナ間の関係を定義します。

  1. version: '3'
    • docker-composeのバージョンを指定しています。
  2. services:
    • webとdbの2つのサービス(コンテナ)を定義しています。
  3. web:
    • webサービス(コンテナ)の設定を始めることを示します。
    • build: .
      • 現在のディレクトリ(.)にあるDockerfileに基づいてDockerイメージをビルドします。
    • command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
      • コンテナが起動する際に実行されるコマンドを指定します。ここでは、まず既存のserver.pidファイルを削除し(存在すれば)、その後Railsサーバを起動します。
    • volumes: - .:/app
      • ホストの現在のディレクトリ(.)とコンテナ内の/appディレクトリをマウントします。ホストとコンテナ間でファイルが共有されます。
    • ports: - 3000:3000
    • depends_on: - db
      • webサービスがdbサービスに依存していることを示します。dbサービスが先に起動した後でwebサービスが起動します。
    • tty: trueとstdin_open: true
      • これらのオプションはコンテナ内での対話型プロセスを可能にします。
  4. db:
    • dbサービス(コンテナ)の設定を始めることを示します。
    • image: postgres:10.1
      • バージョン10.1のPostgreSQLイメージ(Dockerイメージ)を使用します。
    • volumes: - postgres_volume:/var/lib/postgresql/data
      • 名前付きボリュームpostgres_volumeとコンテナ内の/var/lib/postgresql/dataディレクトリをマウントすることで、データベースのデータが永続化されます。
    • environment: POSTGRES_PASSWORD: password
      • 環境変数を設定します。ここではPostgreSQLのパスワードをpasswordとしています。
    • ports: - 5432:5432
      • ホストの5432番ポートとコンテナの5432番ポートをマッピングします。
    • restart: always
      • コンテナが何らかの理由で終了した場合、Dockerが自動的にコンテナを再起動します。
  5. volumes: postgres_volume:
    • 名前付きボリュームpostgres_volumeの設定を始めることを示します。
version: '3'
services:
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: postgres:10.1
    volumes:
      - postgres_volume:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
    restart: always
volumes:
  postgres_volume:

Gemfile

GemfileはRubyのプロジェクトで使用するgem(ライブラリ)を管理するためのファイルです。

  1. source 'https://rubygems.org' gemの取得元となるソースを指定しています。ここでは公式のRubyGemsリポジトリからgemを取得します。
  2. gem 'rails', '~> 5.2.0' rails gemのバージョンを5.2.xと指定しています。この記述により、bundle installコマンドを実行したときにRailsのバージョン5.2.xがインストールされます。
source 'https://rubygems.org'
gem 'rails', '~> 5.2.0'

Gemfile.lock

Gemfile.lockはRubyのプロジェクトで使われるライブラリ(gem)のバージョンを記録するファイルです。Gemfile.lockがあることで、同じプロジェクトでも異なる環境で実行したときに同じgemのバージョンが使われ、挙動の違いを防げます。ただし、新しいRailsプロジェクトを作成する際には、まだどのgemを使用するか、それらのバージョンが決まっていないため、Gemfile.lockは空にします。その後、bundle installが初めて実行されるとき、Gemfile.lockにはGemfileに記述されたgemのバージョンが自動的に記録されます。

docker-composeコマンド

docker-composeを実行して、Rails5のコンテナ環境を構築します。

はじめに、docker-compose runコマンドを実行して、Railsアプリケーションの初期セットアップを行います。

  • web docker-compose.yml ファイル内のサービス名を指しています。
  • rails new . 新しいRailsアプリケーションを現在のディレクトリ(.が現在のディレクトリを示します)に生成するためのコマンドです。
  • --force ファイルがすでに存在していた場合でも、強制的に新しいRailsアプリケーションを生成するためのオプションです。つまり、すでにあるファイルは新しいもので上書きされます。
  • --database=postgresql 新しいRailsアプリケーションのデータベースとしてPostgreSQLを使用するように設定するためのオプションです。
docker-compose run web rails new . --force --database=postgresql

docker-compose buildコマンドを実行して、Dockerfileからイメージをビルドします。

docker-compose build

docker-compose up -dコマンドを実行して、コンテナをバックグラウンド(-dオプション)で起動します。

docker-compose up -d

この段階ではまだエラーになるため、データベースの設定を行います。
スクリーンショット 2023-06-11 11.08.06.png

Railsのconfig/database.ymlを編集します。

default: &default
~~~~省略~~~~~~
~~~~以下の3行を追加~~~~~~
  host: db
  username: postgres
  password: password
~~~~~~~~~~

docker-compose runコマンドを実行して、データベースを作成します。

docker-compose run web rails db:create

docker-compose restartコマンドを実行して、コンテナを再起動します。

docker-compose restart

localhost:3000にアクセスして、Railsのデフォルトページが表示されれば成功です。
スクリーンショット 2023-06-11 10.16.13.png

docker-compose stopコマンドを実行して、コンテナを停止します。

docker-compose stop

localhost:3000にアクセスして、表示されないことを確認します。
スクリーンショット 2023-06-11 10.18.08.png

不要なコンテナやイメージを削除する

これまでの操作を行なっていくと、「dockerコンテナ」「dockerイメージ」が複数作成されているかと思います。

handson % docker-compose ps -a
NAME                           IMAGE                                                                     COMMAND                  SERVICE             CREATED             STATUS                          PORTS
handson-db-1                   postgres:10.1                                                             "docker-entrypoint.s…"   db                  23 minutes ago      Exited (0) 10 seconds ago
handson-web-1                  handson-web                                                               "bash -c 'rm -f tmp/…"   web                 10 minutes ago      Exited (1) 10 seconds ago
handson-web-run-7188bd29e0ec   handson-web                                                               "rails db:create"        web                 2 minutes ago       Exited (0) About a minute ago
handson-web-run-eb881b1d471e   sha256:6ff7a599ebf79862b6f97c4c8af0f53c8422400632514855d24ae26ab637714c   "rails new . --force…"   web                 23 minutes ago      Exited (0) 22 minutes ago

handson % docker-compose images
CONTAINER                      REPOSITORY          TAG                 IMAGE ID            SIZE
handson-db-1                   postgres            10.1                ec61d13c8566        287MB
handson-web-1                  handson-web         latest              8e1e773be953        1GB
handson-web-run-7188bd29e0ec   handson-web         latest              8e1e773be953        1GB
handson-web-run-eb881b1d471e   <none>              <none>              6ff7a599ebf7        972MB

docker-compose up -dを実行したときに作成されるコンテナは以下の2つです:

handson-web-1:Railsアプリケーションをホストするコンテナで、Dockerfileからビルドされたイメージruby:2.5.1を使用します。docker-compose.ymlファイルのwebサービスに対応しています。

handson-db-1:PostgreSQLデータベースをホストするコンテナで、公式のPostgreSQLイメージpostgres:10.1を使用します。docker-compose.ymlファイルのdbサービスに対応しています。

これらの2つのコンテナが起動しているため、Railsアプリケーションはブラウザからアクセス可能になっています。
Railsアプリケーションがブラウザからアクセス可能になるのは、rails1-web-1とrails1-db-1という2つのコンテナが起動しているからです。その他のコンテナやイメージは一時的に作成されたもので、Railsアプリケーションの動作には直接影響しません。

そのため、以下のコマンドでコンテナ、イメージを削除します。

コンテナを削除

不要なコンテナを削除する。

docker rm handson-web-run-7188bd29e0ec

イメージを削除

不要なイメージを削除する。

docker rmi 6ff7a599ebf7

全てのリソースを削除

全ての作業が完了し、利用が終わり、不要になった場合は、docker-compose down --rmi all --volumes --remove-orphansコマンドを実行して、コンテナ、ネットワーク、イメージ、ボリュームを削除できます。

docker-compose down --rmi all --volumes --remove-orphans

まとめ

環境構築の流れをまとめました。

# コンテナ作成の前準備
「ローカル環境のフォルダ」 「Dockerfile」 「docker-compose.yml」 「Gemfile」 「Gemfile.lock」を作成

# Railsアプリケーションのコンテナ環境を構築
docker-compose run web rails new . --force --database=postgresql
docker-compose build
docker-compose up -d
~~ database.ymlを編集 ~~
docker-compose run web rails db:create
docker-compose restart
docker-compose stop
docker-compose down --rmi all --volumes --remove-orphans

# 不要なコンテナ、イメージを削除したい場合
docker rm ${コンテナ}
docker rmi ${イメージ}
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5