返回 Skill 列表
extension
分类: 开发与工程无需 API Key

github-service-containers

在GitHub Actions工作流中将Docker服务容器(如Redis、PostgreSQL等)配置为边车服务,用于集成测试。当向CI工作流添加数据库、缓存或消息队列时,或者调试服务容器的网络和健康检查时使用。

person作者: jakexiaohubgithub

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

| Setting | Container Job | Runner Job | | ---------------- | ----------------------------------- | --------------------------------------------- | | container: | Set (e.g., node:20-bookworm-slim) | Omitted | | Service hostname | Label name (redis) | localhost | | ports: | Not needed | Required ('6379:6379') | | Dynamic port | N/A | ${{ job.services.<label>.ports['<port>'] }} | | Network | Docker 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

| Field | Purpose | | -------------- | ------------------------------------------------ | | 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

| Value | Description | | ------------- | ------------------------------------------------ | | 8080:80 | Maps container TCP port 80 to host port 8080 | | 8080:80/udp | Maps container UDP port 80 to host port 8080 | | 8080/udp | Maps 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.

| Service | Health command | Reference | | ---------- | -------------------- | ----------------------------------------------------- | | Redis | redis-cli ping | redis-service.md | | PostgreSQL | pg_isready | postgres-service.md | | Generic | curl -f http://... | Adapt per service |

Common health check options:

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

Reading Order

| Task | Files to Read | | --------------------------- | ------------------------------------ | | Add Redis to CI | SKILL.md + redis-service.md | | Add PostgreSQL to CI | SKILL.md + postgres-service.md | | Debug networking issues | SKILL.md (decision tree + quick ref) | | Add other service (generic) | SKILL.md (minimal definition) |

In This Reference

| File | Purpose | | ----------------------------------------------------- | -------------------------------------- | | redis-service.md | Redis config, health checks, test | | postgres-service.md | PostgreSQL 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