También disponible en: English · Português · Français · العربية
Archivo .dockerignore: generador y comprobador de rutas
Escribe un .dockerignore, comprueba cualquier ruta contra él y mira en paralelo qué habría hecho git con el archivo idéntico.
Qué es un archivo .dockerignore
El .dockerignore vive junto a tu Dockerfile y enumera lo que no debe enviarse al compilador. Todo el contexto de compilación se empaqueta y se entrega antes de que se ejecute la primera instrucción, así que un node_modules olvidado o un directorio .git cuesta tiempo de subida en cada build, acaba dentro de la imagen si algo lo copia, y rompe la caché de capas sin hacer ruido, porque el contexto cambia cada vez que cambian esos archivos.
Se parece exactamente a un .gitignore: un patrón por línea, una almohadilla para los comentarios, un signo de exclamación para hacer excepciones. Ahí está el problema. Los dos archivos los procesa código completamente distinto, y las mismas líneas pueden dar respuestas opuestas. Nadie te avisa, porque ambos archivos son válidos en los dos sitios.
Esta página ejecuta los dos motores a la vez. Escribe tu .dockerignore, indica una ruta, y verás qué decide el comparador de Docker, qué deciden las reglas de git, qué línea fue la responsable en cada caso y —la parte que lo explica todo— con qué ruta coincidió realmente cada uno.
Cómo se usa
- Pega o escribe el archivo. Debajo aparece cada línea con la forma que toma tras la limpieza y cómo se comparará: como cadena exacta, como prefijo, como sufijo o como patrón. Los botones de ejemplo cargan los cuatro casos en los que ambos archivos discrepan, más uno en el que coinciden.
- Indica una ruta. Relativa al contexto de compilación y con barras normales. Marca la casilla si es una carpeta; eso solo le importa a las reglas de git, y la herramienta explica por qué.
- Lee los dos veredictos. Cada panel nombra la línea que decidió y la ruta con la que coincidió. Cuando discrepan, es una diferencia real de comportamiento y no un capricho de la interfaz.
Las cuatro diferencias que pillan a todo el mundo
La primera no se la espera nadie, y la propia batería de pruebas de Docker la deja por escrito. Excluye todo con doble asterisco, vuelve a incluir un directorio con un signo de exclamación, y un archivo que esté dentro de ese directorio sí se envía al compilador. Dale a git las mismas dos líneas y el archivo sigue ignorado, porque git recorre la ruta de arriba abajo y nunca mira dentro de un directorio que ya ha excluido. El comparador de Docker sigue evaluando patrones después de que coincida un antecesor, así que la excepción posterior todavía se aplica. Las mismas dos líneas, resultados opuestos.
La segunda es la que más tiempo de compilación cuesta. Un patrón sin comodines se compara con la ruta por igualdad de cadenas, y con cada directorio padre por turnos; nada más. Así que una línea que diga node_modules excluye el que está en la raíz de tu contexto y ningún otro. La copia anidada dentro de un paquete se empaqueta y se envía en cada build. En un .gitignore esa misma línea coincide a cualquier profundidad, que es justo por lo que el archivo parece estar funcionando. Ponle delante dos asteriscos y una barra y Docker también llega a las anidadas.
La tercera es un carácter que se esfuma. Todos los patrones pasan por la función de limpieza de rutas de Go antes de usarse, y esa función borra la barra final. Así que una línea acabada en barra no se limita aquí a directorios: es el mismo patrón sin la barra, y coincidirá igual de contento con un archivo que se llame así. En git, la barra final es precisamente lo que restringe un patrón a los directorios.
La cuarta es un carácter que no significa nada. La barra inicial se elimina al leer el archivo, y los comentarios del propio código de Docker dicen que las dos formas son equivalentes. En git, la barra inicial ancla el patrón al directorio donde está el archivo, y omitirla es lo que hace que coincida a cualquier profundidad. El mismo carácter: decisivo en un lado, inerte en el otro.
Limitaciones honestas
Esto compara, no compila. Te dice si una ruta se enviaría al compilador; no sabe si el archivo existe, cuánto ocupa realmente tu contexto ni qué hace tu Dockerfile con nada de ello. El Dockerfile y el propio .dockerignore se envían siempre, digan lo que digan los patrones, porque el compilador los necesita.
Las rutas se tratan como separadas por barras normales, que es con lo que trabaja el compilador de Linux. El comportamiento que se reproduce aquí es el del comparador propio de Docker, y conviene decirlo claro: no existe una especificación de este formato. El comparador es la definición, y la documentación no llega a describirlo: los documentos citan una función de la biblioteca estándar de Go cuyas reglas de patrones no tienen comodín recursivo alguno, mientras que la implementación compila cada patrón a una expresión regular y sí lo admite. Veintitrés de los casos de prueba de la propia implementación de referencia dependen de ese comportamiento.
Hay una regla que parece una diferencia y no lo es. Docker pasa los corchetes tal cual a una expresión regular, así que una clase de caracteres se niega con un acento circunflejo en lugar del signo de exclamación que usaría un glob de shell; pero git también acepta el circunflejo, de modo que ambas formas se comportan igual en los dos lados. Se menciona porque es lo obvio de suponer, y suponerlo sería un error.
Por último, un comentario solo cuenta como comentario si la almohadilla es el primerísimo carácter de la línea. Métele un solo espacio delante y deja de ser un comentario para convertirse en un patrón que coincide con un archivo llamado así. Ese orden viene directamente de la implementación de referencia, que busca la almohadilla antes de recortar los espacios.
¿Por qué es gratis?
Comparar una ruta con una lista de patrones son unos cientos de líneas de manejo de cadenas, y tu navegador lo hace mientras escribes. Ningún servidor ve tu archivo, así que no hay nada que medir ni ninguna cuenta que crear.
No se sube nada. Lo que pegues se queda en esta pestaña.