如何在Docker Compose的ELK栈中使用Entrypoint.sh?构建报错求助
解决Kibana Docker构建报错与Elasticsearch等待启动问题
咱们一步步拆解问题,先搞清楚为啥会报错,再逐个解决:
报错根源分析
你碰到的两个核心问题:
exec format error:这大概率是你的entrypoint.sh脚本没加正确的解释器声明(也就是开头的#!/bin/sh),或者脚本用了Windows的CRLF换行符,Linux容器识别不了这种格式。- 构建时
RUN chmod返回非零:虽然看起来是权限设置失败,但更关键的是你Dockerfile的指令顺序搞反了——得先给脚本加执行权限,再设置ENTRYPOINT,不过这不是触发exec format error的主因。
具体修复步骤
1. 调整Dockerfile的指令顺序
把权限设置的RUN命令移到ENTRYPOINT前面,确保脚本先获得执行权限,再被设为启动入口:
FROM docker.elastic.co/kibana/kibana:6.6.2 COPY ./config/kibana.yml /opt/kibana/config/kibana.yml COPY entrypoint.sh entrypoint.sh USER root # 先给脚本加执行权限,再配置启动入口 RUN chmod +x entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
另外,没必要用sh包裹脚本路径,只要脚本有正确的开头声明,直接写脚本路径就行。
2. 修复entrypoint.sh脚本的问题
给脚本加上解释器声明,同时修正nc命令的写法(有些版本的nc不支持-q参数,换兼容性更好的写法):
#!/bin/sh # 等待Elasticsearch容器就绪 echo "Waiting for Elasticsearch to be ready..." while ! nc -z elasticsearch 9200; do sleep 1 echo "Still waiting for Elasticsearch..." done echo "Elasticsearch is up! Starting Kibana now." exec /usr/local/bin/kibana-docker
- 开头加
#!/bin/sh:告诉容器用哪个shell来执行这个脚本 - 用
nc -z:只检查端口是否开放,比-q兼容性强很多 - 用
exec启动Kibana:让Kibana进程成为容器的PID 1,这样它能正确接收停止信号,避免容器无法正常退出的问题
3. 检查脚本的换行符
如果你的脚本是在Windows下写的,大概率是CRLF换行符,Linux容器跑的时候会报错。可以用这个命令转换成Unix的LF换行符:
sed -i 's/\r$//' entrypoint.sh
或者在VS Code这类编辑器里,直接把换行符设置成Unix风格。
额外优化建议
除了entrypoint脚本,在Docker Compose里加上健康检查和依赖声明,双重保障Kibana在Elasticsearch真正就绪后再启动:
version: '3' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:6.6.2 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9200"] interval: 10s timeout: 10s retries: 5 kibana: build: ./kibana depends_on: - elasticsearch environment: ELASTICSEARCH_URL: http://elasticsearch:9200
depends_on保证Elasticsearch先启动,健康检查则确保它真正能提供服务了,Kibana才会开始自己的启动流程。
内容的提问来源于stack exchange,提问作者Penguen
相关产品推荐
相关产品推荐

