Module 1: Why Cicd And Gitops

6. Hands-on: installing `act`

Description

This is the guide's first lesson where you're going to run real commands. You're going to install act on your machine, confirm the installation with act --version, verify that Docker is running (the dependency without which act can't do anything), and pin the runner image in an .actrc file — so every run in this guide uses exactly the same image, with no surprises. Every What to expect block in this lesson explicitly states whether the output is literal (executed to write this lesson, today) or representative — you're never going to find a made-up number without that label.

Connection to the module

Lessons 1 through 5 gave you the entire why: the problem with manual apply, the CI/CD vocabulary, GitOps, and why this guide chooses GitHub Actions. This lesson, and the one that follows, give you the how. You finish this lesson with act working on your machine, connected to Docker — lesson 7 uses it, for the first time, on a real workflow.


Analogy: a flight simulator for the pipeline

Before installing anything, it's worth understanding exactly what act is, with a concrete image. A flight simulator isn't "almost a plane" — it's the same control software, the same modeled physical responses, the same maneuvers a pilot would execute in real flight, run in a room with no windows, without ever boarding a real plane. act is that for a GitHub Actions workflow: it runs the same YAML, with the same real Marketplace Actions, inside Docker containers designed to imitate a real GitHub runner as faithfully as possible — without that YAML ever touching a GitHub server. When you finish practicing in the simulator, the flight manual doesn't change a single page for the real plane.


Step 1 — Install act

This guide uses act 0.2.89, published on June 1, 2026 — the stable version available while writing this guide. Choose the method that matches your situation.

macOS/Linux, via Homebrew (this guide's method)

act is available directly in Homebrew's main repository (homebrew-core), with no separate tap needed:

brew install act

What to expect (literal output, executed to write this lesson):

==> Fetching downloads for: act
✔︎ Bottle act (0.2.89)
==> Would install 1 formula:
act
🍺  /opt/homebrew/Cellar/act/0.2.89: 10 files, 29.6MB
==> Running `brew cleanup act`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Caveats
zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions

act is a single binary, with no additional dependencies to install besides Docker (which you verify in Step 2) — unlike Terraform, it needs no provider registry or additional configuration to work.

Alternative: the official GitHub CLI extension

If you already have gh (GitHub CLI) installed, there's an official extension maintained by act's own author that installs it as a gh subcommand:

gh extension install https://github.com/nektos/gh-act

This guide doesn't execute this path —brew install act already covers the installation— but it's a real, documented alternative if your workflow already lives inside gh. The end result is the same act binary, invoked as gh act instead of plain act.


Step 2 — Confirm the installation and verify Docker

act --version

What to expect (literal output, executed right now to write this lesson):

act version 0.2.89

If your terminal responds with command not found: act, the binary didn't end up on your PATH — check "Common mistakes" at the end of this lesson.

act doesn't do anything on its own: each job it runs is, internally, a Docker container. Before continuing, confirm Docker is running (not just installed):

docker ps

What to expect (an empty table, with only the headers, is the correct response if you don't have any containers running yet):

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

If this command fails with a connection error to the Docker daemon, open Docker Desktop (or start the Docker service) before continuing — without Docker running, no act command in this guide is going to work, no exceptions.


Step 3 — Choose and pin the runner image

This is the step that makes the difference between a reproducible run and one that depends on whatever image act resolves on the day you run it. The first time you execute any act command without having told it which image to use explicitly, it asks you which one to use:

What to expect (literal output, captured on the first real act run on this machine, before creating .actrc):

? Please choose the default image you want to use with act:
  - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images
  - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions
  - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions

Three sizes, three different trade-offs between fidelity and download weight:

  • Large (~17GB download, ~53GB on disk): an almost-complete replica of what a real GitHub-hosted runner ships with — most of the preinstalled tools you'd find on a real ubuntu-latest. Heavy, but the most faithful.
  • Medium (~500MB): just what's needed to bootstrap Actions, compatible with most real cases — the one this guide uses.
  • Micro (<200MB): only Node.js, the bare minimum for JavaScript-based Actions to start — doesn't work with Actions that assume other preinstalled tools (like hashicorp/setup-terraform, which you're going to use starting in Module 3).

This guide chooses Medium: complete enough for everything you're going to build (including explicitly installing Terraform with hashicorp/setup-terraform@v3 on every run, instead of assuming it's preinstalled), without the download cost of the Large image.

Instead of answering that interactive prompt every time —which would also break this guide's reproducibility if act changed its default behavior in the future— pin the choice explicitly in an .actrc file, at the root of your project:

-P ubuntu-latest=catthehacker/ubuntu:act-latest

This single line tells act, unambiguously, which Docker image to use every time a workflow declares runs-on: ubuntu-latest — the tag catthehacker/ubuntu:act-latest is, specifically, the medium variant maintained by the act community for this exact purpose.

With .actrc in place, confirm act recognizes the configuration without asking again:

act -l

What to expect (literal output, with no workflow yet in this folder — only the table header, and no interactive prompt from the previous step):

