Estoy tratando de construir una nueva imagen de Docker para nuestro proceso de desarrollo, utilizando cpanmpara instalar un montón de módulos Perl como imagen base para varios proyectos.
Mientras desarrolla el Dockerfile, cpanmdevuelve un código de falla porque algunos de los módulos no se instalaron limpiamente.
Estoy bastante seguro de que necesito aptinstalar algunas cosas más.
Mi pregunta es, ¿dónde puedo encontrar el /.cpanm/workdirectorio citado en la salida para inspeccionar los registros? En el caso general, ¿cómo puedo inspeccionar el sistema de archivos de un docker buildcomando fallido ?
Editar mañana Después de morder la bala y ejecutar un finddescubrí
/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm
¿Es esto confiable, o es mejor construir un contenedor "desnudo" y ejecutar cosas manualmente hasta que tenga todo lo que necesito?

/var/lib/docker/aufs/diff/3afa404e[...]/.cpanmesos sonRespuestas:
Cada vez que Docker ejecuta con éxito un
RUNcomando desde un Dockerfile, se confirma una nueva capa en el sistema de archivos de imagen . Convenientemente, puede usar esos identificadores de capas como imágenes para iniciar un nuevo contenedor.Tome el siguiente Dockerfile:
y construirlo:
Ahora puede comenzar un nuevo contenedor de
00f017a8c2a6,044e1532c690y5bd8172529c1:por supuesto, es posible que desee iniciar un shell para explorar el sistema de archivos y probar comandos:
Cuando falla uno de los comandos de Dockerfile, lo que debe hacer es buscar la identificación de la capa anterior y ejecutar un shell en un contenedor creado a partir de esa identificación:
Una vez en el contenedor:
Si realmente necesita experimentar en la capa real que falló en lugar de trabajar desde la última capa de trabajo, vea la respuesta de Drew .
fuente
docker run --rm -it <id_last_working_layer> bash -ily una vez en el contenedor, pruebe el comando que no pudo reproducir el problema, luego arregle el comando y pruébelo, finalmente actualice su Dockerfile con el comando fijo.docker diff <container>obtener una lista completa de los cambios específicos del sistema de archivos realizados en esa capa en particular (archivos agregados, eliminados o cambiados en todo el sistema de archivos para esa imagen).Unable to find image 'd5219f1ffda9:latest' locally. Sin embargo, estaba confundido por los múltiples tipos de ID. Resulta que tienes que usar las ID que están directamente después de las flechas, no las que dicen "Ejecutando en ...".La respuesta principal funciona en el caso de que desee examinar el estado inmediatamente anterior al comando fallido.
Sin embargo, la pregunta pregunta cómo examinar el estado del contenedor fallido. En mi situación, el comando fallido es una compilación que lleva varias horas, por lo que rebobinar antes del comando fallido y ejecutarlo nuevamente lleva mucho tiempo y no es muy útil.
La solución aquí es encontrar el contenedor que falló:
Compromételo con una imagen:
Y luego ejecute la imagen [si es necesario, ejecutando bash]:
Ahora realmente está mirando el estado de la compilación en el momento en que falló, en lugar de en el momento antes de ejecutar el comando que causó la falla.
fuente
DOCKER_BUILDKIT=1para construir suDockerfileDocker almacena en caché todo el estado del sistema de archivos después de cada
RUNlínea exitosa .Sabiendo que:
RUNcomando fallido , coméntelo en el Dockerfile (así como en cualquiera y todos losRUNcomandos posteriores ), luego ejecútelo unadocker buildydocker runotra vez.RUNcomando fallido , simplemente agréguelo|| truepara forzarlo a tener éxito; luego proceda como anteriormente (mantengaRUNcomentados todos y cada uno de los comandos posteriores , ejecutedocker buildydocker run)Tada, no es necesario meterse con elementos internos de Docker o ID de capa, y como beneficio adicional, Docker minimiza automáticamente la cantidad de trabajo que se debe volver a hacer.
fuente
La depuración de fallas de paso de compilación es realmente muy molesta.
La mejor solución que he encontrado es asegurarme de que cada paso que hace un trabajo real tenga éxito y agregar un cheque después de aquellos que fallan. De esa forma, obtiene una capa comprometida que contiene los resultados del paso fallido que puede inspeccionar.
Un Dockerfile, con un ejemplo después de la
# Run DB2 silent installerlínea:fuente
Lo que haría es comentar el Dockerfile a continuación e incluir la línea ofensiva. Luego puede ejecutar el contenedor y ejecutar los comandos de la ventana acoplable a mano, y mirar los registros de la manera habitual. Por ejemplo, si el Dockerfile es
y se está muriendo en el bar que haría
Luego
fuente