Skip to content
Latchkey

How to Migrate CI Service Containers to GitHub Actions

GitLab services, CircleCI secondary docker images, and Bitbucket services all map to the GitHub Actions services block with health checks.

A backing service (Postgres, Redis) launched alongside your job maps to the services: block. Add health-check options: so steps wait for readiness, and connect on the mapped localhost port.

Concept mapping

SourceGitHub Actions
GitLab services:services:
CircleCI extra docker: imageservices:
Bitbucket services:services:
readiness waithealth-check options:

After

.github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: test
        ports: ['5432:5432']
        options: >-
          --health-cmd "pg_isready" --health-interval 10s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - run: DATABASE_URL=postgres://postgres:test@localhost:5432/postgres npm test

What does not map cleanly

  • Without health checks, steps may start before the service is ready; other tools sometimes wait implicitly.
  • When the job itself runs in a container, connect to the service by its name, not localhost.
  • GitLab lets you alias services; in Actions the service key is the hostname within a container job.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →