Automatiza la creación, orquestación y gestión de entornos aislados de desarrollo en Docker (DevContainers).
DevContainer Installer CLI (devcontainer-cli) es una herramienta interactiva y extensible construida en Go. Olvídate de perder horas configurando dependencias, resolviendo conflictos de versiones y adecuando tu entorno local para cada nuevo proyecto: esta CLI automatiza la creación, orquestación y gestión de entornos aislados de desarrollo en Docker (DevContainers).
Con un asistente interactivo (TUI), te permite componer en segundos un contenedor a medida para desarrollo con tu stack preferido, bases de datos dockerizadas, utilidades avanzadas de terminal y agentes de Inteligencia Artificial (como Claude Code, Copilot y Codex), garantizando la máxima productividad y consistencia sin ensuciar tu sistema operativo anfitrión.
El entorno ofrece un contenedor principal (devcontainer-ssh) accesible vía SSH, permitiendo conectar tu editor (VS Code) o terminal según la infraestructura disponible:
1. Acceso Local (Host de desarrollo)
Conexión SSH directa a la IP privada del contenedor en el mismo equipo. No requiere exponer puertos al exterior.
graph LR
subgraph Host["Tu Computadora (Host)"]
VSCode["VS Code / Terminal"]
subgraph DockerEnv["Entorno Docker"]
DevContainer["🖥️ Devcontainer-SSH"]
DBs[("🗄️ Bases de Datos")]
end
end
VSCode -- "SSH Directo (IP Privada)" --> DevContainer
DevContainer <--> DBs
2. Acceso Remoto LAN (Laptop → Servidor)
Conexión desde una laptop a un servidor local (Raspberry Pi, Mini PC) usando el servicio SSH del servidor como puente seguro (netcat), sin exponer puertos del contenedor.
graph LR
subgraph Laptop["Tu Laptop (Cliente)"]
VSCode["VS Code"]
end
subgraph Server["Servidor (Host)"]
SSHD["SSHD (Host)"]
subgraph DockerEnv["Entorno Docker"]
DevContainer["🖥️ Devcontainer-SSH"]
end
end
VSCode -- "SSH (ProxyCommand)" --> SSHD
SSHD -- "netcat (nc): Reenvía tráfico TCP" --> DevContainer
3. Acceso Remoto Seguro (Cloudflare Tunnel)
Acceso desde cualquier lugar mediante Cloudflare Zero Trust y cliente WARP sin abrir puertos en el router. cloudflared se instala dentro del devcontainer (módulo cloudflared), así que el túnel alcanza localhost sin saltos de red. (Ver CLOUDFLARE_TUNNEL.md).
graph LR
subgraph Remote["Remoto (Cafetería/Casa)"]
Laptop["Laptop + WARP Client"]
end
subgraph Internet["Cloudflare Edge"]
ZeroTrust["Zero Trust Network"]
end
subgraph LocalNetwork["Tu Red Local"]
subgraph DockerEnv["Entorno Docker"]
subgraph DevContainer["🖥️ Devcontainer-SSH"]
Cloudflared["Cloudflared (Túnel)"]
end
DBs[("🗄️ Bases de Datos")]
end
end
Laptop -- "Túnel Seguro" --> ZeroTrust
ZeroTrust -- "Túnel Encriptado" --> Cloudflared
Cloudflared -- "localhost" --> DevContainer
Cloudflared -- "Ruteo IP Privada" --> DBs
# Instalación rápida (Linux / macOS)
curl -fsSL https://raw.githubusercontent.com/Joacohbc/my-devcontainer-installer/main/cli/install.sh | sh
# Actualizar la CLI a la última versión
devcontainer-cli upgrade-cli
# Desinstalar la CLI
curl -fsSL https://raw.githubusercontent.com/Joacohbc/my-devcontainer-installer/main/cli/uninstall.sh | shDescargas manuales: Disponibles en los Releases de GitHub (binarios standalone para
linux-x64,linux-arm64,darwin-x64ydarwin-arm64). El autocompletado en Zsh y Bash se configura automáticamente tras instalar.
mkdir mi-proyecto && cd mi-proyecto
devcontainer-cli # Asistente interactivo TUI para generar el entorno
devcontainer-cli up # Levanta el stack de contenedores (o ejecutá directamente devcontainer-cli ssh)devcontainer-cli ssh abre una sesión SSH en el contenedor y es dueño de todo el ciclo de vida SSH (acá vivía el viejo setup-ssh). Si aún no está configurado el acceso SSH para el proyecto, ejecuta automáticamente la configuración (creación de claves, alias SSH y fijado de known_hosts). Con --setup fuerza esa configuración de nuevo antes de conectar.
Los bloques Host se escriben en un archivo propio de la CLI, ~/.ssh/devcontainer-cli.config, y no en tu ~/.ssh/config: a ese último sólo se le agrega una línea Include al principio, la primera vez. Los bloques que versiones anteriores dejaron dentro de ~/.ssh/config se mueven solos. Cambiá la ubicación con devcontainer-cli config ssh-config-file <ruta>.
devcontainer-cli ssh # Conecta al devcontainer (lo configura si es la primera vez)
devcontainer-cli ssh --setup # Rehace la configuración de acceso y luego conecta
devcontainer-cli ssh --via user@docker-host --container dc-ssh # Contenedor en OTRO host, a través de una conexión SSH existente
ssh mi-proyecto # Conexión directa vía cliente SSH tradicional usando el alias generado--via (requiere --container) es para cuando el contenedor vive en un Docker host distinto: usa la conexión SSH que ya tenés a ese host para instalar la clave y fijar el known_hosts, sin instalar devcontainer-cli ahí — la clave privada nunca sale de esta máquina. Es lo opuesto de --setup-external USER@HOST, que asume que la CLI corre en el host remoto: en vez de conectar, imprime un snippet autocontenido (con la clave privada) para pegar en la máquina desde la que te conectás.
Copia archivos entre el host y el contenedor o instala scripts embebidos de IA en caliente:
devcontainer-cli copy ./app.go :/home/devuser/app.go # Host -> Contenedor
devcontainer-cli copy --asset install-claude-code # Materializa instalador en el contenedorComparte sesiones (.claude, .codex, .gemini, .config/gh) entre todos los contenedores mediante un volumen persistente:
devcontainer-cli config shared sync # Sembrar logins del host al volumen
devcontainer-cli config shared backup -o backup.zip # Respaldar volumen a un file .zip
devcontainer-cli config shared restore backup.zip # Restaurar volumen desde un file .zipCada contenedor trae ~/CONTEXT.md, el documento que un agente de IA debería leer primero. Se genera para cada proyecto a partir de los módulos y servicios que elegiste, así que describe lo que realmente hay en esa imagen: que estás dentro de Docker, uv para Python, pnpm para JS, qué versión de Node quedó fija, y a qué host, puerto y credenciales responde cada base de datos (contenedores hermanos, nunca localhost). Elegir otros módulos cambia el documento.
Para lo que sólo se sabe en tiempo de ejecución está get-devcontainer-context, que lista las herramientas realmente instaladas con sus versiones, los servicios alcanzables y el workspace resuelto.
Además, cada imagen trae preinstalada una skill global llamada devcontainer-context (queda enlazada en ~/.agents/skills y ~/.claude/skills, así que los agentes la ven sin instalar nada). Es corta a propósito: le avisa al agente que está adentro de un contenedor Docker, le dice que lea ~/CONTEXT.md y corra get-devcontainer-context antes de asumir nada, y le recuerda lo que vale en todos los contenedores (editar sólo en el workspace, que todo lo de afuera del workspace y /home/devuser se pierde al recrear, que hay sudo sin password, que no hay systemd, que sólo los puertos publicados se ven desde el host, y que las bases se alcanzan por el nombre del servicio de compose y no por localhost).
devcontainer-cli context # Reporte legible del contenedor del proyecto
devcontainer-cli context --json # Salida estructurada, pensada para agentes
get-devcontainer-context # Lo mismo, desde adentro del contenedorLo anterior es la mitad de adentro del contenedor. La mitad de afuera es devcontainer-cli skill: instala en tu máquina una skill que le enseña a un agente del host (Claude Code, Antigravity, …) a manejar esta CLI — generar el devcontainer de un proyecto, correr builds y tests adentro, publicar o tunelizar puertos, revisar qué trae la imagen y destruir el entorno. Con eso el agente puede meter el trabajo en un contenedor en vez de ensuciar tu máquina.
El documento se escribe en los mismos dos directorios que usa la skill de adentro: ~/.claude/skills/devcontainer-cli/SKILL.md y ~/.agents/skills/devcontainer-cli/SKILL.md. Si ya hay un archivo ahí que no escribió la CLI, no se pisa sin --force.
devcontainer-cli skill # Dónde iría y qué hay instalado hoy
devcontainer-cli skill install # Instalar (o actualizar) la skill
devcontainer-cli skill install --agent claude --scope project # Sólo Claude Code, sólo en este proyecto
devcontainer-cli skill show # Imprimir el documento (para otro agente)
devcontainer-cli skill remove # Quitar lo que instaló la CLIVolvé a correr skill install después de un upgrade-cli para quedarte con la versión nueva del documento; los agentes la toman en la sesión siguiente.
El mismo documento está publicado en el repo (skills/devcontainer-cli/SKILL.md), así que una máquina que todavía no tiene el binario puede instalarlo con el CLI de Skills — es la línea que imprimen skill y skill install:
npx skills add Joacohbc/my-devcontainer-installer@devcontainer-cli -gLas dos vías escriben el mismo archivo, así que devcontainer-cli skill reconoce como propia una copia instalada por npx.
La imagen trae aliases por defecto: kill_port <puerto>, npm→pnpm, npx→pnpm dlx, pip/pip3→uv pip, y un lanzador <tool>_yolo por agente (claude_yolo, codex_yolo, copilot_yolo, agy_yolo) que corre el CLI sin prompts de permisos —el contenedor ya es el sandbox—. Los comandos claude, codex, copilot y agy quedan intactos: saltear los permisos es opt-in.
Tus propios aliases los definís por comandos y se guardan en la configuración de la CLI (config.json), no en un archivo suelto de tu home. config alias sync los renderiza dentro del volumen compartido, así que se aplican a todos los contenedores sin reconstruir ninguna imagen y sin reiniciar nada (toman efecto en la próxima shell):
devcontainer-cli config alias # Listar los aliases configurados
devcontainer-cli config alias set ll "ls -la" # Agregar o actualizar uno
devcontainer-cli config alias unset ll # Quitar uno
devcontainer-cli config alias sync # Aplicarlos a todos los contenedoresComo se sourcean después de los defaults de la imagen, lo que definas ahí siempre gana.
Conecta cualquier otro contenedor Docker a la red privada del workspace actual:
devcontainer-cli network connect mi-servicio-extra --alias db-extradevcontainer-cli clean ssh # Elimina bloques SSH y known_hosts obsoletos
devcontainer-cli clean all # Menú interactivo de limpieza de imágenes/volúmenes/redesCredenciales predeterminadas para los servicios de base de datos (Usuario: devuser | Contraseña: devpass):
- PostgreSQL:
psql -h postgres -U devuser -d devdb - MongoDB:
mongosh --host mongo -u devuser -p devpass --authenticationDatabase admin - Redis:
redis-cli -h redis
Para detalles sobre actualización de contraseñas y preparación posterior, consulta POST_INSTALL_STEPS.md.
Permission denied (publickey)
- Ejecuta
devcontainer-cli sshpara verificar y reinstalar automáticamente la clave pública gestionada en~/.ssh/authorized_keysdentro del contenedor. - Si modificaste los archivos manualmente en el contenedor, asegura los permisos requeridos:
chmod 700 ~/.sshychmod 600 ~/.ssh/authorized_keys.
Connection refused o cambio de IP / host key
- Confirma que el contenedor esté activo mediante
docker compose -f .dc_<workspace>/build/docker-compose.yml ps. - Si se reconstruyó la imagen o cambió la IP, ejecuta
devcontainer-cli ssh: la CLI detecta el cambio, actualiza la IP y re-fija automáticamente la host key en~/.config/devcontainer-cli/ssh/known_hosts.
Error de Socket de Docker (DoD) dentro del contenedor
- Verifica que el módulo
dodesté habilitado y que.dc_<workspace>/build/docker-compose.ymlcontenga el montaje- /var/run/docker.sock:/var/run/docker.sock. - Asegura que el usuario
devuserpertenezca al grupodockerdentro del contenedor.