act es una herramienta de línea de comandos que lee los workflows de .github/workflows/ y ejecuta sus jobs en contenedores Docker de tu máquina, imitando a los runners de GitHub. Así puedes probar un cambio en el pipeline en segundos, sin hacer commit y push para cada intento. En este tutorial instalarás act en Ubuntu 24.04, ejecutarás un workflow de ejemplo, le pasarás secretos y variables, recuperarás artefactos y verás cómo depurar un job que falla.

Requisitos previos

Para seguir esta guía necesitas:

  • Un equipo o servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM y 10 GB libres en disco para las imágenes del runner.
  • Un usuario no root con privilegios sudo.
  • Docker Engine instalado desde el repositorio oficial de Docker, con tu usuario en el grupo docker para usarlo sin sudo.
  • Git instalado (sudo apt install -y git).

Comprueba que Docker funciona sin sudo antes de continuar:

docker run --rm hello-world

Si recibes permission denied while trying to connect to the Docker daemon socket, añade tu usuario al grupo con sudo usermod -aG docker "$USER" y vuelve a iniciar sesión.

Paso 1: Instalar act

act se distribuye como un único binario en las publicaciones de su repositorio en GitHub. Descarga la última versión para x86_64, extrae el binario e instálalo en /usr/local/bin:

cd /tmp
curl -fLO https://github.com/nektos/act/releases/latest/download/act_Linux_x86_64.tar.gz
tar -xzf act_Linux_x86_64.tar.gz act
sudo install -m 755 act /usr/local/bin/act
rm act act_Linux_x86_64.tar.gz

En un servidor ARM64 descarga act_Linux_arm64.tar.gz en su lugar. Comprueba la instalación:

act --version
act version 0.2.xx

Paso 2: Crear un proyecto de ejemplo

Para tener algo concreto que ejecutar, crea un repositorio con un workflow sencillo que compila un fichero, usa un secreto y guarda el resultado como artefacto:

mkdir -p ~/act-demo/.github/workflows
cd ~/act-demo
git init -b main

Crea el workflow:

nano .github/workflows/ci.yml
name: CI

on:
  push:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generar el build
        run: |
          mkdir -p dist
          echo "build de ${GITHUB_SHA::7} en ${GITHUB_REF_NAME}" > dist/info.txt
          cat dist/info.txt

      - name: Comprobar el secreto
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          if [ -z "$API_TOKEN" ]; then
            echo "Falta el secreto API_TOKEN"
            exit 1
          fi
          echo "Secreto recibido (${#API_TOKEN} caracteres)"

      - name: Guardar el build
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

      - name: Desplegar
        if: ${{ !env.ACT }}
        run: echo "Este paso solo se ejecuta en GitHub"

El último paso usa la variable ACT, que act define como true en todos los jobs. Es la forma habitual de saltarse en local los pasos que no tienen sentido fuera de GitHub, como un despliegue.

Haz un primer commit para que act tenga un SHA y una rama con los que rellenar el contexto github:

git add .
git commit -m "Workflow de ejemplo"

Si Git aún no conoce tu identidad, configúrala antes con git config --global user.name "Tu Nombre" y git config --global user.email tu@correo.

Paso 3: Elegir la imagen del runner

act no ejecuta los jobs en una máquina virtual como GitHub, sino en un contenedor. Para runs-on: ubuntu-latest necesita saber qué imagen usar. La primera vez que lo ejecutas te pregunta por un tamaño por defecto:

TamañoImagenUso
Micronode:16-buster-slimSolo acciones JavaScript simples; faltan muchas herramientas
Mediumcatthehacker/ubuntu:act-latestRecomendado: Ubuntu con Node.js, Git y utilidades básicas
Largecatthehacker/ubuntu:full-latestCasi idéntico a GitHub, pero ocupa decenas de GB

La opción Medium es un buen punto de partida. En lugar de depender de la pregunta interactiva, fija la imagen en un fichero .actrc en la raíz del proyecto, que act lee en cada ejecución:

nano ~/act-demo/.actrc
-P ubuntu-latest=catthehacker/ubuntu:act-latest
--artifact-server-path /tmp/act-artifacts

Cada línea es una opción de la línea de comandos. -P asocia la etiqueta de runs-on con una imagen y --artifact-server-path activa el servidor de artefactos integrado de act, que usarás en el paso 5.

Lista ahora los jobs que act detecta:

act -l
Stage  Job ID  Job name  Workflow name  Workflow file  Events
0      build   build     CI             ci.yml         push,pull_request

Paso 4: Ejecutar el workflow con secretos y variables

act busca por defecto los secretos en un fichero .secrets y las variables de entorno en .env, ambos en la raíz del proyecto y con formato NOMBRE=valor. Crea el fichero de secretos con un valor de prueba:

nano ~/act-demo/.secrets
API_TOKEN=your_test_token

Estos ficheros no deben llegar nunca al repositorio. Añádelos a .gitignore:

printf '.secrets\n.env\n.vars\n' >> ~/act-demo/.gitignore

Ejecuta el evento push, que es el evento por defecto de act:

cd ~/act-demo
act push

La primera ejecución descarga la imagen del runner y las acciones (actions/checkout, actions/upload-artifact), así que tarda unos minutos. Las siguientes reutilizan la caché. La salida muestra cada paso con el prefijo [workflow/job]; abreviada, termina así:

[CI/build]   | build de 1a2b3c4 en main
[CI/build]   | Secreto recibido (15 caracteres)
[CI/build]   Success - Main Comprobar el secreto
[CI/build]   Success - Main Guardar el build
[CI/build] Job succeeded

