Ruby(Sinatra)+Postgres の開発をローカルでやろう! Vol.2 ~無限 Docker Compose 編~

「[Life is Tech ! Kanto Advent Calendar 2022](https://qiita.com/advent-calendar/2022/life-is-tech-kanto)」22 日目の記事になります。

# はじめに

こんにちは、Life is Tech! で関東 Web サービスコースメンターをやっているいっそです！

今回は、「Ruby(Sinatra)+Postgres の開発をローカルでやろう! Vol.2 ~無限 Docker Compose 編~」ということで、いつもは Cloud9 で運用されている Web サービスコースの開発環境を Docker Compose で建ててみたいと思います！

この記事は昨日と 3 日間に分けて投稿されており、1 日目はローカルに必要なソフトウェアを全部インストールして開発環境を構築する方法をご紹介しました！
興味あればぜひ読んでみてください。

**P.S. 1 日目の macOS, Linux ネイティブ用の記事は [こちら](https://qiita.com/isso_719/items/e83b8fe8d6c6efa229e7)！**
**P.S. 3 日目の Windows 用の記事は [こちら](https://qiita.com/isso_719/items/548263da598e9e519c6d)！**

# Docker とは

[Docker](https://www.docker.com/) とは OS レベルのコンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンプラットフォームです。
要はパソコンの中にパソコンみたいなの建てるやつなんだなーって感じです。
ここではそこまで詳しい説明は必要でないので行いません。

# Docker Compose とは

[Docker Compose](https://docs.docker.jp/compose/toc.html) は複数のコンテナで構成されるアプリケーションについて、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツールです。
Docker は基本アプリケーションごとにコンテナを建てるのが慣習なので、Web サーバとデータベースの 2 つのソフトウェアをコンテナを分けたときに、それらをまとめて管理できたり、相互に繋ぐことができたりするのを簡単にできるものと思っておけば大体 OK です。

# Docker, Docker Compose のインストール

Docker および Docker Compose は Docker Desktop をインストールすることで導入できます。
Docker Desktop のダウンロードは [こちら](https://www.docker.com/)

**P.S. HomeBrew や Scoop といったパッケージマネージャーを使用してもインストールできます！**

# 開発環境を構築する

[Vol.1](https://qiita.com/isso_719/items/e83b8fe8d6c6efa229e7) で紹介した、開発に必要なソフトウェアが入っているコンテナを使用します。

## 構成

今回は Docker Compose を用いて以下 2 つのサービスを管理します。

- web
    - Web サーバの機能を提供する
    - Ruby 3.0.0 のイメージを元に、`bundle install` などの操作を加え独自ビルド
- db
    - データベースの機能を提供する
    - postgres の最新イメージをそのまま使用する

## Dockerfile

今回は web コンテナ用の Dockerfile のみを作成します。(Dockerfile の詳しい説明や書き方は省略します)

(実はどこにおいても良いのですが) わかりやすいようにプロジェクト直下に `Dockerfile` という名前のファイルを以下のように作成します。

```docker
FROM ruby:3.0.0
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
```

## Docker Compose

次に Docker Compose ファイルにサービスを定義していきます。(Docker Compose ファイルの詳しい説明や書き方は省略します)

プロジェクト直下に `docker-compose.yml` という名前のファイルを以下のように作成します。

```yaml
version: '3.9'
services:
  web:
    build: .
    command: bundle exec ruby app.rb -o 0.0.0.0
    ports:
      - 4567:4567
    volumes:
      - .:/app
    depends_on:
      - db
    environment:
      - RACK_ENV=development
  db:
    image: postgres
    ports:
      - 3306:3306
    volumes:
      - postgres_volume:/var/lib/postgresql/data
    environment:
        POSTGRES_HOST_AUTH_METHOD: 'trust'
volumes:
  postgres_volume:
```

## config/database.yml

`config/database.yml` に、データベースに接続するための情報を書きます。

```yaml
default_env: &default
  adapter: postgresql
  encoding: unicode
  database: data
development:
  <<: *default
  host: db
  username: postgres
  password:
production:
  <<: *default
```

## ここまでのまとめ

ここまでのファイルの追加、変更点まとめると、[こちら](https://github.com/isso-719/sinatra-migrate-c9-to-dockerCompose/blob/main/sinatra-migrate-c9-to-docker-compose.sh) のコードのようになります。
上記のスクリプトを使用したい場合は以下のようにすると簡単にできます。(macOS, Linux の場合)

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/isso-719/sinatra-migrate-c9-to-dockerCompose/main/sinatra-migrate-c9-to-docker-compose.sh)"
```

# 開発環境を動かす

いよいよ Docker Compose を使用してコンテナを動かしてみたいと思います。
以下のコマンドを打つだけでコンテナが起動します！

```bash
docker-compose up

# ログを流さないようにするには d オプションを使用します
# docker-compose up -d
```

コマンドを打って、以下のようになれば成功です。

```bash
% docker-compose up
...
Creating count_db_1 ... done
Creating count_web_1 ... done
...
```

# よく使いそうなコマンド

ここではよく使いそうなコマンドを紹介します。

- コンテナの起動
    - `docker-compose up`
    - (ログ出力をしない場合) `docker-compose up -d`
- コンテナの停止
    - `docker-compose down`
- 任意のコマンドを実行する
    - `docker-compose run サービス名 コマンド`
        - (例) データベース作成
            - `docker-compose run web rake db:create`
        - (例) データベースのマイグレート
            - `docker-compose run web rake db:migrate`
- データベースの drop
    - `docker-compose down --volume`
    - 次回コンテナ起動時にデータベースが再生成されます

# 検証

Count 素材を使用して実際に使用できるか検証します。

```bash
count % docker-compose up -d        
Creating network "count_default" with the default driver
Creating volume "count_postgres_volume" with default driver
Creating count_db_1 ... done
Creating count_web_1 ... done

count % docker-compose run web rake db:create
Creating count_web_run ... done
Created database 'data'

count % docker-compose run web rake db:migrate
Creating count_web_run ... done
== 20190423024537 CreateCounts: migrating =====================================
-- create_table(:counts)
   -> 0.0060s
== 20190423024537 CreateCounts: migrated (0.0067s) ============================
```

今回は `docker-compose.yml` で `4567` 番ポートに Web サーバがアタッチされているため、`http://localhost:4567` にアクセスすることで、確認することができます。

`http://localhost:4567` にアクセスすると以下のようになり、ちゃんと動いてることが確認できました！

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246409/88c04cec-7ae0-7433-a1b1-065a8251cca2.png)

# 終わりに

今回は Ruby(Sinatra)+Postgres の開発環境を Docker Compose を用いて構築してみました。
実は、東海の Advent Calendar で勝手に Windows のネイティブ環境構築編上げようかなと思うので、そちらもよろしくお願いいたします！

以上、「[Life is Tech ! Kanto Advent Calendar 2022](https://qiita.com/advent-calendar/2022/life-is-tech-kanto)」22 日目の記事でした。