# act — User Guide

## 1. Quick Start

**act** runs your GitHub Actions workflows locally using Docker containers. Instead of pushing commits to trigger CI, you test workflows on your machine in seconds.

**Key features:**

- Run any GitHub Actions workflow locally without pushing to GitHub
- Support for `push`, `pull_request`, `workflow_dispatch`, and all standard events
- Matrix strategy execution with configurable parallelism
- Secrets, environment variables, and inputs passed via CLI or files
- Built-in artifact server and cache server for action compatibility
- Watch mode for automatic re-runs on file changes
- Offline mode for air-gapped environments
- Dry-run mode for workflow validation without containers

**Prerequisites:** Docker Engine installed and running, Git

**Install and run:**

```bash
brew install act
```

```bash
cd your-repo
act
```

```text
[push/build] 🚀  Start image=node:16-buster-slim
[push/build]   🐳  docker pull node:16-buster-slim
[push/build] ⭐  Run Main actions/checkout@v4
[push/build]   ✅  Success - Main actions/checkout@v4
[push/build] ⭐  Run Main Run tests
[push/build]   ✅  Success - Main Run tests
```

> [!TIP]
> On first run, act prompts you to select a default Docker image size (Large/Medium/Micro). Choose **Medium** for the best balance of compatibility and download size.

**What to try next:** Run a specific job with `act -j build`, list all available jobs with `act -l`, or pass secrets with `act -s MY_SECRET=value`.

## 2. Installation

### System Requirements

| Requirement | Minimum |
|---|---|
| Docker Engine | API v1.25+ (v1.41+ for `--container-architecture`) |
| Git | Any recent version |
| Disk space | 200MB–75GB depending on runner image choice |

### Installation Methods

=== "Homebrew (macOS/Linux)"
    ```bash
    brew install act
    ```

=== "Chocolatey (Windows)"
    ```bash
    choco install act-cli
    ```

=== "Scoop (Windows)"
    ```bash
    scoop install act
    ```

=== "AUR (Arch Linux)"
    ```bash
    yay -S act
    ```

=== "Shell script (Linux/macOS)"
    ```bash
    curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
    ```

=== "Go install"
    ```bash
    go install github.com/nektos/act@latest
    ```

=== "GitHub Releases"
    ```bash
    # Download the appropriate binary from
    # https://github.com/nektos/act/releases
    ```

### Post-install Verification

```bash
act --version
```

```text
act version 0.2.x
```

> [!IMPORTANT]
> Docker must be running before using act. Verify with `docker info`. If you see connection errors, start the Docker daemon first.

### Runner Image Selection

On first run (or if no `.actrc` exists), act prompts you to choose a default runner image:

| Size | Image | Disk | Compatibility |
|---|---|---|---|
| **Large** | `catthehacker/ubuntu:full-latest` | ~75GB | Closest to GitHub-hosted runners |
| **Medium** | `catthehacker/ubuntu:act-latest` | ~500MB | Compatible with most actions |
| **Micro** | `node:16-buster-slim` | <200MB | Node.js actions only |

Your choice is saved to `~/.config/act/actrc` (XDG) or `~/.actrc`.

### Install Troubleshooting

### Error: Cannot connect to the Docker daemon

**Cause:** Docker is not running or the socket path is wrong.

**Solution:**
1. Start Docker: `sudo systemctl start docker` (Linux) or open Docker Desktop
2. Verify: `docker info`
3. If using a custom socket, set `DOCKER_HOST` or use `--container-daemon-socket`

### Error: permission denied while trying to connect to the Docker daemon socket

**Cause:** Current user is not in the `docker` group.

**Solution:**
```bash
sudo usermod -aG docker $USER
newgrp docker
```

### Error: image platform mismatch on Apple M-series

**Cause:** Default images are amd64, but your hardware is arm64.

**Solution:**
```bash
act --container-architecture linux/amd64
```

> [!WARNING]
> On Apple Silicon Macs, running amd64 containers incurs emulation overhead. Some actions may behave differently or run slower than on native amd64 hardware.

## 3. Configuration

### Configuration File (`.actrc`)

act reads configuration from these locations (in order, all are merged):

1. `~/.config/act/actrc` (XDG spec / macOS Library / Windows AppData)
2. `~/.actrc` (home directory)
3. `./.actrc` (project directory)

Each line contains a CLI flag:

```text
-P ubuntu-latest=catthehacker/ubuntu:act-latest
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
-P ubuntu-20.04=catthehacker/ubuntu:act-20.04
--container-architecture linux/amd64
--action-offline-mode
```

> [!NOTE]
> Lines support environment variable expansion (e.g., `--artifact-server-path ${PWD}/.artifacts`). Flags on a single line with a space are split at the first whitespace.

