Github ActionsでRailsがDBと接続できなかった話

Github Actions上で動くCIの設定ファイルを書いていて、様々なサイトや公式ドキュメントを参考にしてもうまく動かず途方に暮れてました。

起きていた問題

POSTGRES_HOSTやdatabase.ymlのhostをコンテナ名にしたりlocalhostにしたり試行錯誤して、以下のようなエラーが出ていました。

| could not connect to server: Connection refused
|       Is the server running on host "localhost" (::1) and accepting
|       TCP/IP connections on port 5432?
| could not connect to server: Connection refused
|       Is the server running on host "localhost" (127.0.0.1) and accepting
|       TCP/IP connections on port 5432?
| Couldn't create 'app_test' database. Please check your configuration.
| rails aborted!
| ActiveRecord::ConnectionNotEstablished: could not connect to server: Connection refused
|       Is the server running on host "localhost" (::1) and accepting
|       TCP/IP connections on port 5432?
| could not connect to server: Connection refused
|       Is the server running on host "localhost" (127.0.0.1) and accepting
|       TCP/IP connections on port 5432?
| could not translate host name "postgres" to address: Name or service not known
| Couldn't create 'app_test' database. Please check your configuration.
| rails aborted!
| ActiveRecord::NoDatabaseError: could not translate host name "postgres" to address: Name or service not known
| could not translate host name "db" to address: Name or service not known
| Couldn't create 'app_test' database. Please check your configuration.
| rails aborted!
| ActiveRecord::NoDatabaseError: could not translate host name "db" to address: Name or service not known

結論

僕はGithub Actionsに毎回Pushするのが嫌でactというツールを使っていました。

結論としてはこのactがサービスコンテナに対応してないのが問題でした。

サービスコンテナに対応してないために、サービスコンテナ上に立ったポスグレDBに接続ができなかったのです。

なのでCIの設定は以下のような設定でPushしたらうまく動いていました。

# rails-base-project/.github/workflows/ci.yml

name: Rails

on: push

jobs:
  rails_test:
    name: Rails test
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:13.4
        env:
          POSTGRES_DB: postgres
          POSTGRES_USER: pguser
          POSTGRES_PASSWORD: password
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
        - 5432:5432
      redis:
        image: redis:6.0
        options: >-
          --health-cmd "redis-cli -h localhost ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 1
    container:
      image: ruby:3.0.2
      env:
        RAILS_ENV: test
        DATABASE_PORT: 5432
        DATABASE_HOST: postgres
        REDIS_URL: redis://redis:6379/1
    steps:
      - uses: actions/checkout@v2
      - name: Install library for postgres
        run: apt-get update && apt-get -yqq install libpq-dev
      - name: Bundle install
        run: bundle install --path=vendor/bundle --jobs 4 --retry 3
      - name: Install Node.js
        run: |
          curl -sL https://deb.nodesource.com/setup_14.x | bash -
          apt-get update && apt-get install -y nodejs
      - name: Install dependencies
        run: npm i
      - name: Setup test database
        run: |
          bundle exec rails db:create
          bundle exec rails db:seed
      - name: Run tests
        run: bundle exec rspec
# rails-base-project/config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: <%= ENV.fetch("DATABASE_HOST", 'localhost') %>
  port: <%= ENV.fetch("DATABASE_PORT", 5432) %>
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: app_development
  username: pguser
  password: password

test:
  <<: *default
  database: app_test
  port: 5432
  username: pguser
  password: password

production:
  <<: *default
  database: app_production
  username: <%= ENV['DATABASE_UERNAME'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>

ソースコードはこちらに公開してます。

https://github.com/yosipy/rails-base-project

まとめ

僕はあまりDockerなどのコンテナ周りが専門ではないので、Rubyやpostgresのバージョンの問題なのか?何か書き方が間違っているのか?Portやhostの設定が違うのかと迷走してしまいました。

しかし、act自体が対応してなかったとは夢にも思いませんでした。。。

これが参考になって貴重な休日を無駄にしなかったのであれば幸いです。

僕の日曜日は帰ってこないので。