github-service-containers
3
总安装量
1
周安装量
#61493
全站排名
安装命令
npx skills add https://github.com/kjanat/skills --skill github-service-containers
Agent 安装分布
amp
1
opencode
1
cursor
1
kimi-cli
1
codex
1
github-copilot
1
Skill 文档
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-actionskill.
Prerequisites
- Linux runners only (
ubuntu-latestor 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 viajob.services.<label>.ports['6379'] - Composite actions: Service containers cannot be created inside composite actions