### Secrets, Variables, and Environment

| Source | Flag | File default | Format |
|---|---|---|---|
| Secrets | `-s KEY=VALUE` | `--secret-file .secrets` | `KEY=VALUE` or YAML |
| Variables | `--var KEY=VALUE` | `--var-file .vars` | `KEY=VALUE` or YAML |
| Environment | `--env KEY=VALUE` | `--env-file .env` | `KEY=VALUE` (dotenv) |
| Inputs | `--input KEY=VALUE` | `--input-file .input` | `KEY=VALUE` |

Secrets files support both dotenv format and YAML:

```yaml
# .secrets (YAML format)
MYSECRET: |
  multi-line
  secret value
GITHUB_TOKEN: ghp_xxxxxxxxxxxx
```

> [!TIP]
> If no `GITHUB_TOKEN` secret is provided, act automatically attempts to retrieve one from the `gh` CLI (GitHub CLI) if installed.

### Platform Mapping

Map GitHub runner labels to Docker images:

```bash
act -P ubuntu-latest=catthehacker/ubuntu:act-latest
act -P self-hosted=my-custom-image:latest
```

Default platform mappings (built-in):

| Label | Default Image |
|---|---|
| `ubuntu-latest` | `node:16-buster-slim` |
| `ubuntu-22.04` | `node:16-bullseye-slim` |
| `ubuntu-20.04` | `node:16-buster-slim` |
| `ubuntu-18.04` | `node:16-buster-slim` |

See the Admin Guide for the full configuration reference.

## 4. Core Usage

### Running Workflows

**Run the default event (push):**

```bash
act
```

**Run a specific event:**

```bash
act pull_request
```

**Run a specific job:**

```bash
act -j test
```

**Run with workflow_dispatch inputs:**

```bash
act workflow_dispatch --input name=value
```

Or provide an event payload:

```bash
act workflow_dispatch -e event.json
```

### Listing and Visualizing Workflows

**List all jobs:**

```bash
act -l
```

```text
Stage  Job ID   Job name   Workflow name  Workflow file  Events
0      build    Build      CI             ci.yml         push
0      test     Test       CI             ci.yml         push
1      deploy   Deploy     CI             ci.yml         push
```

**Draw workflow graph:**

```bash
act -g
```

```text
┌───────┐ ┌──────┐
│ build │ │ test │
└───────┘ └──────┘
         ↓
    ┌────────┐
    │ deploy │
    └────────┘
```

### Validating Workflows

```bash
act --validate
```

```bash
act --validate --strict
```

> [!NOTE]
> `--validate` parses workflows against the GitHub Actions schema without running them. Add `--strict` for stricter validation rules. Schema errors link to `https://nektosact.com/usage/schema.html` for details.

### Passing Secrets and Environment

```bash
# Inline secret
act -s GITHUB_TOKEN=ghp_xxxxx

# Secret from environment variable (prompts if not set)
act -s MY_SECRET

# File-based secrets
act --secret-file my-project.secrets

# Environment variables
act --env CI=true --env NODE_ENV=test
```

Secrets are case-insensitive — `my_secret` and `MY_SECRET` are the same key. If you pass a secret name without a value and the environment variable is not set, act prompts for interactive input.

### Matrix Filtering

Run only specific matrix combinations:

```bash
act --matrix os:ubuntu-latest
act --matrix node:18 --matrix os:ubuntu-latest
```

> [!WARNING]
> Matrix keys are separated by `:` (not `=`). For example: `--matrix java:13`, not `--matrix java=13`.

### Watch Mode

Automatically re-run workflows when files change:

```bash
act -w
```

act watches the working directory (respecting `.gitignore`) and re-executes on any file change, checking every 2 seconds.

### Dry Run

Validate workflows without creating containers:

```bash
act -n
```

```text
*DRYRUN* [push/build] 🚀  Start image=node:16-buster-slim
*DRYRUN* [push/build] ⭐  Run Main actions/checkout@v4
*DRYRUN* [push/build]   ✅  Success - Main actions/checkout@v4
```

## 5. Common Tasks

### Use a Custom Docker Image for a Runner Label

**Goal:** Map `self-hosted` or a custom label to your own image.

**Steps:**

```bash
act -P self-hosted=ghcr.io/myorg/my-runner:latest
```

Or persist in `.actrc`:

```text
-P self-hosted=ghcr.io/myorg/my-runner:latest
```

**Verify:** `act -l` shows your jobs; `act` pulls and uses the mapped image.

### Run with GitHub Enterprise Server Actions

**Goal:** Use actions from a GHE instance while redirecting some to github.com.

```bash
act --github-instance github.example.com \
    --replace-ghe-action-with-github-com github/super-linter \
    --replace-ghe-action-token-with-github-com ghp_xxxxx
```

