|

Exec entrypoint.sh no such file: causas y solución

En pocas palabras: El error exec /entrypoint.sh: no such file or directory aparece porque el kernel no encuentra el intérprete del shebang, que con finales de línea CRLF queda como /bin/sh\r. Se arregla pasando el script a LF con sed y marcándolo ejecutable con git update-index –chmod=+x.

El error exec /entrypoint.sh: no such file or directory en Docker aparece cuando el kernel no encuentra el intérprete de la línea #!, no el script. La causa más común son los finales de línea CRLF de un checkout en Windows. Se corrige con LF, un shebang válido y el bit ejecutable.

Un shebang es la secuencia #! al inicio de un script, que le indica al cargador del sistema qué intérprete ejecutar, según la entrada de Wikipedia sobre el shebang. CRLF es el final de línea de Windows (retorno de carro más salto de línea), mientras que Linux usa solo LF. Si el intérprete queda escrito como /bin/sh\r, el exec falla y Docker nombra a tu script en el mensaje.

En 30 segundos

  • El archivo que falta es el intérprete (por ejemplo /bin/sh\r), no tu entrypoint.sh.
  • CRLF da “no such file or directory”; sin shebang o con BOM UTF-8 da “exec format error”; modo Git 100644 da “permission denied”.
  • El arreglo manual son cinco comandos: file, git ls-files -s, sed, una regla en .gitattributes y git update-index --chmod=+x.
  • La regla *.sh text eol=lf en .gitattributes es la que evita que el problema vuelva.

¿Qué archivo falta cuando el entrypoint.sh sí existe?

Falta el intérprete, no el script. Al ejecutar un script, execve() lee la línea #! y lanza el programa que nombra. Con CRLF, ese nombre arrastra un \r invisible y el kernel busca /bin/sh\r, que no existe. Docker igual informa el nombre de tu script, y por eso ls -l /entrypoint.sh dentro de la imagen te muestra el archivo y no sirve para diagnosticar, según el artículo de dev.to publicado el 9 de octubre de 2026.

Wikipedia describe el mismo fenómeno: algunos sistemas interpretan el retorno de carro como parte del comando del intérprete, típicamente en scripts editados con saltos de línea DOS.

¿Cuáles son las causas que rompen el shebang y qué error da cada una?

Son cuatro, y cada una produce un mensaje distinto. Esta tabla sale de la fuente en dev.to.

Qué hay en el archivoQué ve el kernelError que obtenés
CRLF con #!/bin/shIntérprete /bin/sh\rno such file or directory
CRLF con #!/usr/bin/env bashUn programa llamado bash\r/usr/bin/env: 'bash\r': No such file or directory
Sin shebang, o BOM UTF-8 antes de #!No hay #!exec format error
Modo Git 100644Archivo no ejecutablepermission denied
exec entrypoint.sh no such file diagrama explicativo

El origen típico es un checkout en Windows con core.autocrlf=true. docker build envía ese árbol de trabajo con CRLF y COPY lo deja tal cual en la imagen. Según la documentación de gitattributes, si el atributo text no está especificado, Git decide con core.autocrlf; y si text está activo sin esas variables, el valor por defecto es eol=crlf en Windows.

Eso sí: el BOM es raro. Wikipedia explica que los bytes 0xEF 0xBB 0xBF antes del shebang pueden impedir que se ejecute el intérprete.

¿Cómo se corrige exec entrypoint.sh no such file paso a paso?

Primero diagnosticás, después convertís a LF, fijás la regla en Git y marcás el archivo como ejecutable. Estos son los comandos que da la fuente:

file entrypoint.sh
# busca "with CRLF line terminators"
git ls-files -s entrypoint.sh
# 100644 = no ejecutable
sed -i 's/\r$//' entrypoint.sh
echo '*.sh text eol=lf' >> .gitattributes && git add --renormalize .
git update-index --chmod=+x entrypoint.sh
  • Diagnóstico con file y git ls-files. Si file dice “with CRLF line terminators” o Git muestra 100644, ya tenés dos culpables.
  • Conversión con sed. Borra el \r al final de cada línea. Si trabajás en VS Code, cambiar CRLF por LF en la barra de estado hace lo mismo.
  • Regla en .gitattributes. *.sh text eol=lf fuerza LF en el árbol de trabajo. La documentación de Git trae justamente este ejemplo (*.sh text eol=lf) y recomienda git add --renormalize . para normalizar archivos ya versionados.
  • Bit ejecutable. git update-index --chmod=+x corrige el modo en el índice. La alternativa es hacerlo en el Dockerfile con chmod +x o COPY --chmod=755.

La regla de .gitattributes es la parte que importa. Sin ella, el próximo que clone el repo en Windows con core.autocrlf=true te devuelve los CRLF, y el contenedor vuelve a morir con el mismo mensaje.

¿Cómo verificar que la imagen quedó bien antes de desplegar?

