docker composeを使ってRailsアプリをdocker化する方法

## はじめに

今回は**Docker公式のクィックスタート: Compose と Rails**というページを参考にDocker Composeを使ってRailsアプリ+Postgresのdocker化に挑戦したので、その方法を説明していきます。  

初学者による説明なので、ご注意ください。



https://docs.docker.jp/compose/rails.html
## 対象読者

- クイックスタートの例をそのまま実施したが、うまくいかない人

- Rails+PostgresのDocker化の手順をなんとなく知りたい人

- 三日前の自分



## バージョン

クイックスタートのままのバージョンで実施するとあれやこれやとエラーになってしまったので、バージョンを下記のように設定しています。

- Ruby 3.2.2

- Rails 7.1.x

- Postgres version 12

RubyとRailsのバージョンの組み合わせは下記を参考にして選びました。  

参考：  

https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html

## 筆者の環境

- macOS Sequoia 15.3

- Apple M2

## 1.Railsアプリのdocker化に必要なファイルを4つ作成

まずはRailsアプリを構成するファイルとdocker化に必要なファイルを用意します。  



以下の4つのファイルが必要です。

- Dockerfile

- Gemfile

- Gemfile.lock

- docker-compose.yml



それぞれ説明していきます。

---

### Dockerfile

Dockerイメージを作成するために、Dockerfileを記述します。  

下記のように記述します。  

ここでは、クイックスタートのコードからruby:3.2.2に変更しています。

```dockerfile
FROM ruby:3.2.2
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
```
#### apt-get update

- 最新のパッケージリストをソフトウェアの配布元から取得する

- システムのパッケージ情報を最新の状態にする

- \-qqオプション

   - ログを極力表示させない



#### apt-get install

- パッケージ名を指定してインストールする
---
### Gemfile

以下のように記述します。  

ここでは、クイックスタートのコードから7.1に変更しています。

```plain
source 'https://rubygems.org'
gem 'rails', '7.1'
```

---

### Gemfile.lock

空のGemfile.lockファイルを作成します。  

DockerfileをDockerイメージにビルドするために記述します。


---
### docker-compose.yml

Railsを動かすコンテナとPostgresを動かすコンテナが2つありますが、本来、ネットワークを作成したり色々設定しないとコンテナ間の接続ができません。  

docker composeという仕組みのおかげで、一つのdocker composeの中にある複数のコンテナは設定不要でコンテナ間通信ができるようになります。  



docker-compose.ymlは下記のように記述します。  


:::note
ファイル名がdocker-compose.ymlではなく、compose.yamlが公式推奨ですが、今回はクイックスタートの例で進みます。  

加えて、version: ‘3’というのも不要で、残したままコマンドを実行すると警告が出ますが、同様にこのまま進めます。
:::

```plain
version: '3'
services:
  db:
    image: postgres:12
    environment:
      - 'POSTGRES_PASSWORD=postgres'
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

個人的に重要なプロパティだけ説明します。



#### environment

環境変数を追加できます。
`POSTGRES_PASSWORD`の記述を忘れるとエラーになります。
ここの値が重要で、下記のような記述がGitHubのdocsにありました。  


> PostgreSQL イメージでは、見逃しやすい環境変数がいくつか使用されます。必須の変数は のみで`POSTGRES_PASSWORD`、残りはオプションです。

参考：

https://github.com/docker-library/docs/blob/master/postgres/README.md#environment-variables

## 2.Railsアプリの雛形を作成

```plain
docker-compose run web rails new . --force --database=postgresql
```

とターミナルに入力します。



すると、Railsアプリに必要なファイルが作成されます。

## 3.Dockerイメージを再ビルド

先ほどのコマンドを入力すると、DockerfileとGemfileに変更が入ります。

```plain
docker-compose build
```

とターミナルに入力して、Dockerイメージを作ります。  

web BuiltとなればOKです。  

![Screenshot - 2025-04-10 00.39.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/af257bed-3449-41f0-bcf5-16826e6252dd.png)



## 4.データベースの接続設定

config/database.yml はdefault部分だけ修正します。

```plain
default: &default
  adapter: postgresql
  encoding: unicode
  host: db # 追加
  username: postgres # 追加
  password: postgres # 追加
