Guías
Documentación
Agente en contenedor aislado

Docker y OrbStack

Corre el agente en un contenedor aislado con Docker u OrbStack: base completa de Rails, un archivo Compose listo.

Docker y OrbStack corren el agente en un contenedor aislado con una base completa de Rails y cada librería nativa preinstalada. El trabajo del agente —clones, bundle install, migraciones, compilación de assets— se queda dentro de sus volúmenes, y el repo trae un archivo Compose para que un solo comando lo levante.

¿Cuál entorno?

Apple Container

El mayor aislamiento: cada agente corre en su propia VM ligera. La opción nativa y delgada en una Mac reciente.

Apple silicon · macOS 15+

Docker y OrbStack

Estás aquí

Corre donde corra Docker, Intel o ARM, con un archivo Compose listo. OrbStack lo mantiene ligero en una Mac.

Docker u OrbStack · Intel o Apple silicon

¿No es lo que buscas? Configura Apple Container en su lugar.

Instala el entorno de ejecución

Instala OrbStack —recomendado en una Mac— o Docker Desktop, y confirma que el demonio está corriendo.

brew install orbstack          # recommended — or install Docker Desktop
docker --version && docker info

El agente corre por completo dentro del contenedor, así que la única otra herramienta que necesitas en la Mac es Claude Code, usada una vez para generar el token del agente. Sáltala si ya la tienes.

npm install -g @anthropic-ai/claude-code

Obtén la imagen

Descarga la imagen publicada y etiquétala como local/fragua:latest para que la guía y el archivo Compose coincidan. Descargarla evita la construcción de 10 a 15 minutos y te da la imagen publicada exacta.

docker pull ghcr.io/maquina-app/fragua-docker:latest
docker tag ghcr.io/maquina-app/fragua-docker:latest local/fragua:latest
docker image ls | grep fragua
Qué trae la imagen

La imagen es un entorno Rails completo construido sobre Ubuntu 24.04. No tienes que confiar a ciegas: esto es lo que trae, y un comando para confirmarlo tú mismo.

Entornos de lenguajes
Ruby y Node, gestionados por mise. El .mise.toml propio de un proyecto sobrescribe las versiones globales automáticamente.
Cadena de herramientas de Ruby
Bundler y Rails preinstalados, con banderas de compilación conectadas a las librerías del sistema para que gemas nativas como nokogiri, pg, mysql2 y hiredis compilen sin líos.
Librerías nativas
Toda la base que necesita bundle install: herramientas de compilación, SSL y cripto, SQLite, PostgreSQL y MySQL, imagen y multimedia (ImageMagick, libvips, WebP, ffmpeg), PDF (wkhtmltopdf y tipografías), libxml, Protobuf y gRPC, geoespacial (GEOS, PROJ), y renderizado con Pango/Cairo.
Herramientas de línea de comandos
GitHub CLI, git, Claude Code y la CLI de Fragua: todo lo que el agente necesita para clonar, construir y subir cambios.

Confirma la base desde dentro del contenedor:

ruby --version && node --version && rails --version
sqlite3 --version && pg_config --version && mysql_config --version
ffmpeg -version | head -1 && wkhtmltopdf --version
gh --version && claude --version && fragua --version

Corre esto en la sesión de configuración de abajo, o en cualquier shell del contenedor. Cada línea debe imprimir una versión.

¿Quieres cambiar lo que se instala: agregar una librería, fijar una versión, construir multiarquitectura? El Dockerfile y el script de construcción viven en el repo de fragua-tools, con notas para personalizar y publicar tu propia imagen.

Crea los volúmenes e inicia sesión una vez

Todo lo que el agente necesita vive en cuatro volúmenes con nombre, así que el agente en marcha no depende de nada de tu Mac. Los configuras una vez; sobreviven cada reconstrucción.

Crea los cuatro volúmenes

docker volume create fragua-config
docker volume create fragua-secrets
docker volume create fragua-workdir
docker volume create fragua-data
docker volume ls | grep fragua
fragua-config
/fragua-config

Token de Fragua y estado local, tu identidad de Git, el token de Claude y el estado de sesión y por proyecto de Claude Code.

fragua-secrets
/fragua-secrets

El token de GitHub CLI y la llave SSH propia del contenedor, juntos. Solo lectura cuando el agente está corriendo, así que los usa pero nunca los reescribe.

fragua-workdir
/fragua-workdir

El árbol de trabajo del agente: clones, bundle install, bases de datos, assets compilados.

fragua-data
/fragua-data

Los CLIs de Claude Code y fragua, además de las gemas y paquetes de Node que el agente instala al correr — guardados para que una reconstrucción no los descargue de nuevo.

Genera el token de Claude (en tu Mac)

El inicio de sesión interactivo de Claude Code necesita un navegador, que un contenedor sin pantalla no puede abrir. Genera un token de larga duración en la Mac: lo pegas en un volumen enseguida, y el contenedor lo lee de ahí en cada corrida.

claude setup-token

Abre la sesión de configuración única

Abre una shell de una sola vez con los volúmenes de configuración y de secretos montados con escritura. Es la única vez que el volumen de secretos tiene escritura: al correr baja a solo lectura, así que el agente usa el token de GitHub y la llave SSH pero nunca los reescribe.

docker run --rm -it \\
  -v fragua-config:/fragua-config:rw \\
  -v fragua-secrets:/fragua-secrets:rw \\
  local/fragua:latest bash

Dentro del contenedor, crea los directorios de secretos y luego inicia sesión en GitHub. El flujo de código de dispositivo funciona sin pantalla: imprime un código y una URL. La bandera --insecure-storage escribe el token en el volumen de secretos para que persista; sin ella gh puede guardarlo en un llavero dentro de la VM que desaparece en la siguiente corrida.

