Docker容器运行失败:setup.sh找不到,求跨平台适配方案
解决Windows环境下Docker容器中Shell脚本执行失败及Nodemon热更新无效问题
问题概述
项目在macOS/Linux系统上通过Docker Compose运行正常,但Windows环境执行docker compose up时,Node应用容器启动失败,日志报错:bash: line 1: ./setup.sh: cannot execute: required file not found。进入容器确认setup.sh存在,但执行仍提示找不到;同时Nodemon监听文件修改后无反应,将文件换行符从CRLF改为LF后,两个问题均解决。需要实现项目跨平台兼容的方案。
解决方案
1. 通过Git统一换行符(根源解决)
在项目根目录创建.gitattributes文件,强制指定脚本、JS等文件使用LF换行符,确保团队成员无论在什么系统下拉取、提交代码,文件换行符始终一致:
*.sh text eol=lf *.js text eol=lf *.cjs text eol=lf *.json text eol=lf
- 原理:该文件告诉Git,匹配的文件类型在检出时自动转换为LF,提交时也保持LF格式,避免Windows系统自动转成CRLF。
2. Docker启动命令兼容CRLF(临时兼容方案)
如果无法修改Git配置,可在Docker Compose的启动命令中先转换脚本的换行符,再执行:
修改docker-compose.yml中app服务的command:
command: bash -c "sed -i 's/\r$//' ./setup.sh && chmod +x ./setup.sh && ./setup.sh"
- 原理:
sed -i 's/\r$//' ./setup.sh会移除文件每行末尾的\r(CR字符),将CRLF转换为LF,确保bash能正确解析脚本。
3. 编辑器层面强制LF(团队协作辅助)
在项目根目录创建.vscode/settings.json(针对VS Code用户),设置项目默认换行符为LF:
{ "files.eol": "\n" }
- 作用:团队成员打开项目时,编辑器自动使用LF保存文件,从本地编辑阶段避免生成CRLF格式的文件。
4. Nodemon配置优化
确保Nodemon能正确检测文件变化,可在项目根目录创建nodemon.json:
{ "watch": ["app/**/*.js", "config/**/*.js"], "ext": "js,mjs,cjs,json", "legacyWatch": false }
- 配合前面的换行符统一方案,Nodemon就能正常监听文件内容修改,触发热更新。
问题原因说明
- Linux容器中的bash解释器要求Shell脚本使用LF换行符,若文件是CRLF格式,bash会将每行末尾的
\r视为命令的一部分,导致解析错误,表现为“文件未找到”。 - Nodemon在检测文件变化时,若文件因CRLF/LF转换导致内容的隐性变化(而非代码修改),可能会忽略真正的代码更新;统一为LF后,文件修改能被正确识别。
内容的提问来源于stack exchange,提问作者msrajwat298
相关产品推荐
相关产品推荐

