Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GitHub Actions: How to connect to Postgres in GithHub Actions

I am trying GitHub Actions for CI with a Ruby on Rails application.

My setup is with VM, not running the Ruby build in a container.

This is my workflow yml. It runs all the way without errors until the step "Setup Database".

name: Rails CI  on:   push:     branches:     - master   pull_request:     branches:     - master  jobs:   build:      runs-on: ubuntu-latest      services:       postgres:         image: postgres:10.10         env:           POSTGRES_USER: postgres           POSTGRES_PASSWORD: postgres           POSTGRES_DB: db_test         ports:           - 5432/tcp         options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5       redis:         image: redis:latest         ports:           - 6379/tcp      steps:     - uses: actions/checkout@v1      - name: Set up ruby 2.5       uses: actions/setup-ruby@v1       with:         ruby-version: 2.5.5      - name: Set up node 8.14       uses: actions/setup-node@v1       with:         node-version: '8.14'      - name: Setup system dependencies       run: sudo apt-get install libpq-dev      - name: Setup App Dependencies       run: |         gem install bundler -v 1.17.3 --no-document         bundle install --jobs 4 --retry 3         npm install         npm install -g yarn      - name: Run rubocop       run: bundle exec rubocop      - name: Run brakeman       run: bundle exec brakeman      - name: Setup Database       env:         RAILS_ENV: test         POSTGRES_HOST: localhost         POSTGRES_USER: postgres         POSTGRES_PASSWORD: postgres         POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}       run: |         cp config/database.yml.ci config/database.yml         bundle exec rails db:create         bundle exec rails db:schema:load      - name: Run rspec       env:         RAILS_ENV: test         REDIS_HOST: redis         REDIS_PORT: ${{ job.services.redis.ports[6379] }}         POSTGRES_HOST: localhost         POSTGRES_USER: postgres         POSTGRES_PASSWORD: postgres         POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}       run: bundle exec rspec --tag ~type:system 

I am able to install ruby, node, the images, Postgres as a service, etc, and run Rubocop and Brakeman. But when I try to set up the DB before running Rspec it says it cannot connect to the DB.

As far as I've been able to ascertain, the host is localhost when running the VM configuration as opposed to a container configuration.

This is the database.yml.ci that the "Setup Database" step copies to the database.yml to be used by Rails.

test:   adapter: postgresql   encoding: unicode   database: db_test   pool: 5   username: <%= ENV['POSTGRES_USER'] %>   password: <%= ENV['POSTGRES_PASSWORD'] %>   host: <%= ENV['POSTGRES_HOST'] %> 

I expected Postgres to be correctly set up and bundle exec rails db:create to create the database. However, it throws the following error:

rails aborted! PG::ConnectionBad: 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? 

I've tried all sorts of different configurations, but unfortunately, Actions is sort of knew and there doesn't seem to be a lot of material available online.

Any ideas on how to fix this?

===========================

EDIT:

So I was able to sort this out through trial and error. I ended up using a docker image with a ruby and node container. This is the working configuration:

on:   push:     branches:     - master   pull_request:     branches:     - master     - development     - release  jobs:   build:      runs-on: ubuntu-latest      container:       image: timbru31/ruby-node:latest      services:       postgres:         image: postgres:11         env:           POSTGRES_USER: postgres           POSTGRES_PASSWORD: postgres           POSTGRES_DB: ci_db_test         ports:           - 5432:5432         options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5      chrome:         image: selenium/standalone-chrome:latest         ports:           - 4444:4444      steps:     - uses: actions/checkout@v1      - name: Setup app dependencies       run: |         gem install bundler -v 1.17.3 --no-document         bundle install --jobs 4 --retry 3         npm install         npm install -g yarn      - name: Run rubocop       run: bundle exec rubocop      - name: Run brakeman       run: bundle exec brakeman      - name: Setup database       env:         RAILS_ENV: test         POSTGRES_HOST: postgres         POSTGRES_USER: postgres         POSTGRES_PASSWORD: postgres         POSTGRES_DB: ci_db_test         POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}       run: |         cp config/database.yml.ci config/database.yml         bundle exec rails db:create         bundle exec rails db:schema:load      - name: Run rspec       env:         RAILS_ENV: test         POSTGRES_HOST: postgres         POSTGRES_USER: postgres         POSTGRES_PASSWORD: postgres         POSTGRES_DB: ci_db_test         POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}         SELENIUM_URL: 'http://chrome:4444/wd/hub'       run: bundle exec rspec 

And the CI DB configuration database.yml.ci

default: &default   adapter: postgresql   encoding: unicode   username: <%= ENV['POSTGRES_USER'] %>   password: <%= ENV['POSTGRES_PASSWORD'] %>   host: <%= ENV['POSTGRES_HOST'] %>   pool: 5   database: <%= ENV['POSTGRES_DB'] %>  test:   <<: *default 
like image 227
Rui Freitas Avatar asked Sep 12 '19 23:09

Rui Freitas


1 Answers

I have a slightly different setup but this was the most relevant question when I encountered the same error so wanted to post here in case it can help. The two things that were critical for me were: 1) Set the DB_HOST=localhost 2) Set the --network="host" argument when you start the docker container with your rails app

name: Master Build  on: [push]  env:   registry: my_registry_name   # Not sure these are actually being passed down to rails, set them as the default in database.yml   DB_HOST: localhost   DB_USERNAME: postgres   DB_PASSWORD: postgres  jobs:   my_image_test:     runs-on: ubuntu-latest      services:       postgres:         image: postgres:latest         env:           POSTGRES_DB: postgres                   POSTGRES_PASSWORD: postgres           POSTGRES_USER: postgres         ports:           - 5432:5432         # Set health checks to wait until postgres has started         options: >-           --health-cmd pg_isready           --health-interval 10s           --health-timeout 5s           --health-retries 5      steps:       - name: Check out repository         uses: actions/checkout@v2       - name: Build my_image docker image         uses: whoan/docker-build-with-cache-action@v5         with:           username: "${{secrets.aws_ecr_access_key_id}}"           password: "${{secrets.aws_ecr_secret_access_key}}"           registry: "${{env.registry}}"           image_name: my_image           context: my_image       - name: Lint rubocop         working-directory: ./my_image         run: docker run $registry/my_image bundle exec rubocop       - name: Run rails tests         working-directory: ./my_image         run: docker run --network="host" $registry/my_image bash -c "RAILS_ENV=test rails db:create && RAILS_ENV=test rails db:migrate && rails test" 
like image 181
aoh Avatar answered Oct 06 '22 12:10

aoh