**Verify:** Actions from `github.com` are fetched with the provided token.

### Use the Artifact Server

**Goal:** Test actions that upload/download artifacts.

```bash
act --artifact-server-path /tmp/act-artifacts
```

The artifact server starts automatically on the address/port specified by `--artifact-server-addr` (default: outbound IP) and `--artifact-server-port` (default: `34567`).

> [!TIP]
> The artifact server supports both v1 (`actions/upload-artifact@v3`) and v4 (`actions/upload-artifact@v4`) protocols. Artifacts are stored as files in the specified directory.

### Bind the Working Directory (Skip Copy)

**Goal:** Avoid the overhead of copying your repo into the container.

```bash
act -b
```

> [!WARNING]
> Bind-mounting means workflows can modify your local files directly. Use with caution on workflows that do cleanup steps or delete files.

### Reuse Containers Between Runs

**Goal:** Maintain state (installed packages, caches) between repeated runs.

```bash
act -r
```

Containers are not removed after successful runs. Combine with `--rm` to auto-remove on failure instead.

### Use Local Actions Without Fetching

**Goal:** Test local action changes without pushing to a remote.

```bash
act --local-repository test/my-action@v1=/path/to/local/action
```

The `--local-repository` flag maps a remote action reference to a local directory. Multiple mappings can be provided. This requires `--use-new-action-cache`.

### Run Workflows in Offline Mode

**Goal:** Run workflows without network access (actions must already be cached).

```bash
act --action-offline-mode
```

When offline mode is enabled, `--pull` is automatically forced to `false`. Action content must already exist in the action cache directory.

### Control Concurrency

**Goal:** Limit parallel job execution.

```bash
act --concurrent-jobs 2
```

Default: number of CPUs available on the machine.

### Use a Custom Docker Network

**Goal:** Connect workflow containers to existing services.

```bash
act --network my-network
```

> [!NOTE]
> The default network mode is `host`. When using a custom network, the artifact and cache servers may need explicit `--artifact-server-addr` and `--cache-server-addr` flags so containers can reach them.

### Skip Container Image Pulling

**Goal:** Speed up iteration when images are already present.

```bash
act --pull=false
```

### Change the Workflow File Location

**Goal:** Run workflows from a non-standard directory.

```bash
act -W ./ci/workflows/
```

Use `--no-recurse` to disable searching subdirectories for workflow files.

### Generate a Bug Report

**Goal:** Collect system information for filing issues.

```bash
act --bug-report
```

```text
act version:            0.2.x
GOOS:                   linux
GOARCH:                 amd64
Docker host:            unix:///var/run/docker.sock
Docker Engine:
  Engine version:       24.0.7
  ...
```

## 6. Troubleshooting

### Diagnostic Decision Tree

```text
Act fails to start?
├── Docker not running → start Docker daemon
├── Socket not found → set DOCKER_HOST or --container-daemon-socket
├── Permission denied → add user to docker group
└── Image pull fails → check network / use --action-offline-mode

Workflow runs but actions fail?
├── MODULE_NOT_FOUND → node_modules not bundled, check action packaging
├── 127 exit code → command not found in container image
├── Secrets empty → check -s / --secret-file
└── Platform mismatch → add --container-architecture linux/amd64
```

### Error: `Could not find any stages to run`

**Cause:** No workflows match the specified event or job ID.

**Solution:**
1. List available jobs: `act -l`
2. Verify the event name matches a workflow trigger
3. Check the `-W` path points to your workflow files

**Prevention:** Always verify with `act -l` before running specific events.

### Error: `exitcode '127': command not found`

**Cause:** The container image doesn't have the required binary installed.

**Solution:**
1. Switch to a larger runner image: `-P ubuntu-latest=catthehacker/ubuntu:act-latest`
2. Or use the full image: `-P ubuntu-latest=catthehacker/ubuntu:full-latest`

**Prevention:** Use the Medium or Large image for workflows that need system tools beyond Node.js.

### Error: `Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable`