```

#### adapter

- データベースの種類を指定

#### host

- データベースが動作しているホスト名（コンテナ名）を指定

<br>

次に、config/database.ymlを書き換えたら

```plain
docker-compose up
```

と入力します。


:::note warn
ここで、RubyとRailsのバージョンが古かったり、新しすぎたり、組み合わせが悪かったりするとエラーになることが多かったです。
:::
<br>
なんかエラーになった！

![Screenshot - 2025-04-10 20.30.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/14c0759f-8684-4d51-b3b6-13fb6fffbe38.png)



なので、docker-compose.ymlのwebのプロパティに以下を追加します！

```plain
RAILS_ENV=development
```

<br>

そして、再度、`docker-compose up`を入力して  
下図のような表示になったらOKです。       

![Screenshot - 2025-04-10 20.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/e1225483-d8a8-4db3-8962-b7dd8741b5ab.png)

:::note info
ちなみに`docker-compose up -d`と入力してバックグラウンドでコンテナを起動すると  別タブへ移動する必要がありません。
:::



その後、ターミナルで新規タブを開き、下記を入力します。

```plain
docker-compose run web rake db:create
```


![Screenshot - 2025-04-10 20.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/1b4ad105-e31b-436f-b2d2-03505e12c96d.png)

まだダメのようです。  
コマンドの言う通り、**bundle exec**を頭につけて実行します。

```plain
docker-compose run web bundle exec rake db:create
```

このエラーは解決しましたが、別の理由でダメみたいです。
![Screenshot - 2025-04-10 20.56.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/2393c000-0e0d-4b42-82ff-f3b29f5f1e98.png)


<br>
色々調査したところ、rails newを入力したときに、Dockerfileの記述の中で  
WORKDIRが/railsになっていました。  

![Screenshot - 2025-04-10 23.42.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/a2dde818-4163-4981-8d7f-f10b44015af5.png)




前述の通り、docker-compose.ymlファイルはホストのカレントディレクトリを/myappにマウントするよう設定しています。  
<br>
そのため、database.ymlのhost: dbという設定が反映されず、Postgresのコンテナに接続できなかったのでは？と思いました。  
しかし、直前で`docker-compose run`であったり、Dockerfile内に`COPY . .`などしていて、更新はされているものと思いましtおそらくキャッシュされたイメージがビルドされたのかなーと勝手に思っています。

<br>

また、一つ前のエラーで`RAILS_ENV=”development”`にしましたが、Dockerfileを見ると`RAILS_ENV=”production”`と記載されており、これが原因だったようですね。  


<br>
と、初学者による考えは置いておいて、本題へ戻ります。



- Dockerfileをもともと作成したファイルに上書きして・・・  

- `docker-compose build`を入力・・・  

- `docker-compose up`を入力・・・  

- `docker-compose run web bundle exec rake db:create`を入力すると・・・
<br>


![Screenshot - 2025-04-10 21.02.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/32f59a8c-8377-4c9b-b8ee-603e62681b74.png)





ようやくデータベースが出来ました！

## 5.RailsのWelcomeページを確認する

<localhost:3000>にアクセスしましょう！


![Screenshot - 2025-04-10 21.04.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993508/ef4c1ac3-3c59-42d9-9562-2b4b894f2fdf.png)




無事、日の丸を拝むことができました！



## 終わりに

今回はクイックスタートの例を元にDocker Composeを使ったRails+PostgresのDocker化について説明しました。



いくつかエラーを紹介しましたが、ここに載せ切れないくらいのエラーを経験しました。今回の演習を通して、Docker Composeの使い方だけでなく、エラーとの向き合い方を知り、エラーが出てもめげない精神はついたのかなと思います！


もちろんまだまだ実務レベルには程遠いと思うので、これからも精進します！



## 参考

https://docs.docker.jp/compose/rails.html