Saltar al contenido
← Volver a Onopen

Guía por archivo

initializeCommand: la parte del devcontainer que corre fuera del contenedor

Abrir un proyecto en un dev container suena a aislamiento: el código raro se queda dentro. Pero uno de los comandos que declara devcontainer.json se ejecuta en tu máquina, antes de que exista el contenedor.

.devcontainer/devcontainer.json.devcontainer.json

Lo medimos

5.5%

de los 9,997 repositorios más populares de GitHub tienen al menos un hallazgo de la familia devcontainer.

554

repositorios con un dev container que declara algo que revisar.

Cómo lo medimos

Qué se ejecuta y cuándo

La especificación de Dev Containers dice que initializeCommand se ejecuta en la máquina anfitriona durante la inicialización, incluida la creación del contenedor y los arranques posteriores, y que puede correr más de una vez por sesión. Corre en la carpeta del código, con tu usuario y con acceso a tu disco, tus claves SSH y tu configuración de git.

El resto del ciclo de vida sí corre dentro: onCreateCommand y updateContentCommand al crear el contenedor, postCreateCommand cuando se asigna por primera vez, postStartCommand en cada arranque y postAttachCommand cada vez que una herramienta se conecta. Que corran dentro no los vuelve inocuos: runArgs puede pedir --privileged y mounts puede montar carpetas de tu máquina, como ~/.ssh, dentro del contenedor.

Por qué pasa desapercibido

El editor detecta el devcontainer.json y ofrece "Reabrir en contenedor". Ese clic es todo lo que hace falta para que initializeCommand se ejecute en el anfitrión. Como la idea del contenedor es aislar, poca gente lee ese archivo con la desconfianza con la que leería un script de instalación.

En nuestro estudio, 554 de los 9,997 repositorios más populares (5.5%) tienen al menos un hallazgo en su configuración de dev container. Casi siempre es una preparación legítima del entorno, y por eso un initializeCommand que lee ~/.gitconfig o llama a curl se confunde fácilmente con el resto.

Cómo revisarlo a mano

Antes de reabrir en contenedor, busca todos los devcontainer.json (puede haber varios en subcarpetas de .devcontainer) y lee initializeCommand primero, porque es el único que corre fuera. Después revisa runArgs, mounts y los comandos de ciclo de vida.

devcontainer.json admite comentarios, así que grep funciona mejor que un parser JSON estricto.

find . -name devcontainer.json -o -name .devcontainer.json | grep -v node_modulesgrep -rn -A3 -E 'initializeCommand|runArgs|mounts' .devcontainer .devcontainer.json 2>/dev/null

Qué marca Onopen

El escáner devcontainer lee .devcontainer/**/devcontainer.json y .devcontainer.json. Marca initializeCommand como inmediato (!) porque corre en el anfitrión, y señala también el resto de comandos de ciclo de vida y las features. Lo que corre dentro del contenedor suele salir como diferido (~): se ejecuta, pero después de un acto deliberado como construirlo.

onopen --only devcontainer --explain ./repo

Preguntas frecuentes

¿initializeCommand se ejecuta dentro del contenedor?

No. Según la especificación, corre en la máquina anfitriona, en la carpeta del código, antes y en cada arranque del contenedor.

¿Usar un dev container me protege de un repositorio malicioso?

Ayuda con lo que corre dentro, pero no con initializeCommand ni con montajes o permisos que el propio archivo pida. Revísalo antes de reabrir en contenedor.

¿Qué otros campos debería mirar?

runArgs (por ejemplo --privileged), mounts que lleven carpetas de tu máquina al contenedor, y los comandos postCreateCommand y postStartCommand.

Fuentes

Otras guías

Revisa un repositorio antes de abrirlo

Onopen es gratis y de código abierto. Lee la configuración, no ejecuta nada y no abre ninguna conexión.