Docker容器无法执行migrate.sh:文件存在却提示找不到
以下是几种常见导致该错误的原因及对应解决办法:
脚本Shebang行错误或缺失
脚本执行时需要通过开头的#!指定解释器,如果这一行缺失、写错路径(比如用了#!/usr/bin/bash但容器基础镜像里只有/bin/bash),系统会找不到对应的执行程序,进而抛出类似"no such file or directory"的错误。
解决:检查migrate.sh开头的shebang,改成容器内存在的shell路径。可以先进入容器执行which sh或which bash确认路径,比如改成#!/bin/sh(几乎所有Linux基础镜像都包含)。脚本使用Windows换行符(CRLF)
如果在Windows环境下编写脚本,默认换行符是CRLF,而Linux容器只识别LF换行符。执行时系统会把行尾的\r当成文件名的一部分,实际寻找的是./migrate.sh\r,自然找不到文件。
解决:用dos2unix migrate.sh转换脚本格式,或者在编辑器中设置为LF换行(比如VS Code右下角可切换换行符类型)。也可以在容器内执行cat -A migrate.sh查看,行尾显示^M$就说明是CRLF格式。工作目录不匹配
你使用./migrate.sh是相对当前工作目录的路径,但容器启动时的工作目录可能不是脚本所在的目录。比如你把脚本复制到了/app/migration,但容器的WORKDIR设置为/app,那./migrate.sh就指向/app/migrate.sh,而不是实际的脚本位置。
解决:在docker-compose.yml中使用绝对路径执行脚本,比如/app/migration/migrate.sh up;或者在Dockerfile中设置WORKDIR /app/migration,确保启动时的工作目录是脚本所在路径;也可以用命令组合:cd /app/migration && ./migrate.sh up。执行权限未正确生效
即使你手动赋予了执行权限,也可能因为镜像构建时的命令顺序或COPY参数问题导致权限丢失。比如先复制文件再设置权限,但COPY操作可能覆盖了权限;或者基础镜像的umask限制了文件权限。
解决:在Dockerfile中确保复制文件后执行chmod +x /path/to/migrate.sh;或者使用Docker 17.09+支持的COPY --chmod=755参数直接设置权限:COPY --chmod=755 migrate.sh /app/migration/。可以进入容器执行ls -l migrate.sh确认权限是否包含执行位(即权限字符串中有x,比如-rwxr-xr-x)。
内容的提问来源于stack exchange,提问作者pizhlo

