Self-hosted GitHub Actions Runner in Docker Container
- Register only one runner per container
- Use ephemeral mode for security-sensitive workflows
- Keep runner updated to latest version
- Limit network exposure of runner
- Do not store secrets in runner configuration
.env configuration example:
# Runner configuration
RUNNER_VERSION=2.328.0
RUNNER_URL=https://github.com/OWNER/REPO
RUNNER_TOKEN=PASTE_REGISTRATION_TOKEN_HERE
RUNNER_NAME=gh-runner
RUNNER_LABELS=self-hosted,linux
RUNNER_WORK=_work
EPHEMERAL=false| Variable | Purpose | Default |
|---|---|---|
RUNNER_VERSION |
GitHub Actions runner version | 2.328.0 |
RUNNER_URL |
Repository URL for runner registration | - |
RUNNER_TOKEN |
Registration token from GitHub | - |
RUNNER_LABELS |
Comma-separated runner labels | self-hosted,linux |
EPHEMERAL |
One-time use runner | false |
RUNNER_NAME |
Custom runner name | gh-runner |
RUNNER_WORK |
Working directory | _work |
1. Multi-architecture Support:
# Build for all supported platforms
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t ghcr.io/owner/gh-runner:latest .2. Ephemeral Mode:
# One-time runner that self-destructs after workflow
EPHEMERAL=true3. Automatic Configuration:
1. Container starts
2. Registers with GitHub
3. Creates health check file
4. Starts listening for jobs
5. Automatically unregisters on exit
Basic setup:
RUNNER_URL=https://github.com/ponfertato/ponfertato
RUNNER_TOKEN=abcdef1234567890Custom labels for specific workflows:
RUNNER_LABELS=self-hosted,linux,arm64,cpu-intensiveEphemeral runner for security:
# Only runs one workflow then unregisters
EPHEMERAL=trueRunner Lifecycle:
- Container startup
- GitHub registration
- Health check initialization
- Job execution
- Automatic cleanup on exit
Multi-arch Support:
x86_64 → linux-x64
arm64 → linux-arm64
armv7 → linux-arm
Build the multi-architecture Docker image locally:
docker compose -f gh-runner/docker-compose.yml buildThis creates a local Docker image with the specified runner version.
Launch the runner container in the background:
docker compose -f gh-runner/docker-compose.yml up -dThe runner will automatically:
- Register with GitHub using your provided token
- Start listening for workflow jobs
- Create a health check file when ready
- Unregister itself on container shutdown
To run multiple instances simultaneously:
# Update .env file
REPLICAS=3
# Recreate the service
docker compose -f gh-runner/docker-compose.yml up -d --force-recreateThis creates 3 identical runners that can handle multiple concurrent workflows.
Horizontal scaling:
# .env file
REPLICAS=3Distributed workloads:
# docker-compose.yml
deploy:
replicas: ${REPLICAS}MIT License