Stage  Job ID  Job name  Workflow name  Workflow file  Events

No errors, no questions — exactly the behavior you're going to need every time you run act in andes-cargo-infra/ from lesson 8 onward.


Common mistakes

command not found: act after brew install (flow-based). What happens: the command finished with no errors, but your shell can't find the binary. Why it happens: on macOS, if Homebrew isn't correctly linked to your shell's PATH (more common in recent Homebrew installs or non-standard shells), the binary exists at /opt/homebrew/bin/ but your terminal doesn't look there. How to spot it: which act returns no path. How to fix it: close and reopen your terminal; if it persists, confirm the install path with brew --prefix act and add it to your PATH manually, or run brew link act.

Architecture warning on Apple Silicon (reproduced, literal, for this lesson). What happens: on a Mac with an M-series chip (M1/M2/M3/M4), every act run prints this warning before starting any job:

level=warning msg= ⚠ You are using Apple M-series chip and you have not specified container architecture, you might encounter issues while running act. If so, try running it with '--container-architecture linux/amd64'. ⚠

Why it happens: act's runner images (like catthehacker/ubuntu:act-latest) are mostly built for amd64 architecture (Intel/AMD), and Docker on Apple Silicon runs them via emulation. How to spot it: the message shows up, literally, in the output of every act push/act -l on a Mac with an Apple Silicon chip — it's not an error, it's an informational warning. How to fix it: for the vast majority of workflows in this guide there's nothing you need to do about it —emulation works correctly, just a bit slower— if some day a specific Action fails in a strange way only on Apple Silicon, add --container-architecture linux/amd64 to the act command as the message itself suggests.

The interactive prompt reappears even though you already created .actrc (location-based). What happens: someone creates .actrc in one folder, but runs act from a different folder, and the image-selection prompt reappears. Why it happens: act looks for .actrc in the current working directory (and in the user's $HOME as global config) — an .actrc in ~/project-a/ doesn't apply if you run act from ~/project-b/. How to spot it: the "Please choose the default image" prompt reappears in a folder where you thought you'd already solved it. How to fix it: confirm with pwd which folder you're standing in, and that .actrc exists right there (ls -la .actrc). Every project in this guide —lesson 7's lab, and later andes-cargo-infra/ from lesson 8 onward— needs its own .actrc.


Exercises

Exercise 1 — Verify your own installation. Run act --version and docker ps on your machine, right now. Do they match this lesson's literal output? If act --version shows a number other than 0.2.89, what does that tell you about when you installed it?

See solution

act --version should show act version 0.2.89 or a later version —Homebrew installs the latest available at the moment of your brew install, so a higher number is normal and expected if you installed after this guide was published; a lower number would indicate an old cached installation, worth updating with brew upgrade act. docker ps, if you don't have any containers running, should show only the header row, with no data rows below it.

Exercise 2 — Explain the image size to a colleague. A coworker asks you why this guide chose the "Medium" image instead of the "Large" one, if the "Large" one is "more complete and closer to a real runner." Answer them in two or three sentences.

See solution

A complete answer sounds, roughly, like this: "The Large image is, yes, the most faithful to a real GitHub runner, but it weighs around 17GB to download and up to 53GB on disk — a high cost just to practice locally. The Medium image (~500MB) ships what's needed for the vast majority of real Actions to work, including hashicorp/setup-terraform, which explicitly installs Terraform on every run instead of assuming it's preinstalled — so we don't lose any fidelity in what this guide needs, only in tools we're never going to use."

Exercise 3 — Diagnose the reappearing prompt. A colleague tells you: "I created my .actrc yesterday, but today act asked me again which image I want to use." What's the first question you'd ask them, based on what you learned in "Common mistakes"?

See solution

The first question should be: "are you running act from the same folder where you created the .actrc?" act looks for that file in the current working directory — if your colleague created .actrc inside one project but later ran act from a different folder (for example, a new test project, or andes-cargo-infra/ instead of lesson 7's lab), the file simply isn't where act looks for it, and the default behavior (asking) shows up again.


Summary and next step

In this lesson you installed act 0.2.89 with Homebrew and confirmed the installation with act --version (literal output, executed today). You verified Docker is running with docker ps, saw the real prompt act shows the first time it chooses a runner image, and solved it permanently and reproducibly with an .actrc file that pins catthehacker/ubuntu:act-latest — the medium image you're going to use throughout this guide.

Before moving on you should be able to: install act from scratch on your system, without looking at this lesson; explain the difference between the Large, Medium, and Micro images; and create an .actrc that avoids the interactive prompt in any new project.

You have the tool installed and Docker verified, but you haven't run any real workflow yet. Lesson 7 does exactly that: your first "hello world," end to end.

Resources

  1. nektosact.com — Installation — every officially documented installation method, including the gh extension.
  2. nektosact.com — Runners — official documentation for the Large/Medium/Micro images and how to pin them with .actrc.
  3. GitHub — nektos/act — the tool's official repository.
  4. Homebrew — Formula: act — the formula's page in Homebrew's main repository.