Fíjate en que el paso Desplegar no aparece: la condición !env.ACT lo ha saltado. act oculta el valor de los secretos en el log igual que GitHub, sustituyéndolo por ***.

Algunas formas útiles de acotar la ejecución:

act push -j build
act pull_request
act push -W .github/workflows/ci.yml
act push -n

-j ejecuta un solo job, el segundo comando simula el evento pull_request, -W limita la ejecución a un fichero de workflow y -n (dry run) muestra el plan sin crear contenedores.

Si prefieres no usar ficheros, pasa los secretos en la línea de comandos. Con -s NOMBRE sin valor, act lo toma de tu entorno, lo que evita que la contraseña quede en el historial de la shell:

export API_TOKEN=your_test_token
act push -s API_TOKEN

Las variables de configuración del repositorio (el contexto vars) se pasan igual con --var NOMBRE=valor o en un fichero .vars.

Paso 5: Recuperar los artefactos

Gracias a --artifact-server-path en .actrc, act arranca un servidor de artefactos local y actions/upload-artifact@v4 guarda cada artefacto como un fichero ZIP bajo /tmp/act-artifacts, en un subdirectorio por ejecución. Localízalo:

find /tmp/act-artifacts -name '*.zip'

La ruta devuelta incluye el identificador de la ejecución y el nombre del artefacto (dist). Lista su contenido sustituyendo ruta_del_zip por la ruta anterior:

unzip -l ruta_del_zip
Archive:  ruta_del_zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       25  2026-09-25 10:12   info.txt

actions/download-artifact@v4 funciona también contra este servidor, así que los workflows que pasan artefactos entre jobs se pueden probar completos.

Paso 6: Usar una imagen de runner personalizada

Si tus jobs instalan siempre las mismas herramientas con apt-get, cada ejecución local repite esa descarga. Puedes crear una imagen propia a partir de la de act con esas herramientas ya incluidas. Crea un Dockerfile fuera de .github:

nano ~/act-demo/Dockerfile.act
FROM catthehacker/ubuntu:act-latest

RUN apt-get update \
    && apt-get install -y --no-install-recommends jq postgresql-client shellcheck \
    && rm -rf /var/lib/apt/lists/*

Constrúyela:

docker build -t act-runner:local -f Dockerfile.act .

Y cambia la línea -P de .actrc para que la use:

-P ubuntu-latest=act-runner:local
--artifact-server-path /tmp/act-artifacts

Por defecto act intenta descargar la imagen de un registro en cada ejecución, y una imagen solo local fallaría. Ejecuta con --pull=false para usar la que acabas de construir:

act push --pull=false

Recuerda que esto solo cambia el entorno local. En GitHub el job sigue ejecutándose en la imagen oficial de ubuntu-latest, así que no debes depender de herramientas que solo existen en tu imagen.

Paso 7: Depurar un job que falla

Cuando un paso falla, lo primero es ver la salida completa con el modo detallado:

act push -v 2>&1 | tee act-debug.log

Si necesitas inspeccionar el estado del contenedor tras el fallo, usa --reuse, que no elimina el contenedor del job al terminar:

act push --reuse
docker ps --filter "name=act-" --format '{{.Names}}'
act-CI-build-3c9e1f0a...

Entra en él con el nombre que te muestre docker ps. El código del repositorio está en la misma ruta que en tu máquina:

docker exec -it act-CI-build-3c9e1f0a bash

Dentro puedes repetir los comandos del paso que falla y revisar las variables GITHUB_* con env | grep ^GITHUB_. Cuando termines, elimina el contenedor con docker rm -f y el nombre anterior.

Solución de problemas

  • Cannot connect to the Docker daemon: Docker no está en marcha (sudo systemctl status docker) o tu usuario no pertenece al grupo docker.
  • command not found en un paso que funciona en GitHub: la imagen Medium no incluye todo lo que trae el runner de GitHub. Instala la herramienta en el propio workflow, usa una imagen personalizada como en el paso 6 o prueba con catthehacker/ubuntu:full-latest.
  • En un equipo con Apple Silicon o ARM64, las acciones fallan con errores de arquitectura: fuerza la plataforma de GitHub con --container-architecture linux/amd64. Irá más lento porque se emula.
  • Un job con services: (por ejemplo PostgreSQL) no conecta a la base de datos: act crea los servicios en una red de Docker propia; usa el nombre del servicio como host, igual que en GitHub cuando el job corre en un contenedor.
  • Acciones que dependen de la API de GitHub fallan: algunas necesitan un token real. Pásalo con -s GITHUB_TOKEN="$(gh auth token)" si usas GitHub CLI, o con un token personal de acceso con permisos mínimos.

Conclusión

Has instalado act en Ubuntu 24.04, has ejecutado un workflow de GitHub Actions en local con secretos y artefactos, y sabes cómo usar una imagen de runner propia y depurar un job que falla dentro de su contenedor. act no sustituye a la ejecución en GitHub, pero reduce mucho los ciclos de prueba y error al escribir un pipeline.

Como siguientes pasos puedes:

  • Añadir la condición !env.ACT a los pasos de despliegue o publicación de tus workflows reales.
  • Guardar un .actrc en cada repositorio para que todo el equipo use la misma imagen.
  • Probar eventos concretos pasando un fichero JSON con act -e evento.json, útil para workflows de release o workflow_dispatch con entradas.