Github Actions services not reachable

I’m trying to use Github Actions with a Docker compose-like setup. I would like to use a service container to start a postgres instance, to connect to from an elixir container. The way I read the docs, this should work:

name: CI / Automated testing
on: push

jobs:
  test:
    name: Unit & integration tests
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:11
        ports:
          - 5432:5432
        env:
          POSTGRES_PASSWORD: supersecret

    container:
      image: elixir:1.9-slim
      env:
        MIX_ENV: test
        POSTGRES_PORT: 5432
        POSTGRES_HOSTNAME: postgres
        POSTGRES_PASSWORD: supersecret

    steps:
      - name: Checkout code
        uses: actions/checkout@master
      - name: Install dependencies
          mix do local.hex --force, local.rebar --force, deps.get
      - name: Compile code (warnings as errors)
        run: mix compile --warnings-as-errors
      - name: Check code formatting
        run: mix format --check-formatted
      - name: Run tests
        run: mix test

But sadly it does not work. Setting POSTGRES_HOSTNAME to localhost also does not seem to work. Does anybody know how to fix the issue?

2 Likes

And yes, those environment variables are correctly picked up by the application and it really tries to connect to the hostname set in the variable :wink:

Anybody? @jeremyepling, might you be able to help? I cannot for the life of me get this working.

name: CI / Automated testing
on: push

jobs:
  test:
    name: Unit & integration tests
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:11
        ports:
          - 5432:5432
        env:
          POSTGRES_PASSWORD: supersecret

    container:
      image: elixir:1.9-slim
      env:
        MIX_ENV: test
        POSTGRES_HOSTNAME: localhost
        POSTGRES_PASSWORD: supersecret

    steps:
      - name: Display build environment
        run: printenv
      - name: Checkout code
        uses: actions/checkout@master
      - name: Install dependencies
        run: mix do local.hex --force, local.rebar --force, deps.get
      - name: Run tests
        run: mix test
        env:
          POSTGRES_PORT: ${{ job.services.postgres.ports['5432'] }}

I’ve tried:

 - setting hostname to “postgres” and “localhost”

 - setting service port to 5432 and 5432:5432

 - setting env POSTGRES_PORT to 5432 and ${{ job.services.postgres.ports[‘5432’] }}

Or you @ethomson ?

One possibility is that the postgres service is not fully started by the time your steps try to access it (I’ve seen this issue for mysql, postgres, etc)

You can try adding a healthcheck via options (or in the Dockerfile, if you were building your own service container). The actions runner will respect the health status of the services before finalizing the “Initialize containers” step:

services:
postgress:
  image: postgres:11
   options: >-
    --health-cmd pg_isready
     --health-interval 10s
     --health-timeout 5s
     --health-retries 5

Sorry if the formatting got messed up via pasting here, and hope that helps

3 Likes

Additionally, just in case I skimmed your question too fast and missed something:

All the containers in a job are connected to the same Docker network. This means you can access other containers using their network alias (we assign the network alias based on the service name), which in your case is “postgres”, so you can also try using “postgres” as the POSTGRES_HOSTNAME inside your steps there. 

As a nit, you do not need to expose ports explictly here, because all the containers on Docker network automatically expose ports to each other (https://docs.docker.com/network/bridge/

If you were *not* using a job container, you would be correct in needing to access the service via localhost, and needing to bind a port on the host machine

I have the exact same problem as @juulsme but with my dynamodb-local service

services:
dynamodb:
image: amazon/dynamodb-local
ports:
- 8000:8000

being unreachable from localhost:8000.

I’m currently trying to inspect the container because a simple docker ps -a during my steps shows that the container is stopped … 

EDIT SOLVED:

workdir is overwritten in services with the path to a volume where you repo codes lives.

I think this should be optionnal and easily opted-out because I think the main use case for services is just to run a service that will never interact with your main repo code.

The fix for running dynamodb-local in a service is to switch back to the old workdir where the dynamodb-local JAR is located.

services:
dynamodb:
image: amazon/dynamodb-local
options: --workdir /home/dynamodblocal
ports:
- 8000:8000

N.B : I’ve found the correct workdir by using docker history on the image as the Dockerfile for dynamodb-local is not public (I think) 

Thank you for your response, I will try with the health check tomorrow! (it’s midnight where I live now). I know about the docker networks, I’ve tried using the container hostname first - that seemed most logical to me as well and I also spotted that the containers are started with the same network flag. I’ll give it a go with the healthcheck :slight_smile:

And I’ll try the workdir thing too :slight_smile:

The healthcheck thing did the trick, although I’ll keep the changed workdir in mind for future reference. Thanks for your help!

In the end, the solution was to “do things like in compose” plus the healtcheck:

name: CI / Automated testing
on:
  push:
    branches:

jobs:
  test:
    name: Unit & integration tests
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:11
        env:
          POSTGRES_PASSWORD: supersecret
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    container:
      image: elixir:1.9-slim
      env:
        POSTGRES_HOSTNAME: postgres
        POSTGRES_PASSWORD: supersecret
        POSTGRES_PORT: 5432

    steps:
      - name: Checkout code
        uses: actions/checkout@master
      - name: Install dependencies
        run: mix do local.hex --force, local.rebar --force, deps.get
      - name: Run tests
        run: mix test
2 Likes