mkdir -p /fragua-secrets/gh /fragua-secrets/ssh && chmod 700 /fragua-secrets/ssh
gh auth login --insecure-storage

Dale al contenedor su propia llave SSH en vez de copiar la tuya personal. Una llave dedicada está aislada de tu Mac y puedes revocarla por separado. Define una identidad de Git, genera la llave y regístrala en GitHub:

git config --global user.name  "Your Name"
git config --global user.email "[email protected]"

chmod 700 /root/.ssh
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "fragua-docker"
gh auth refresh -h github.com -s admin:public_key
gh ssh-key add /root/.ssh/id_ed25519.pub --title "fragua-docker"
ssh -o IdentitiesOnly=yes -i /root/.ssh/id_ed25519 -T [email protected]

¿Usas remotos https:// en vez de [email protected]? Sáltate la llave por completo y corre gh auth setup-git para que gh actúe como ayudante de credenciales de git.

Avanzado: puedes reutilizar una llave del host montándola y copiándola una vez, pero solo si no tiene frase de paso; bajo tu propio riesgo.

Pega el token de claude setup-token en el volumen de configuración. El entrypoint de la imagen lee este archivo en cada corrida, así que no lo vuelves a pasar.

printf '%s' 'PASTE_THE_setup-token_VALUE' > /fragua-config/claude-oauth-token
chmod 600 /fragua-config/claude-oauth-token
claude -p "reply with the single word: ok"

Por último, conecta la CLI de Fragua con el AgentToken de tu página de Configuración, revisa la instalación y sal de la shell.

fragua login
fragua doctor
exit

Corre el agente

Un compose.yaml monta solo los cuatro volúmenes, sin rutas del host. Tómalo aquí abajo, levántalo, sigue los logs y revisa el estado del agente.

fragua-config rw
/fragua-config
fragua-secrets ro
/fragua-secrets
fragua-workdir rw
/fragua-workdir
fragua-data rw
/fragua-data
compose.yaml

Guárdalo como compose.yaml en el directorio desde donde corres docker compose. Monta solo los cuatro volúmenes — sin rutas del host, nada conectado a tu Mac.

services:
  fragua-agent:
    image: local/fragua:latest
    volumes:
      - fragua-config:/fragua-config:rw     # fragua status/DB, git identity, claude token + state
      - fragua-secrets:/fragua-secrets:ro   # gh token + SSH key (read-only at runtime)
      - fragua-workdir:/fragua-workdir:rw   # agent working tree
      - fragua-data:/fragua-data:rw         # claude + fragua CLIs, runtime gems + node modules
    restart: unless-stopped

volumes:
  fragua-config:
    external: true
  fragua-secrets:
    external: true
  fragua-workdir:
    external: true
  fragua-data:
    external: true
docker compose up -d
docker compose logs --follow
docker compose exec fragua-agent fragua status

¿Prefieres un docker run de una sola vez? Aquí está el equivalente del archivo Compose:

docker run -d --name fragua-agent --restart unless-stopped \\
  -v fragua-config:/fragua-config:rw \\
  -v fragua-secrets:/fragua-secrets:ro \\
  -v fragua-workdir:/fragua-workdir:rw \\
  -v fragua-data:/fragua-data:rw \\
  local/fragua:latest

Día a día

Recónstruye o actualiza el agente. Cada volumen sobrevive a docker compose down y a las reconstrucciones de imagen, así que no hay que volver a configurar.

# rebuild — every volume survives, no re-setup
docker compose exec fragua-agent fragua prune --yes
docker compose down
docker build --no-cache -t local/fragua:latest .
docker compose up -d --force-recreate   # recreate so the new image's CLIs are adopted (plain up -d/start keeps the old container)

# update the CLIs (Claude Code + fragua) a running agent uses — no rebuild
docker compose exec fragua-agent fragua-refresh-cli   # both (or: claude / fragua)
# (refresh only the image's offline baseline instead: ./build.sh --refresh-cli)

# inspect the workdir without touching the running agent
docker run --rm -v fragua-workdir:/data:ro alpine ls -la /data

# drop the runtime gem/node cache + CLIs (re-bootstrapped on next start, keeps creds)
docker volume rm fragua-data && docker volume create fragua-data

Solución de problemas

claude /login falla con "Invalid OAuth Request / Unknown scope"
El redirect del navegador no puede completarse en un contenedor sin pantalla. Corre claude setup-token en tu Mac y escribe el resultado en /fragua-config/claude-oauth-token.
git push falla con "Permission denied (publickey)"
La llave del contenedor no está en GitHub. Vuelve a correr gh ssh-key add /root/.ssh/id_ed25519.pub en la shell de configuración y prueba con ssh -T [email protected].
gh dice "not logged in" cuando el agente ya corre
El volumen fragua-secrets no está montado o está vacío. Vuelve a correr gh auth login --insecure-storage en la shell de configuración y confirma que el volumen esté listado en tu compose.yaml.
git por HTTPS falla con "could not read Username for https://github.com"
No hay un ayudante de credenciales de git conectado al token de gh: el agente se configuró solo con SSH. Corre gh auth setup-git una vez en la shell de configuración; escribe el ayudante en /fragua-config/gitconfig y persiste.
claude rechaza --dangerously-skip-permissions con "cannot be used with root/sudo privileges"
La imagen corre como root por diseño y define IS_SANDBOX=1 para que Claude Code reconozca el contenedor aislado. Si te topas con esto, estás en una imagen vieja construida antes de esa variable: reconstruye, o define IS_SANDBOX=1 al invocar claude.
Un host x86 no puede correr una imagen arm64
Publica una imagen multiarquitectura con ./build.sh --platform linux/amd64,linux/arm64 para que hosts Intel y ARM puedan descargar la misma etiqueta.