Docker ComposeでRailsアプリをDocker化

この記事では、Docker Composeを使ってRailsアプリをDocker化する手順を、初学者の方でも分かりやすいように解説します。
今回は用意されているrailsアプリをクローンしてDocker化していきます。

# 前提条件

- Docker Desktop がインストールされていること
- Git がインストールされていること
- Rails アプリケーションが用意されていること

# 今回の構成

- `docker-compose up` で Rails サーバーを起動
- DB は PostgreSQL 12 を使用
- ホストのファイルシステムとコンテナのファイルシステムを同期
- `docker-compose up` で Rails プロセスと DB が起動し、`http://localhost:3000` でアクセス可能

# Docker化の方針

- `docker-compose up` で上記条件を満たす環境を構築
- まずは Web アプリ起動に必要な最低限のコードを `Dockerfile`, `docker-compose.yml`, `database.yml` に記述し、コンテナ内で必要なコマンドを探して追記
- 必要なコマンドを特定後、各ファイルを編集し、`docker-compose up` で環境構築できるようにする

# Docker化の手順

## 1. プロジェクトを git clone

まず、Rails プロジェクトをローカルにクローンします。

$ git clone [クローンしたいプロジェクトのURL]
$ cd [クローンしたフォルダ名]

## 2. Ruby のバージョンを確認
予期せぬエラーの回避するためにクローンしたrailsプロジェクトの`Gemfile` から Ruby のバージョンを確認します。
今回クローンしたrailsプロジェクトのGemfileは以下でした。

`ruby "3.2.2"`

## 3. Dockerfile の作成

`Dockerfile` を作成し、以下の内容を記述します。

```Dockerfile:Dockerfile
FROM ruby:3.2.2
RUN apt-get update -qq && apt-get install -y \
  build-essential \
  libpq-dev \
  nodejs \
  postgresql-client \
  yarn
WORKDIR /rails-docker
COPY Gemfile Gemfile.lock /rails-docker/
RUN bundle install
ADD . /rails-docker
```

**Dockerfile の解説:**

- `FROM ruby:3.2.2`: Ruby 3.2.2 をベースイメージとして使用
- `RUN apt-get update ...`: 必要なパッケージをインストール
- `WORKDIR /rails-docker`: 作業ディレクトリを設定
- `COPY Gemfile ...`: `Gemfile` と `Gemfile.lock` をコピー
- `RUN bundle install`: gem をインストール
- `ADD . /rails-docker`: アプリケーションコードをコピー

## 4. docker-compose.yml の作成


`docker-compose.yml` を作成し、以下の内容を記述します。

```docker:docker-compose.yml
volumes:
  db-date:

services:
  web:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/rails-docker'
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: postgres:12
    volumes:
      - 'db-date:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
```

**docker-compose.yml の解説:**

- `volumes`: **データの保存場所を設定します。**
  - Dockerコンテナは、通常、停止したり削除したりするとデータが消えてしまいます
  - ボリュームを使うと、コンテナが停止してもデータを保存できます
- `services`: **複数のコンテナをまとめて設定します。**
  - `web`: Web アプリケーションのコンテナ設定
    - `build: .`: 同じフォルダにあるDockerfileを使ってイメージをビルドします
    - `ports`: パソコンの3000番ポートとコンテナの3000番ポートを繋ぎます
    - `volumes`: パソコンのフォルダとコンテナのフォルダを同期します
    - `environment`: コンテナ内で使う環境変数を設定します
    - `depends_on`: `db`コンテナが起動してから`web`コンテナを起動します
    - `links`: 古い設定ですが、`db`コンテナと`web`コンテナを繋ぎます
  - `db`: PostgreSQL 12 のコンテナ設定
    - `image: postgres:12`: PostgreSQL 12 のイメージをダウンロードして使います
    - `volumes`: データベースのデータを保存する場所を設定します
    - `environment`: データベースのユーザー名やパスワードを設定します

:::note alert
```
environment:
      - 'DATABASE_PASSWORD=postgres'
```
今回は個人学習用で設定をしているため、環境変数を直接記述していますが、実際のプロジェクトや自作アプリの開発時は、セキュリティ上の理由から、環境変数を直接記述するのではなく、外部ファイル (.env ファイルなど) に記述したり、Docker Secrets などの機能を使って、サービス内で環境変数を安全に管理するようにしましょう。
:::


## 5. database.yml の編集

`config/database.yml` を編集し、以下の内容を記述します。

```database.yal
default: &default
  adapter: postgresql
  encoding: unicode
  host: db                                        *追記
  user: postgres                                  *追記
  port: 5432                                      *追記
  password: <%= ENV.fetch("DATABASE_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 } %>
```

**database.yml の解説:**

- `host: db`: DB コンテナのホスト名を指定
- `password: <%= ENV.fetch("DATABASE_PASSWORD") %>`: 環境変数からパスワードを取得

## 6. コンテナを起動し、必要なコマンドを探す

`docker-compose up` でコンテナを起動し、Rails アプリに必要なコマンドを探します。

$ docker-compose up -d

以下のコマンドを実行してコンテナに入り、必要なコマンドを確認します。

$ docker-compose exec web bash
$ rails db:create
$ rails db:migrate
$ rails s -b 0.0.0.0
$ exit

## 7.docker-compose.yml の編集

上記で確認したコマンドを元に、 `docker-compose.yml` を編集します。

**docker-compose.yml の編集例:**

```docker:docker-compose.yml
volumes:
  db-date:

services:
  web:
    build: .
    ---- 追記 ------------------------------------------------------------
    command: >
      bash -c "rails db:create && rails db:migrate && rails s -b 0.0.0.0"
    ---------------------------------------------------------------------
    ports:
      - '3000:3000'
    volumes:
      - '.:/rails-docker'
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: postgres:12
    volumes:
      - 'db-date:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
```

**編集内容の解説:**

- `command`: コンテナ起動時に実行するコマンドを追加
  - `bundle exec rails db:create`: データベースを作成
  - `bundle exec rails db:migrate`: マイグレーションを実行
  - `bundle exec rails s -p 3000 -b '0.0.0.0'`: Rails サーバーを起動

## 8. 動作確認

`docker-compose up` を実行し、`http://localhost:3000` にアクセスして動作を確認します。

$ docker-compose up --build -d

# さいごに

この記事では、Docker Compose を使って Rails アプリを Docker 化する手順を解説しました。Docker を活用することで、開発環境の構築やデプロイが簡単になります。ぜひ Docker を活用してみてください。

参考記事

> クィックスタート: Compose と Rails
https://docs.docker.jp/compose/rails.html