Docker启动statsd Ruby容器失败报No such file or directory错误
问题根因
容器启动报': No such file or directory由两个问题单独或共同导致:
- CMD指令路径配置错误:Dockerfile中已经通过
WORKDIR $app_root$app_name将工作目录切换到应用部署路径/var/code/simplebank/statsd-agent,但CMD指令重复拼接了全路径,实际尝试执行的文件路径为/var/code/simplebank/statsd-agent/var/code/simplebank/statsd-agent/statsd-agent.rb,该路径不存在。 - 脚本换行符格式错误:如果在Windows环境下编辑
statsd-agent.rb,文件会默认使用CRLF(Windows格式)换行,脚本首行shebang#!/usr/bin/env ruby末尾会携带不可见的\r回车符,系统会尝试查找名为ruby\r的解释器,因\r触发终端光标回退行首的效果,原本完整的报错信息/usr/bin/env: 'ruby\r': No such file or directory会被覆盖,最终仅显示': No such file or directory。
修复方案
- 修正Dockerfile配置
- 移除CMD中重复的路径拼接,直接使用工作目录下的相对路径,同时改用exec格式的CMD避免shell解析问题
- 直接写死EXPOSE的端口(EXPOSE指令不支持ARG变量展开)
- 构建阶段增加换行符转换逻辑,兼容本地编辑的换行符问题
- 可选:修正Gemfile源地址,移除冗余的www前缀避免安装依赖时的跳转问题
修正后的Dockerfile参考:
FROM alpine:3.6 MAINTAINER simplebank <engineering@simplebenak.book> ENV TERM xterm ENV LANG=en_GB.UTF-8 ENV HOME /root/ ENV app_root=/var/code/simplebank/ ENV app_name=statsd-agent ENV REFRESHED_AT 2016-11-25 COPY . $app_root$app_name RUN apk update && apk --update add \ ruby \ ruby-irb \ ruby-json \ ruby-rake \ ruby-bigdecimal \ ruby-io-console \ libstdc++ \ tzdata \ ca-certificates \ bash \ dos2unix RUN gem install bundler --no-ri --no-rdoc \ && cd $app_root$app_name ; dos2unix *.rb ; bundle install \ && rm -rf /var/cache/apk/* RUN chown -R nobody:nogroup $app_root$app_name RUN chmod +x $app_root$app_name/statsd-agent.rb USER nobody EXPOSE 8125/udp WORKDIR $app_root$app_name CMD ["./statsd-agent.rb"]
- 统一本地文件换行符格式
所有构建相关文件(Dockerfile、Gemfile、statsd-agent.rb)建议使用Unix标准的LF换行符,不要使用Windows的CRLF换行符:- 本地编辑时可在VS Code等编辑器右下角点击换行符类型,切换为LF
- 使用Git管理代码时,执行
git config --global core.autocrlf input避免拉取代码时自动将换行符转为CRLF
- 修正启动命令的端口映射
StatsD服务使用UDP协议,启动容器时需指定协议类型,否则端口映射不生效:
docker run -dp 8125:8125/udp statsd_service
验证步骤
- 执行无缓存构建避免旧层干扰:
docker build --no-cache -t statsd_service . - 启动容器后执行
docker logs <容器ID>,无报错即表示启动成功,向8125端口发送UDP数据时会正常打印StatsD指标日志。
内容的提问来源于stack exchange,提问作者Retko
相关产品推荐
相关产品推荐

