Act for Running GitHub Actions Locally
Act lets you run GitHub Actions workflows locally using Docker, giving you fast feedback without pushing commits to GitHub. This guide covers installing Act on Linux, configuring runner images, managing secrets, handling artifacts, and debugging failed workflows.
Prerequisites
- Docker installed and running
- A repository with GitHub Actions workflow files in
.github/workflows/ - Linux (Ubuntu/Debian or CentOS/Rocky), macOS, or WSL2
Installing Act
# Method 1: Install script (Linux/macOS)
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Method 2: Download binary directly
VERSION=$(curl -s https://api.github.com/repos/nektos/act/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4)
wget "https://github.com/nektos/act/releases/download/${VERSION}/act_Linux_x86_64.tar.gz"
tar xzf act_Linux_x86_64.tar.gz
sudo mv act /usr/local/bin/
chmod +x /usr/local/bin/act
# Method 3: Via Go
go install github.com/nektos/act@latest
# Verify installation
act --version
Basic Usage
Run from the root of a repository containing .github/workflows/:
# List all available workflows and jobs
act --list
# Run the default push event trigger
act push
# Run a specific workflow
act push --workflows .github/workflows/ci.yml
# Run a specific job by name
act push --job build
# Run a specific event
act pull_request
act release
act workflow_dispatch
# Dry run (show what would happen without executing)
act --dryrun push
Configuring Runner Images
GitHub's hosted runners include many pre-installed tools. Act uses Docker images to emulate them:
| Runner Label | Micro Image | Medium Image | Full Image |
|---|---|---|---|
| ubuntu-latest | node:16-buster-slim | catthehacker/ubuntu:act-20.04 | catthehacker/ubuntu:full-20.04 |
On first run, Act asks which image size to use. Choose based on your workflow needs:
# Use the medium image for best balance of speed and compatibility
act push --platform ubuntu-latest=catthehacker/ubuntu:act-22.04
# Use the full image for maximum compatibility
act push --platform ubuntu-latest=catthehacker/ubuntu:full-22.04
# Use a completely custom image
act push --platform ubuntu-latest=my-custom-runner:latest
Pre-pull images to save time:
docker pull catthehacker/ubuntu:act-22.04
docker pull catthehacker/ubuntu:full-22.04
Managing Secrets and Variables
# Pass a single secret via CLI flag
act push --secret MY_SECRET=value
# Use a secrets file (recommended)
cat > .secrets << 'EOF'
DOCKER_USERNAME=myuser
DOCKER_PASSWORD=mypassword
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=secret...
EOF
act push --secret-file .secrets
# Pass environment variables
act push --env NODE_ENV=test --env API_URL=http://localhost:3000
# Use an env file
cat > .env.act << 'EOF'
NODE_ENV=test
API_URL=http://localhost:3000
EOF
act push --env-file .env.act
Add .secrets to .gitignore:
echo ".secrets" >> .gitignore
echo ".env.act" >> .gitignore
Artifact Handling
Act supports artifact upload/download with a local artifact server:
# Enable artifact server (stores artifacts locally)
act push --artifact-server-path /tmp/act-artifacts
# With a specific port
act push --artifact-server-path /tmp/act-artifacts --artifact-server-port 34567
Example workflow using artifacts:
# .github/workflows/build.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: make build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: build-output
path: dist/
test:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/download-artifact@v3
with:
name: build-output
path: dist/
- name: Test
run: ls -la dist/
# Run the multi-job workflow with artifacts
act push --artifact-server-path /tmp/artifacts
ls /tmp/artifacts/
Debugging Failed Workflows
# Enable verbose output
act push --verbose
# Keep containers running after failure for inspection
act push --reuse
# Enter the container to debug manually
docker exec -it act-build-build bash
# View container logs
docker logs act-build-build
# Run with a shell open before the failing step
# Add this to your workflow temporarily:
# - name: Debug
# uses: mxschmitt/action-tmate@v3
# Watch container in real-time
act push --watch
# Rebuild container from scratch (don't reuse)
act push --pull=true --rm
Inspect Act's output more carefully:
# Save output to a file
act push 2>&1 | tee act-output.log
# Filter for errors only
act push 2>&1 | grep -E 'Error|FAIL|failed'
Act Configuration File
Create a .actrc file in your repository or home directory to avoid repeating flags:
cat > ~/.actrc << 'EOF'
# Default platform/runner image
--platform ubuntu-latest=catthehacker/ubuntu:act-22.04
--platform ubuntu-20.04=catthehacker/ubuntu:act-20.04
# Always use this secrets file
--secret-file /home/myuser/.act-secrets
# Default artifact path
--artifact-server-path /tmp/act-artifacts
# Container architecture
--container-architecture linux/amd64
EOF
Per-repository config at .actrc in the repo root overrides the global one.
Troubleshooting
Docker permission denied:
sudo usermod -aG docker $USER
newgrp docker
# Or run with sudo
sudo act push
Step fails with "command not found" in micro image:
Switch to the full runner image which has more pre-installed tools:
act push --platform ubuntu-latest=catthehacker/ubuntu:full-22.04
Cannot pull catthehacker images (slow or failing):
# Use a smaller alternative
act push --platform ubuntu-latest=node:18-bullseye
# Or pre-pull during off-peak hours
docker pull catthehacker/ubuntu:act-22.04
Action uses GitHub-specific APIs not available locally:
Some actions depend on GitHub APIs (e.g., github.token for PR comments). Set a fake token:
act push --secret GITHUB_TOKEN=fake_token_for_local_testing
Workflow uses workflow_call or workflow_dispatch with inputs:
act workflow_dispatch --input version=1.2.3 --input environment=staging
Conclusion
Act dramatically speeds up GitHub Actions development by letting you test workflow changes locally before pushing. With support for secrets, artifacts, and custom runner images, it handles most real-world CI scenarios. For complex workflows involving GitHub-specific APIs, combine Act testing with selective pushes to validate the final pieces.


