CircleCI × docker-compose をRailsアプリに導入してみた

Railsアプリに`CircleCI`と`docker-compose`を導入してみました。
以下記録も兼ねて残しておきます。


```.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.8-node-browsers
        environment:
          - BUNDLER_VERSION: 2.2.33
          - RAILS_ENV: test
          - POSTGRES_USER: <%= ENV['POSTGRES_USER'] %>
      - image: circleci/postgres
        environment:
          - POSTGRES_USER: <%= ENV['POSTGRES_USER'] %>
          - POSTGRES_PASSWORD: <%= ENV['POSTGRES_PASSWORD'] %>
          - POSTGRES_DB: port_test
    environment:
      - PGHOST: 127.0.0.1
    working_directory: ~/port
    steps:
      - checkout
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-
      - run:
          name: install dependencies
          command: |
            gem install bundler -v 2.2.33
            bundle install --jobs=4 --retry=3 --path vendor/bundle
      - save_cache:
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - ./vendor/bundle
      - run:
          name: Wait DB start-up
          command: dockerize -wait tcp://127.0.0.1:5432 -timeout 120s
      - run:
          name: Setup database
          command: |
            sudo ln -s /usr/lib/x86_64-linux-gnu/libffi.so.7.1.0 /usr/lib/x86_64-linux-gnu/libffi.so.6
            bundle exec rails db:create
            bundle exec rails db:migrate
            bundle exec rails webpacker:install
      - run:
          name: Run rspec
          command: bundle exec rspec
      - run:
          name: Run rubocop
          command: bundle exec rubocop

```



```:Dockerfile
FROM ruby:2.6.8
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

WORKDIR /port
COPY Gemfile /port/Gemfile
COPY Gemfile.lock /port/Gemfile.lock
RUN gem install -v 2.2.33 bundler 
RUN bundle install
RUN gem install -v 6.1.4.1 rails
COPY . /port

# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# イメージ実行時に起動させる主プロセスを設定
CMD ["rails", "server", "-b", "0.0.0.0"]
```


```docker-compose.yml
version: "3"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: <%= ENV['POSTGRES_USER'] %>
      POSTGRES_PASSWORD: <%= ENV['POSTGRES_PASSWORD'] %>
    ports:
      - '5432:5432'

  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/port
    ports:
      - "3000:3000"
    environment:
      DATABASE_PORT: 5432
      DATABASE_USER: <%= ENV['POSTGRES_USER'] %>
      DATABASE_PASSWORD: <%= ENV['POSTGRES_PASSWORD'] %>
    depends_on:
      - db

```



```database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  host: db
  timeout: 5000
  username: <%= ENV['POSTGRES_USER'] %>
  password: <%= ENV['POSTGRES_PASSWORD'] %>

development:
  <<: *default
  database: port_development

test:
  <<: *default
  database: port_test
  host: <%= ENV['PGHOST'] || 'db' %>

production:
  <<: *default
  database: port_production

```

# 遭遇したエラー

### 1. Please upgrade Node.jsとエラーが表示される
Webpackerが必要とするNode.jsのバージョンが10.17.0以上であるのに対し当時のNode.jsのバージョンは10.16.3。
![スクリーンショット 2021-12-17 23.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/865b3118-39b8-1ece-9391-12d5b88cf62c.png)
##### → rubyのバージョンを`2.6.3`から`2.6.8`に上げたら解決できた。
gemの依存関係とかもあるのであまりやらない方が良いかも、、今回は上がり幅が小さかったのでこのやり方で解決しました。

---

### 2. ローカルとCircleCIでデータベースのホスト名が異なる
RSpecやRubocopなどのテストをする場合、ローカルでは`db`というホスト名、CircleCIでは`localhost`にそれぞれ接続する必要があります。なので

```database.yml（一部抜粋）
test:
  <<: *default
  database: port_test
  host: <%= ENV['PGHOST'] || 'db' %>
```

```.circleci/config.yml（一部抜粋）
environment:
      - PGHOST: 127.0.0.1
```

とすることによって`PGHOST`がある場合はそちらを参照、無い場合は`db`に接続するように設定しました。


# 参考
[[CircleCI] ローカルでCircleCIを使いたい](https://zenn.dev/wtkn25/articles/circleci-local-setting)
[まさかPushデバッグしてないよね？ よく使うCircleCIのデバッグ方法](https://blog.vtryo.me/entry/circleci-debug-method)
[【CircleCI】Railsアプリに導入（設定ファイルについて）](https://qiita.com/Daiki-Abe/items/d90599d904c2b1370d10)
[【Rails】GithubとCircleCIを連携してcommit時にrspecとrubocopを動かす](https://qiita.com/junara/items/a40bb231c405be7983f7)
[Rails + CircleCIでRSpecを実行しようとするとDBのエラーが出る](https://teratail.com/questions/285185)
[dockerとcircleciを使ってRSpecテストするとPlease upgrade Node.jsとエラーが表示される](https://teratail.com/questions/374359)