github-service-containers

Configure Docker service containers (Redis, PostgreSQL, etc.) as sidecar services in GitHub Actions workflows for integration testing. Use when adding databases, caches, or message queues to CI workflows, or debugging service container networking and health checks.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "github-service-containers" with this command: npx skills add kjanat/skills/kjanat-skills-github-service-containers

GitHub Actions Service Containers

Run Docker containers (Redis, PostgreSQL, etc.) alongside workflow jobs for integration testing.

Not what you need? For building Docker container actions (Dockerfile + action.yml), see the github-docker-action skill.

Prerequisites

  • Linux runners only (ubuntu-latest or self-hosted Linux with Docker)
  • Service containers cannot be used inside composite actions
  • Each service is created fresh per job and destroyed when the job completes

Job Type Decision Tree

Networking depends on whether your job runs in a container or on the runner:

Where does your job run?
├─ In a container (`container:` key set)
│   ├─ Hostname: service label name (e.g., `redis`, `postgres`)
│   ├─ Port mapping: NOT needed (Docker bridge network)
│   └─ See reference files → "Container Job" sections
│
└─ Directly on runner (no `container:` key)
    ├─ Hostname: `localhost`
    ├─ Port mapping: REQUIRED (e.g., `ports: ['6379:6379']`)
    └─ See reference files → "Runner Job" sections

Quick Reference

SettingContainer JobRunner Job
container:Set (e.g., node:20-bookworm-slim)Omitted
Service hostnameLabel name (redis)localhost
ports:Not neededRequired ('6379:6379')
Dynamic portN/A${{ job.services.<label>.ports['<port>'] }}
NetworkDocker bridge (automatic)Host network via mapped ports

Minimal Service Definition

services:
  redis:
    image: redis
    ports:
      - 6379:6379
    options: >-
      --health-cmd "redis-cli ping"
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5

Service fields

FieldPurpose
image:Docker Hub image (or ghcr.io/... for private)
ports:Host:container port mapping (runner jobs only)
options:Docker --health-* flags for readiness checks
env:Environment variables passed to the container
credentials:username: / password: for private registries

Port mapping syntax

ValueDescription
8080:80Maps container TCP port 80 to host port 8080
8080:80/udpMaps container UDP port 80 to host port 8080
8080/udpMaps random host port to container UDP port 8080

Private Registry Authentication

services:
  db:
    image: ghcr.io/org/private-image:latest
    credentials:
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}
  cache:
    image: redis
    credentials:
      username: ${{ secrets.DOCKERHUB_USERNAME }}
      password: ${{ secrets.DOCKERHUB_PASSWORD }}

Health Checks

Always define health checks — without them, job steps start before the service is ready.

ServiceHealth commandReference
Redisredis-cli pingredis-service.md
PostgreSQLpg_isreadypostgres-service.md
Genericcurl -f http://...Adapt per service

Common health check options:

options: >-
  --health-cmd "<command>"
  --health-interval 10s
  --health-timeout 5s
  --health-retries 5

Reading Order

TaskFiles to Read
Add Redis to CISKILL.md + redis-service.md
Add PostgreSQL to CISKILL.md + postgres-service.md
Debug networking issuesSKILL.md (decision tree + quick ref)
Add other service (generic)SKILL.md (minimal definition)

In This Reference

FilePurpose
redis-service.mdRedis config, health checks, test
postgres-service.mdPostgreSQL config, health checks, test

Gotchas

  • Windows/macOS runners: Service containers are Linux-only
  • Missing health checks: Steps start immediately; service may not be ready
  • Port conflicts: Two services mapping the same host port fail silently
  • container: + ports:: Port mapping is ignored in container jobs (bridge handles it)
  • Dynamic ports: Omit host port (- 6379) then read via job.services.<label>.ports['6379']
  • Composite actions: Service containers cannot be created inside composite actions

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

github-script

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-docker-action

No summary provided by upstream source.

Repository SourceNeeds Review
General

changelog-writing

No summary provided by upstream source.

Repository SourceNeeds Review