**Cause:** OIDC token requests are not supported locally by act. (GitHub issue [#2500](https://github.com/nektos/act/issues/2500))

**Solution:** Skip the step when running locally:

```yaml
- if: ${{ !env.ACT }}
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: ...
```

### Error: `Cannot find module MODULE_NOT_FOUND`

**Cause:** A JavaScript action's `node_modules` are not bundled. (GitHub issue [#6034](https://github.com/nektos/act/issues/6034))

**Solution:**
1. The action may need `npm install && npm run build` before use
2. Use `--use-new-action-cache` for better caching of action dependencies

### Error: `failed to connect to docker daemon`

**Cause:** The Docker socket path is invalid or Docker is using a non-default location.

**Solution:**
```bash
# Find the socket
ls /var/run/docker.sock ~/.docker/run/docker.sock

# Or specify explicitly
act --container-daemon-socket unix:///path/to/docker.sock
```

### Error: `DOCKER_HOST was not set, couldn't be found in the usual locations`

**Cause:** No Docker socket was found at any of the common locations and `DOCKER_HOST` is not set.

**Solution:**
1. Verify Docker is installed and running
2. Set `DOCKER_HOST` to your Docker socket: `export DOCKER_HOST=unix:///var/run/docker.sock`
3. Or pass `--container-daemon-socket` on the command line

### Error: `act sends GHE token from gh to github.com causing 401`

**Cause:** The `gh` CLI returns a GitHub Enterprise token, but act uses it against `github.com`. (GitHub issue [#6077](https://github.com/nektos/act/issues/6077))

**Solution:** Pass the token explicitly:
```bash
act -s GITHUB_TOKEN=ghp_your_github_com_token
```

### Actions that use `amazon-ecr-login` fail

**Cause:** ECR login actions depend on AWS OIDC or credentials that behave differently locally. (GitHub issue [#6063](https://github.com/nektos/act/issues/6063))

**Solution:** Pre-authenticate with ECR outside act and mount the credentials, or skip the login step in local runs.

### Error: `The runs.using key must be one of: [node12 node16 node20 docker composite]`

**Cause:** The action uses an unsupported `runs.using` value.

**Solution:** Check the action version — you may need a newer version of act that supports the required runtime.

> [!CAUTION]
> Using `--insecure-secrets` prints secrets to the terminal in plain text. Never use this in shared or recorded terminal sessions.

### `self-hosted` runner tries to use `/Users/runner` on macOS

**Cause:** act creates runner directories based on expected GitHub runner paths. (GitHub issue [#5974](https://github.com/nektos/act/issues/5974))

**Solution:** Use `--action-cache-path` to redirect:
```bash
act --action-cache-path ~/.cache/act
```

> [!WARNING]
> When using `--rm` (auto-remove), containers are removed even on failure. This can make debugging harder — consider omitting `--rm` during development.

## 7. FAQ

**Q: What is the `ACT` environment variable?**

act sets `ACT=true` inside workflow containers. Use `if: ${{ !env.ACT }}` in your workflow steps to skip steps that don't work locally (like deployments or OIDC authentication).

**Q: How do I disable the version check on startup?**

Set the environment variable `ACT_DISABLE_VERSION_CHECK=1`.

**Q: Where does act cache actions?**

By default in `~/.cache/act/`. Override with `--action-cache-path`. The cache server stores data in `~/.cache/actcache/` by default (override with `--cache-server-path`).

**Q: Can I run multiple act instances concurrently?**

There is no built-in lock mechanism for concurrent act invocations against the same Docker daemon. (GitHub issue [#6061](https://github.com/nektos/act/issues/6061))

**Q: Does act support reusable workflows (`workflow_call`)?**

Yes. act supports reusable workflows with the format `{owner}/{repo}/.github/workflows/{filename}@{ref}`. Local reusable workflows with relative paths (`./.github/workflows/`) are a requested feature. (GitHub issue [#5992](https://github.com/nektos/act/issues/5992))

**Q: Does act support service containers?**

Yes. Service containers defined in workflow YAML (`services:`) are created alongside the job container, including health checks and port mapping.

**Q: How do I pass GPU access to containers?**

GPU passthrough is not currently supported. (GitHub issue [#1091](https://github.com/nektos/act/issues/1091))

**Q: Can I skip image pulling for faster iteration?**

Use `--pull=false` to skip pulling images that already exist locally, or `--action-offline-mode` to also skip fetching action repositories.

**Q: How does act handle the `runs-on` label?**

act maps `runs-on` labels to Docker images via the platform mapping (`-P`). If no mapping exists for a label, the default built-in mapping is used (e.g., `ubuntu-latest` → `node:16-buster-slim`).

**Q: What shells are supported?**

act supports `bash`, `sh`, `python`, `pwsh` (PowerShell Core), `cmd` (Windows), and custom shells, matching the GitHub Actions shell options.

**Q: Does act use `actions/checkout` automatically?**

By default, act copies local files into the container instead of running `actions/checkout`. Use `--no-skip-checkout` to force `actions/checkout` to run instead.

**Q: Can I use `.gitignore` to control what gets copied into the container?**

Yes, this is enabled by default (`--use-gitignore=true`). Files matched by `.gitignore` are excluded from the container copy. Disable with `--use-gitignore=false`.

**Q: How do I specify a working directory for a different repo?**

Use `act -C /path/to/repo` to set the working directory.

---

_Generated May 2026 from nektos/act at bd86152. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
