Study guide

6.3 Service Containers & Network Topology

GitHub Actions Certification GH-200

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Introduction & Exam Overview

1.1 Exam Structure, Format & Scoring 1.2 GitHub Actions Architecture & Core Mental Model 1.3 Hands-On Preparation & Exam Day Strategy

2 Chapter 2: Workflow Triggers & Event Architecture

2.1 Webhook & Code Events: push, pull_request, and pull_request_target 2.2 Scheduled & Manual Triggers: schedule, workflow_dispatch, and repository_dispatch 2.3 Release, Issue, and Dynamic Lifecycle Events 2.4 Branch, Tag, and Path Filtering Patterns

3 Chapter 3: Jobs, Matrix Strategies & Execution Control

3.1 Job Anatomy, Step Execution & Job Dependencies (needs) 3.2 Contexts, Expressions & Functions 3.3 Environment Variables & Workflow Commands 3.4 Matrix Strategies & Multi-Platform Builds 3.5 YAML Anchors, Aliases & Merge Keys

4 Chapter 4: Reusable Workflows & Troubleshooting

4.1 Authoring & Calling Reusable Workflows (workflow_call) 4.2 Comparing Reusable Workflows, Composite Actions & Starter Workflows 4.3 Troubleshooting Workflow Runs & Debug Logging 4.4 Concurrency Controls & Status Check Functions

5 Chapter 5: Authoring Custom Actions

5.1 Action Architecture & action.yml Specification 5.2 Authoring Composite Actions 5.3 Building JavaScript Actions 5.4 Building Docker Container Actions

6 Chapter 6: Action Distribution, Marketplace & Advanced Action Types

6.1 Action Versioning, Semantic Releases & Tagging 6.2 Publishing Actions to GitHub Marketplace 6.3 Service Containers & Network Topology 6.4 actions/github-script & Workflow Tooling

7 Chapter 7: Runner Infrastructure & Self-Hosted Runners

7.1 GitHub-Hosted Runners & Larger Runners 7.2 Self-Hosted Runner Setup, Architecture & Communication 7.3 Self-Hosted Runner Security & Ephemeral Runners 7.4 Runner Groups, Labels & Organization Routing

8 Chapter 8: Enterprise Governance, Policies & Environments

8.1 Enterprise & Organization Action Policies 8.2 Environments, Protection Rules & Deployment Approvals 8.3 Repository Rulesets, Required Status Checks & Governance 8.4 Usage Limits, Billing Multipliers & Usage Metrics

9 Chapter 9: Secrets, Permissions & OIDC Cloud Authentication

9.1 Encrypted Secrets Architecture & Scopes 9.2 GITHUB_TOKEN & Least Privilege Configuration 9.3 OpenID Connect (OIDC) & Workload Identity Federation 9.4 Script Injection Prevention & Secure Workflow Patterns

10 Chapter 10: Supply Chain Hardening & Performance Optimization

10.1 Supply Chain Hardening: SHA Pinning, Dependabot & Artifact Attestations 10.2 Caching Dependencies with `actions/cache` 10.3 Artifacts Management & Job Handoff 10.4 Workflow Performance, Cost Optimization & Architecture Review

6.3 Service Containers & Network Topology

Key Takeaways Explain This Topic AI

Service containers ( services: ) provide ephemeral, isolated Docker containers (e.g., PostgreSQL, Redis, MySQL) alongside workflow jobs to facilitate integration and end-to-end testing.

When a job runs directly on a virtual machine host runner, service container ports must be mapped ( ports: - 5432:5432 ), and steps communicate with the service via localhost:<port> or 127.0.0.1:<port> .

When a job runs inside a container ( container: { image: ... } ), all service containers and the job container share the same user-defined Docker bridge network, allowing direct communication via the service container name ( postgres:5432 , redis:6379 ) without port mapping.

Service health checks ( options: --health-cmd ... --health-interval ... --health-timeout ... --health-retries ... ) ensure the service daemon is fully initialized before workflow steps begin execution.

Service containers are isolated per job and automatically torn down when the job finishes, preventing cross-test data pollution and resource leaks.

Last updated: August 2026

Service Containers & Network Topology

Modern continuous integration pipelines require realistic testing environments that mirror production infrastructure. Rather than relying on fragile mock libraries, integration tests frequently require real database engines (PostgreSQL, MySQL, MongoDB), in-memory caches (Redis, Memcached), or messaging brokers (RabbitMQ, Kafka).

GitHub Actions provides Service Containers ( services: ) to host these auxiliary services in ephemeral, isolated Docker containers for the duration of a job. Mastering the network topology differences between host-level VM jobs and containerized jobs is a fundamental concept on the GH-200 exam.

1. Service Containers Architecture & Lifecycle

A service container is declared under the jobs.<job_id>.services key. GitHub Actions manages the complete lifecycle of service containers:

Pre-Job Initialization: Before any workflow steps execute, the runner pulls the container images and starts all defined service containers concurrently.

Health Check Validation: If health checks are configured, the runner waits until all services report a healthy status before invoking the first step.

Step Execution: Job steps interact with the services across the network.

Post-Job Teardown: Once all job steps complete (whether successful, failed, or cancelled), the runner automatically stops and deletes all service containers and their associated networks. +-----------------------------------------------------------------------------+

  • | SERVICE CONTAINER LIFECYCLE |
  • | |
  • | [Job Queued] ──> [Pull Images & Start Containers in Parallel] |
  • | │ |
  • | v |
  • | [Evaluate Health Checks (--health-cmd)] |
  • | │ |
  • | v |
  • | [Execute Job Steps (Checkout, Test)] |
  • | │ |
  • | v |
  • | [Stop & Destroy Service Containers] ──> [Job Completed] |
  • +-----------------------------------------------------------------------------+
  • 2. Network Topology: Host VM Runner vs. Container Job

The way workflow steps connect to service containers depends entirely on whether the job itself executes directly on the host virtual machine or inside a job container . +-----------------------------------------------------------------------------+

  • | SCENARIO A: JOB ON HOST VM RUNNER |
  • | |
  • | +---------------------------------------------------------------------+ |
  • | | RUNNER HOST VM (runs-on: ubuntu-latest) | |
  • | | | |
  • | | Steps execute on Host OS: | |
  • | | `npm test` connects to: `localhost:5432` or `127.0.0.1:6379` | |
  • | | │ │ | |
  • | | │ Port 5432:5432 │ Port 6379:6379 | |
  • | | v v | |
  • | | +───────────────────────────+ +───────────────────────────+ | |
  • | | | Service Container: pg | | Service Container: redis | | |
  • | | | image: postgres:16 | | image: redis:7-alpine | | |
  • | | +───────────────────────────+ +───────────────────────────+ | |
  • | +---------------------------------------------------------------------+ |
  • +-----------------------------------------------------------------------------+
  • +-----------------------------------------------------------------------------+
  • | SCENARIO B: JOB INSIDE CONTAINER |
  • | |
  • | +---------------------------------------------------------------------+ |
  • | | RUNNER HOST VM (runs-on: ubuntu-latest) | |
  • | | | |
  • | | +----------------------- DOCKER BRIDGE NETWORK -----------------+ | |
  • | | | | | |
  • | | | +──────────────────────+ +──────────────────────────+ | | |
  • | | | | Job Container | | Service Container | | | |
  • | | | | (container: node:20) | | (services.postgres) | | | |
  • | | | | | | | | | |
  • | | | | Connects directly |──────>| Hostname: 'postgres' | | | |
  • | | | | to: 'postgres:5432' | | Port: 5432 (Internal) | | | |
  • | | | +──────────────────────+ +──────────────────────────+ | | |
  • | | | | | |
  • | | +───────────────────────────────────────────────────────────────+ | |
  • | +---------------------------------------------------------------------+ |
  • +-----------------------------------------------------------------------------+
  • Detailed Comparison Matrix

Configuration Dimension Job on Host VM Runner ( runs-on: ubuntu-latest ) Job in Container ( container: node:20 )

Where Steps Run Directly in the host virtual machine operating system. Inside the specified container execution context.

Service Hostname localhost or 127.0.0.1 Service container label name (e.g., postgres , redis ).

Port Mapping ( ports: ) Mandatory: Must map host port to container port (e.g., 5432:5432 ). Not Required: Containers share the Docker bridge network; all ports are accessible directly.

Docker Network Runner creates bridge network for services; maps ports to host. Runner attaches job container and service containers to the same bridge network.

DNS Resolution Host OS cannot resolve container names via Docker DNS. Docker internal DNS resolves container label names automatically.

Warning

If your job runs on a host VM and you omit the ports: declaration in your service definition, your steps will not be able to connect to the service container via localhost , resulting in connection refused errors ( ECONNREFUSED ).

3. Configuring Health Checks for Service Containers

Database engines and distributed systems take several seconds to initialize filesystems, run migrations, and open listening sockets. If steps execute before the service is ready, tests will fail with race conditions.

Health checks are configured using Docker daemon options passed via the options: key: services:

postgres:

image: postgres:16

env:

  • POSTGRES_DB: testdb
  • POSTGRES_USER: testuser
  • POSTGRES_PASSWORD: testpassword

ports:

  • 5432:5432
  • # Docker health check parameters
  • options: >-
  • -health-cmd pg_isready
  • -health-interval 10s
  • -health-timeout 5s
  • -health-retries 5
  • Health Check Parameters Explained

--health-cmd : The command executed inside the container to test service readiness (e.g., pg_isready , mysqladmin ping , redis-cli ping , or curl -f http://localhost:8080/health ).

--health-interval : The duration between consecutive health check probes (e.g., 10s ).

--health-timeout : The maximum time permitted for the health command to complete before marking the check as a failure (e.g., 5s ).

--health-retries : The number of consecutive failed checks required before the container is marked unhealthy (e.g., 5 ).

--health-start-period : Grace period providing the container time to bootstrap before health checks begin counting against retries.

4. Complete Multi-Service Integration Workflow

The following complete workflow demonstrates running both PostgreSQL and Redis service containers to support an integration test suite running on an Ubuntu VM host: name: Backend Integration Tests

on:

push:

branches: [main]

pull_request:

branches: [main]

jobs:

integration-suite:

runs-on: ubuntu-latest

services:

postgres:

image: postgres:16-alpine

env:

  • POSTGRES_DB: test_enterprise
  • POSTGRES_USER: runner_admin
  • POSTGRES_PASSWORD: secret_password123

ports:

  • 5432:5432
  • options: >-
  • -health-cmd pg_isready
  • -health-interval 10s
  • -health-timeout 5s
  • -health-retries 5

redis:

image: redis:7-alpine

ports:

  • 6379:6379
  • options: >-
  • -health-cmd "redis-cli ping"
  • -health-interval 5s
  • -health-timeout 3s
  • -health-retries 3

steps:

  • name: Checkout repository
  • uses: actions/checkout@v4
  • name: Setup Node.js runtime
  • uses: actions/setup-node@v4

with:

  • node-version: '20'
  • cache: 'npm'
  • name: Install test dependencies
  • run: npm ci
  • name: Execute Integration Tests against Services
  • run: npm run test:integration

env:

  • DATABASE_URL: postgres://runner_admin:secret_password123@localhost:5432/test_enterprise
  • REDIS_URL: redis://localhost:6379

Loading diagram... Service Container Startup, Health Verification, and Teardown Sequence