Skip to content

GitHub Actions Service Container Connection Refused Fix

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about GitHub Actions Service Container Connection Refused Fix. We cover key concepts, practical examples, and best practices.

Your workflow connects to a service container (PostgreSQL, Redis, MySQL) and gets Connection refused — the service container isn't ready when your job step runs.

The Problem

# WRONG — no health check before using the service
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
    steps:
      - run: psql -h localhost -U postgres -c "SELECT 1"
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed:
Connection refused

PostgreSQL takes several seconds to initialize. The step runs before the service is ready to accept connections.

Step-by-Step Fix

1. Add a health check to the service

services:
  postgres:
    image: postgres:16
    env:
      POSTGRES_PASSWORD: postgres
    ports:
      - 5432:5432
    options: >-
      --health-cmd pg_isready
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5

GitHub Actions waits for the health check to pass before starting job steps.

2. Add a wait step as fallback

steps:
  - name: Wait for PostgreSQL
    run: |
      for i in $(seq 1 30); do
        pg_isready -h localhost && break
        sleep 2
      done

3. Use the service container hostname

services:
  redis:
    image: redis:7
    ports:
      - 6379:6379

steps:
  - run: |
      redis-cli -h redis -p 6379 PING

Service containers are accessible via localhost (when ports are mapped) or via the service name (redis, postgres) on the container network.

4. Match environment variables to service ports

services:
  mysql:
    image: mysql:8
    env:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
    ports:
      - 3306:3306

steps:
  - run: |
      mysql -h 127.0.0.1 -P 3306 -u root -proot -e "SHOW DATABASES;"

Expected output:

✓ PostgreSQL is ready (accepting connections)
✓ SELECT 1 returned 1 row

Prevention Tips

  • Add --health-cmd to every service container
  • Use --health-retries 5 for services with slow startup
  • Add a manual wait-for-it.sh step for unsupported images
  • Use the service name as hostname when no port is mapped
  • Check service logs with docker logs when debugging

Common Mistakes with actions service container

  1. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  2. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  3. Using head and tail instead of pattern matching, causing runtime errors on empty lists

These mistakes appear frequently in real-world GITHUB code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why can't my job connect to localhost when the service has ports mapped?

The service container runs on the same Docker network as the job container. Port mapping (5432:5432) makes it accessible via localhost on the host. If it still fails, check that no other service is using the port and that the service started correctly.

How do I debug a service container that won't start?

Add a step to inspect the service: docker ps -a to list containers, docker logs <container> to check startup logs. Remove --health-cmd temporarily to see if the service container itself starts. Verify image name and tags are correct.

Can I use docker-compose services in GitHub Actions?

No. GitHub Actions supports services at the job level but not docker-compose.yml. Define each service individually under the services: key. For complex multi-service setups, use a custom action that runs <a href="/devops/docker-compose/">docker compose</a> up.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro