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 LabelMicro ImageMedium ImageFull Image
ubuntu-latestnode:16-buster-slimcatthehacker/ubuntu:act-20.04catthehacker/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.