GitHub Actions have revolutionized the way developers automate workflows within their repositories. From continuous integration and continuous deployment (CI/CD) pipelines to automating issue labeling and release notes generation, Actions provide a powerful, integrated way to manage the software development lifecycle directly within GitHub.
However, developing and testing these workflows can sometimes feel cumbersome. The traditional cycle involves:
- Making changes to your workflow files (typically located in
.github/workflows/
). - Committing these changes.
- Pushing them to your GitHub repository.
- Waiting for GitHub's runners to pick up the job and execute it.
- Analyzing the logs on the GitHub website to see if your changes worked or if they introduced errors.
This process, especially the waiting part and the context switch between your local editor and the GitHub UI, can significantly slow down development, particularly when iterating on complex workflows or debugging tricky issues. What if you could test your Actions before pushing them?

This is precisely where act
comes in. As its tagline suggests, "Think globally, act
locally". act
is an open-source command-line tool designed to run your GitHub Actions workflows locally using Docker containers. It simulates the environment provided by GitHub Actions, allowing you to test and iterate on your workflows rapidly without the need to commit and push every minor change.
Want an integrated, All-in-One platform for your Developer Team to work together with maximum productivity?
Apidog delivers all your demans, and replaces Postman at a much more affordable price!

Why Run GitHub Actions Locally with act
?
The benefits of incorporating act
into your development workflow are substantial:
- Fast Feedback: This is the primary advantage. Instead of the commit-push-wait-debug cycle, you can run your workflow immediately after making a change locally. Get feedback in seconds or minutes, not minutes or tens of minutes. This drastically speeds up the development and debugging process for your
.github/workflows/
files. - Local Task Runner: Many projects use tools like
make
,npm scripts
, or custom shell scripts to define common development tasks (building, testing, linting, etc.).act
allows you to consolidate these tasks. You can define your build, test, and other processes as GitHub Actions jobs, and then useact
to run these same jobs locally for development purposes. This reduces duplication and ensures consistency between your local development environment and your CI/CD pipeline You define the tasks once in your workflow files, and they run identically (or very similarly) everywhere. - Offline Development: Test basic workflow syntax and logic even without a constant internet connection (though initial image downloads and certain actions might require connectivity).
- Cost Savings: While GitHub provides a generous free tier for public repositories and reasonable pricing for private ones, running complex or long workflows repeatedly during development can consume runner minutes. Testing locally avoids this usage.
- Debugging Power: Debugging failed Actions on GitHub often involves adding extra logging, pushing, and waiting. With
act
, you can inspect the local environment, mount volumes, and potentially use more advanced debugging techniques within the Docker containers it spins up.
How Does act
Work?
Understanding the mechanism behind act
helps in using it effectively and troubleshooting potential issues. Here’s a breakdown of its operation:
- Workflow Parsing: When you execute the
act
command in your repository's root directory, it scans the.github/workflows/
directory for your workflow YAML files. - Event Trigger Simulation: By default,
act
simulates apush
event, but you can specify other events likepull_request
,workflow_dispatch
, etc. It determines which workflows and jobs should run based on the event specified and theon:
triggers defined in your workflow files. - Dependency Analysis:
act
analyzes the dependencies between jobs within a workflow (using theneeds:
keyword) to determine the correct execution order. - Docker Image Management: For each job,
act
identifies the runner environment specified (e.g.,runs-on: ubuntu-latest
). It then maps this to a specific Docker image.act
uses the Docker API to:
- Pull Images: Download the required runner images and any Docker images used by container actions (
uses: docker://...
). By default, it pulls images on each run unless configured otherwise. - Build Images (If Necessary): If an action points to a local Dockerfile (
uses: ./path/to/action
),act
can build the Docker image locally.
- Container Execution:
act
uses the Docker API to create and run containers for each step within a job. It configures these containers to mimic the GitHub Actions environment as closely as possible:
- Environment Variables: Standard GitHub Actions environment variables (like
GITHUB_SHA
,GITHUB_REF
,GITHUB_REPOSITORY
,CI
, etc.) are injected. - Filesystem: The repository code is mounted into the container's workspace directory (
/github/workspace
). Files generated by steps are persisted within the container for subsequent steps. - Networking: Containers are typically run on a Docker bridge network, allowing communication if needed (though networking specifics might differ from GitHub's environment).
- Log Streaming:
act
streams the logs from the running containers directly to your terminal, providing real-time feedback on the execution progress and any errors.
Essentially, act
orchestrates local Docker containers to replicate the execution flow and environment of your GitHub Actions workflows.
Prerequisites: Docker Installation
The core dependency for act
is Docker. act
leverages the Docker engine to create the isolated environments needed to run your workflow steps. Before installing act
, you must have a working Docker installation on your system.
- Install Docker: Follow the official instructions for your operating system:
- macOS: Docker Desktop for Mac
- Windows: Docker Desktop for Windows (Requires WSL 2 or Hyper-V)
- Linux: Follow the specific instructions for your distribution (e.g., Ubuntu, Fedora, Debian, etc.). Ensure you add your user to the
docker
group to run Docker commands withoutsudo
. - Verify Docker: After installation, open your terminal and run
docker run hello-world
. This command downloads a small test image and runs it in a container. If it runs successfully, your Docker setup is ready.
Installing act
Once Docker is running, you can install act
. There are several ways to do this, depending on your operating system and preferences.
1. Homebrew (macOS and Linux)
If you use the Homebrew package manager, installation is straightforward:
brew install act
This installs the latest stable release. If you want the absolute latest development version (which might require a compiler), you can use:
brew install act --HEAD
2. GitHub CLI Extension (macOS, Windows, Linux)
If you already use the GitHub CLI (gh
), you can install act
as an extension:
gh extension install nektos/gh-act
After installation, you invoke act
via the gh
command:
gh act # Instead of just 'act'
gh act -l
gh act pull_request
3. Chocolatey (Windows)
For users of the Chocolatey package manager on Windows:
choco install act-cli
(Note: Some sources might list act
instead of act-cli
. Check the latest package name on the Chocolatey community repository if you encounter issues.)
4. Scoop (Windows)
For users of the Scoop package manager on Windows:
scoop install act
5. WinGet (Windows)
For users of the Windows Package Manager (winget
):
winget install nektos.act
6. Linux Script Installer
A convenience script is available for Linux distributions without easy access via package managers:
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
(Note: Always exercise caution when piping scripts directly into sudo
. Review the script content first if you have security concerns.)
7. Other Methods (Arch, COPR, MacPorts, Nix)
Installation instructions for other package managers like pacman
(Arch), COPR (Fedora), MacPorts, and Nix are available in the official act
documentation:
Verification:
After installation, open a new terminal window and run:
act --version
# or if using the gh extension:
gh act --version
This should print the installed version of act
, confirming the installation was successful.
Initial Configuration: Runner Images
The first time you run act
within a project directory, it might prompt you to choose a default runner image size. GitHub Actions offers runners with varying resources and pre-installed software. act
tries to mimic this by using different base Docker images.
You'll typically be presented with a choice like this:
? Please choose the default image you want to use with act:
- Micro: Minimal image with nodejs support (~200MB) docker.io/node:16-buster-slim
- Medium: Act image with basic tools (~500MB) ghcr.io/catthehacker/ubuntu:act-latest
- Large: Github Actions runner image (~17GB) ghcr.io/catthehacker/ubuntu:full-latest
Default image? [Medium]:
- Micro: Based on official Node.js slim images (like
node:16-buster-slim
ornode:16-bullseye-slim
). Very small and fast to download, but contains only Node.js and minimal system libraries. Suitable if your actions only need Node.js or install all their dependencies themselves. - Medium: Provided by the user
catthehacker
(e.g.,catthehacker/ubuntu:act-latest
,catthehacker/ubuntu:act-22.04
). These images include more common tools found on GitHub runners but are still relatively lightweight (around 500MB). This is often the recommended default as it balances features and size. - Large: Also from
catthehacker
(e.g.,catthehacker/ubuntu:full-latest
,catthehacker/ubuntu:full-22.04
). These are created from filesystem dumps of the actual GitHub-hosted runners and contain nearly all the pre-installed software. They offer the highest compatibility but are very large (often >17GB), leading to long initial download times and significant disk space usage.
Recommendation: Start with the Medium image. It provides a good balance and works for many common use cases. If you encounter issues due to missing software, you can either install the software within your workflow steps or switch to using the Large image for that specific runner (more on this later).
act
saves your choice in a configuration file (~/.actrc
). You can change the default later by editing this file or re-running act
in a directory where it needs to configure.
Core act
Usage: Running Your Workflows
Once installed and configured, using act
is relatively simple. Navigate to the root directory of your project (the one containing the .github
folder) in your terminal.
1. Run Default Event (push
)
The simplest command runs the workflows triggered by the default push
event:
act
# or
gh act
act
will parse your workflows, identify jobs triggered on: push
, pull the necessary Docker images (if not already cached), and execute the jobs.
2. List Available Workflows and Jobs
To see which workflows and jobs act
recognizes and would run for the default event:
act -l
# or
gh act -l
This outputs a list like:
Stage Job ID Job name Workflow name Workflow file Events
0 build Build CI Pipeline ci.yaml push
1 test Test CI Pipeline ci.yaml push
1 lint Lint Code Quality codeql.yaml push,pull_request
3. Run a Specific Job
If you only want to test a single job from a workflow, use the -j
flag followed by the job ID (from the act -l
output):
act -j build
# or
gh act -j build
4. Trigger a Specific Event
Workflows often trigger on events other than push
. You can simulate these events by providing the event name as an argument to act
:
# Simulate a pull request event
act pull_request
# Simulate a workflow_dispatch event (manual trigger)
act workflow_dispatch
# Simulate a schedule event
act schedule
# Simulate a release event
act release -e event.json # Provide event payload details if needed
act
will only execute workflows and jobs configured to run on:
the specified event.
5. Passing Inputs for workflow_dispatch
Workflows triggered by workflow_dispatch
can accept inputs. You can provide these using the --input
flag or -i
:
# Assuming your workflow has an input named 'environment'
act workflow_dispatch --input environment=staging
6. Handling Secrets
GitHub Actions workflows often rely on secrets (like API keys or tokens). act
does not automatically access your GitHub secrets. You need to provide them locally.
- Interactive Prompt: Use the
-s
flag.act
will prompt you to enter the value for each secret defined in your workflow:
act -s MY_SECRET_TOKEN -s ANOTHER_SECRET
Alternatively, just act -s
will prompt for all secrets.
- Environment Variables: Secrets are often passed as environment variables prefixed with
SECRET_
. You can define them in your shell before runningact
:
export SECRET_MY_SECRET_TOKEN="your_value"
act
- Secrets File: Create a file (e.g.,
.secrets
) withKEY=VALUE
pairs:
MY_SECRET_TOKEN=your_value
ANOTHER_SECRET=another_value
Then run act
with the --secret-file
flag:
act --secret-file .secrets
(Ensure this file is added to your .gitignore
to avoid committing secrets!)
7. Handling Variables and Environment Variables
- Workflow Variables: You can provide values for variables defined at the workflow level (
vars:
context, although fullvars
context support inact
might be limited) using the--var
flag or a--var-file
, similar to secrets. - Environment Variables: To set custom environment variables for the workflow run, use the
--env
flag or an--env-file
.
act --env NODE_ENV=development --env CUSTOM_FLAG=true
act --env-file .env_vars
Managing Runner Environments and Images
While the default runner images (Micro, Medium, Large) cover many scenarios, you often need more control.
1. Limitations of Default Images
Remember that the default act
runner images (especially Micro and Medium) are not identical to the environments provided by GitHub. They might lack specific tools, libraries, or system services (like systemd
) that your workflow expects. The Large images offer higher fidelity but come with the significant size drawback.
2. Specifying Alternative Images with -P
If a job requires a specific environment or toolset not present in the default image, you can tell act
to use a different Docker image for a specific platform using the -P
(platform) flag.
The format is -P <platform>=<docker-image>
.
<platform>
: The label used in your workflow'sruns-on:
directive (e.g.,ubuntu-latest
,ubuntu-22.04
,ubuntu-20.04
).<docker-image>
: The full name of the Docker image to use (e.g.,node:18
,python:3.10-slim
,mcr.microsoft.com/devcontainers/base:ubuntu
).
Examples:
# Use the Large image specifically for jobs running on ubuntu-22.04
act -P ubuntu-22.04=ghcr.io/catthehacker/ubuntu:full-22.04
# Use a specific Node.js version for ubuntu-latest jobs
act -P ubuntu-latest=node:18-bullseye
# Use a more complete image from nektos/act-environments (very large!)
# WARNING: nektos/act-environments-ubuntu:18.04 is >18GB
act -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04
# Specify multiple platforms if your workflow uses them
act -P ubuntu-20.04=node:16-buster -P ubuntu-22.04=node:18-bullseye
3. Using Local Runner Images (--pull=false
)
By default, act
tries to pull the latest version of the specified Docker image every time it runs. If you have built a custom runner image locally or want to ensure you're using the exact version you have cached, you can disable this behavior:
act --pull=false
# or potentially use offline mode
act --action-offline-mode
This tells act
to use the locally available image if present and only attempt to pull if it's missing.
4. Running Natively on Host (-self-hosted
)
For workflows targeting macOS or Windows (runs-on: macos-latest
or runs-on: windows-latest
), if you are running act
on that same host operating system, you can instruct act
not to use a Docker container for the runner itself. Instead, it will execute the steps directly on your host machine. This can be useful if Docker compatibility is an issue or if you need direct access to host resources.
# Run macos-latest jobs directly on your Mac host
act -P macos-latest=-self-hosted
# Run windows-latest jobs directly on your Windows host
act -P windows-latest=-self-hosted
Caution: Running directly on the host bypasses the isolation provided by Docker. Workflow steps will have access to your file system and potentially modify your host environment. Use this option with care. Steps within the job that explicitly use Docker containers (like service containers or container actions) will still use Docker.
Limitations and Considerations
While act
is incredibly useful, it's important to be aware of its limitations:
- Not a Perfect Replica:
act
simulates the GitHub Actions environment but isn't identical. Differences exist in networking, available system services (e.g., nosystemd
in Docker containers easily), specific hardware resources, and the exact set of pre-installed tools (unless using the very large runner images). Some workflows, especially complex ones interacting heavily with the underlying OS or specific GitHub features, might behave differently inact
versus on GitHub. - Context Differences: Some parts of the
github
context might be incomplete or contain default/mock values when run locally. Thesecrets
context always needs explicit input. Thevars
context support might also have limitations compared to the live GitHub environment. - Concurrency:
act
typically runs jobs sequentially based on theirneeds
dependencies. It doesn't fully replicate GitHub's ability to run independent jobs concurrently using matrix strategies across multiple runners (thoughact
does support running matrix jobs, they usually run sequentially locally). - Hosted Services: Features like caching (
actions/cache
) might work differently or require specific configuration locally compared to GitHub's integrated caching service. Service containers defined in workflows should work, asact
uses Docker for those too. - Platform Availability: You can only run Linux-based jobs within Docker on any Docker-supported host (Mac, Windows, Linux). To run
macos-latest
jobs, you ideally needact
on macOS (or use the-self-hosted
flag on macOS). Similarly,windows-latest
jobs typically requireact
on Windows (or-self-hosted
on Windows). While Docker can run Windows containers on Windows,act
's primary focus and most stable support revolve around Linux containers.
Recommendation: Use act
for rapid development, syntax checking, basic logic testing, and iterating on individual jobs or steps. Always perform final validation by running your workflows on GitHub itself before merging critical changes, especially for deployment pipelines. Consult the official act
documentation for the detailed support matrix and known issues.
Conclusion
Testing GitHub Actions locally is a significant productivity booster, transforming the potentially slow and tedious debug cycle into a fast, iterative process. The act
CLI tool provides a robust and flexible way to achieve this by leveraging Docker to simulate the GitHub Actions runner environment on your local machine.
By integrating act
into your workflow, you gain:
- Faster feedback loops.
- Reduced reliance on pushing to GitHub for testing.
- The ability to use your Actions definitions as a local task runner.
- Improved debugging capabilities.
While it has limitations and isn't a perfect 1:1 replacement for the live GitHub environment, act
covers a vast range of use cases and significantly lowers the friction involved in developing reliable and effective GitHub Actions workflows. Install it, try running your existing workflows locally, and experience the benefits of thinking globally while acting locally.
Want an integrated, All-in-One platform for your Developer Team to work together with maximum productivity?
Apidog delivers all your demans, and replaces Postman at a much more affordable price!