Mirá el primer renglón del script dentro de la imagen y fijate si termina en \r. Esto es una sugerencia editorial nuestra, no figura en la fuente y no la medimos en este artículo. Te puede servir nuestra cobertura de automatizar estas comprobaciones con Taskfile.

docker run --rm --entrypoint sh tu-imagen -c "head -n 1 /entrypoint.sh | od -c"

Si ves \r \n al final de la línea, hay CRLF. Con cat -A el equivalente es ver ^M$. Cuando la salida muestre solo \n, pasá a revisar permisos e intérprete.

Revisar lo que quedó adentro de la imagen, y no lo que ves en tu carpeta, es lo que corta el bucle de “en mi máquina el archivo está perfecto”.

¿Sirve EntryCheck para detectar el problema en el editor?

EntryCheck es una extensión gratuita de VS Code (licencia MIT) que sigue los scripts desde el Dockerfile y señala el problema antes de buildear. La creó el mismo autor del artículo de dev.to, así que es una herramienta de un tercero que no pudimos validar de forma independiente. Tomalo como una opción más.

Según el autor, sigue ENTRYPOINT, CMD y RUN (a través de COPY y WORKDIR), entrypoint y command de compose, run: de GitHub Actions, script: de GitLab CI, scripts de package.json y hooks de Husky. Sus reglas:

  • EC001: finales de línea CRLF.
  • EC002: shebang ausente o no absoluto en un script que se ejecuta directo.
  • EC003: BOM UTF-8 antes del shebang.
  • EC004: modo 100644 en Git, salvo que el Dockerfile ya use chmod +x o COPY --chmod=755.
  • EC005: falta una regla eol para *.sh en .gitattributes.

El autor afirma que no usa red ni telemetría y que el chequeo de Git corre solo en workspaces de confianza. Se instala con code --install-extension jaytankdev.entrycheck.

Tiene límites que el propio autor reconoce. No verifica que el intérprete exista en la imagen (un #!/bin/bash en Alpine sigue fallando) y no sigue el build.context de compose ni rutas con variables. Lo que estos datos no permiten concluir es cuánto se reduce el problema en equipos reales, porque la fuente no trae mediciones. Sobre eso hablamos en cómo Docker organiza las capas del filesystem.

Errores comunes al arreglar este error

  • Convertir a LF solo en tu máquina. Sin la regla en .gitattributes, el arreglo se pierde en el siguiente clon. Corrección: commiteá la regla y corré git add --renormalize ..
  • Usar #!/bin/bash en una imagen Alpine. Si la imagen no trae bash, el error sigue idéntico aunque el archivo esté en LF. Corrección: usá #!/bin/sh o instalá bash en la imagen.
  • Arreglar CRLF y olvidar el modo 100644. Pasás de “no such file” a “permission denied”. Corrección: git update-index --chmod=+x o COPY --chmod=755.
  • Pasar por alto el BOM. El archivo parece normal, pero sin #! en el primer byte el error es “exec format error”. Corrección: guardá el script en UTF-8 sin BOM.

Preguntas Frecuentes

¿Cómo convierto un script de CRLF a LF para Docker?

Ejecutá sed -i 's/\r$//' entrypoint.sh, que elimina el retorno de carro al final de cada línea. En VS Code podés cambiar CRLF por LF desde la barra de estado. Después agregá *.sh text eol=lf a .gitattributes para que no vuelva.

¿Qué diferencia hay entre “no such file or directory”, “exec format error” y “permission denied”?

“No such file or directory” indica que el intérprete del shebang no existe, típicamente por un \r de CRLF. “Exec format error” indica que falta el shebang o que hay un BOM UTF-8 antes de él. “Permission denied” indica que el archivo no tiene el bit ejecutable, como el modo Git 100644.

¿Qué es el shebang y por qué rompe el contenedor?

El shebang es la secuencia #! seguida de la ruta de un intérprete, en la primera línea del script. Rompe el contenedor cuando esa línea tiene un carácter invisible, como el \r de CRLF, porque el kernel busca un intérprete con ese nombre exacto y no lo encuentra.

¿Cómo evito que Git en Windows cambie los saltos de línea de mis .sh?

Agregá *.sh text eol=lf a .gitattributes y corré git add --renormalize .. Según la documentación de Git, eol=lf usa en el directorio de trabajo los mismos finales de línea que en el índice, sin importar core.autocrlf.

Conclusión

El mensaje de Docker nombra a tu script, pero el archivo que falta es el intérprete. Antes de tocar el Dockerfile, corré file entrypoint.sh y git ls-files -s entrypoint.sh: en dos comandos descartás CRLF y el modo 100644.

Después fijá *.sh text eol=lf en .gitattributes, porque ese commit es lo que protege al resto del equipo. Y si usás Alpine, revisá que el intérprete del shebang exista en la imagen, algo que ni la solución manual ni EntryCheck resuelven por vos.

Fuentes

Te puede interesar...