Can't connect to Postgres service

I have written a github action that runs tests in a docker container. Sometimes users of that action will want to connect to a database for the tests, I would expect they could just use a postgres service to do so,  but currently I cannot get that to work. 

name: On Prs
on: [pull_request]

jobs:
  run_tests:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:11-alpine
        env:
          POSTGRES_USER: monster
          POSTGRES_PASSWORD: monster
        ports:
          - "54321:5432"
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 10

    steps:
      - uses: actions/checkout@v2
      - name: "run dem tests"
        uses: Adzz/elixir_run_tests_action@v2.0.0

The app is correctly configured to listen port 54321 and the db user and password are configured correctly to both be monster. Is there something obvious I am missing??

The error is:

(DBConnection.ConnectionError) tcp connect (postgres:54321): connection refused - :econnrefused  

Thanks!

Hi @adzz ,

Thank you for being here!

From your code ‘ports: - “54321:5432”’, you are mapping TCP port 5432 in the container to port 54321 on the Docker host. I don’t have your exact code, so if your app is listening port on host runner, it should be ‘54321’ port.

But since you’re using a github container action to communicate with postgres service, as doc mentioned:

your step uses container actions, you don’t need to map ports to access the service or action. Docker automatically exposes all ports between containers on the same Docker user-defined bridge network. You can directly reference the service container by its hostname. The hostname is automatically mapped to the label name you configure for the service in the workflow.

You should not need to listen to the port but reference its hostname/label name directly.

Thanks.

1 Like

Thanks for the response, that was a typo my App was configured to listen to 54321, so it should have been working.

If i drop the port mapping how will it know what port my app is configured to listen to? Indeed if i do that it (predictably) doesn’t connect to the database.

1 Like

Hi @adzz,

Thanks for your reply!  You can use this snippet environment variable in the env setting,  then workflow will know which port is used for connection.

POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}

There is  actions/example-services for using Actions with services in both a VM and Docker container. Hope it helps!

1 Like

Hi,

I have the same issue.

this is my workflow file

name: Django CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      max-parallel: 4
      matrix:
        python-version: [3.7]

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres:12-alpine
        # Provide the password for postgres
        env:
          POSTGRES_USER: admin
          POSTGRES_PASSWORD: admin
          POSTGRES_DB: app

        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:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v1
      with:
        python-version: ${{ matrix.python-version }}
        
    - name: Install pip-tools
      run: |
        pip install --upgrade pip
        pip install pip-tools

    - name: Cache dependencies
      uses: actions/cache@v1
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('project/requirements/*.txt') }}
        restore-keys: |
          ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('project/requirements/*.txt') }}

    - name: Install Dependencies
      run: |
        pip-sync project/requirements/base.txt project/requirements/dev.txt

    - name: Prepare test results
      run: |
        mkdir -p out/tests
        
    - name: Run Linter
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 project --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 project --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --output-file out/tests/flake8-${{ matrix.python-version }}-project.txt

    - name: Run Tests
      run: |
        pytest project --junitxml=out/tests/pytest-${{ runner.os }}-${{ matrix.python-version }}-project.xml
      env:
        SQL_DATABASE: app
        SQL_USER: admin
        SQL_PASSWORD: admin
        SQL_PORT: ${{ job.services.postgres.ports[5432] }}
        SQL_HOST: postgres
        
    - name: Archive Linter results
      uses: actions/upload-artifact@v2.0.1
      with:
        name: flake8-results
        # A file, directory or wildcard pattern that describes what to upload
        path: out/tests/flake8-*.txt

    - name: Archive Test results
      uses: actions/upload-artifact@v2.0.1
      with:
        name: pytest-results
        # A file, directory or wildcard pattern that describes what to upload
        path: out/tests/pytest-*.xml

my app is a django app that uses some environment variables to connect to postgres

in the logs I see that the django app uses the right values but I see that string

psycopg2.OperationalError: could not translate host name "postgres" to address: Temporary failure in name resolution
1 Like

That looks like your test is running on the host, not in a second container. In that case you can’t use the service container name, instead you’ll have to use localhost and the mapped port (5432 in your workflow).

2 Likes

yep, I understood and fixed the issue this morning

2 Likes