docker-compose部署Prometheus无法加载配置及采集指标问题排查
问题:Docker部署Prometheus v2.36.2无法加载自定义配置、无法采集宿主机Spring Boot指标、host网络模式下9090端口不可访问
问题复现配置与现象
初始部署配置
初始docker-compose.yaml配置如下:
version: '3.7' networks: back-tier: services: prometheus: image: prom/prometheus:v2.36.2 volumes: - ./prometheus/:/prometheus/ ports: - 9090:9090 networks: - back-tier restart: always
本地./prometheus/目录下存放自定义prometheus.yml,目标是采集宿主机8080端口Spring Boot应用的/actuator/prometheus端点指标,配置内容:
# Sample Prometheus config # This assumes that your Prometheus instance can access this application on localhost:8080 global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). scrape_configs: - job_name: 'spring boot scrape' metrics_path: '/actuator/prometheus' scrape_interval: 5s static_configs: - targets: ['localhost:8080']
初始启动现象:
- 直接访问
http://localhost:8080/actuator/prometheus可正常返回greeting_time_seconds等自定义指标 - 访问
http://localhost:9090/无法查询到上述自定义指标 - 访问
http://localhost:9090/config发现Prometheus加载的是默认配置,未读取本地自定义配置文件
第一次调整后的现象
将volumes挂载路径修改为- ./prometheus/:/etc/prometheus/后:
- 访问
/config接口确认自定义配置已成功加载 - Prometheus UI中仍无法查询到Spring Boot应用的
greeting_time_seconds自定义指标,仅能展示Prometheus自身的少量内置指标
第二次调整后的现象
注释自定义back-tier网络,添加network_mode: "host"配置,修改后docker-compose.yaml如下:
version: '3.7' #networks: # back-tier: services: prometheus: image: prom/prometheus:v2.36.2 volumes: - ./prometheus/:/etc/prometheus/ ports: - 9090:9090 # networks: # - back-tier network_mode: "host" restart: always
重新启动后容器运行状态正常,但http://localhost:9090地址无法访问。
根因分析与解决方案
各阶段问题根因
- 初始阶段配置不加载:
prom/prometheus官方镜像默认读取配置的路径为/etc/prometheus/prometheus.yml,初始配置将本地目录挂载到/prometheus/路径,镜像不会从该路径加载自定义配置,因此始终加载内置默认配置。 - 配置加载后无法采集指标:Docker容器内的
localhost指向容器自身的网络命名空间,并非宿主机网络。配置中target写localhost:8080实际是尝试访问Prometheus容器内部的8080端口,该端口没有运行Spring Boot应用,因此采集失败,只能拿到Prometheus自身的指标。 - host网络模式下9090无法访问:
- 当配置
network_mode: "host"时,Docker会直接使用宿主机网络栈,此时compose中配置的ports端口映射规则完全不生效 - 非Linux环境(Windows/Mac的Docker Desktop)对host网络模式的支持存在兼容问题,容器服务不会直接映射到宿主机localhost
- 部分情况下Prometheus默认启动参数仅绑定127.0.0.1:9090,或宿主机防火墙拦截了9090端口的访问
- 当配置
最终可落地配置(推荐方案,无需使用host网络模式)
不需要启用host网络,通过Docker内置的DNS域名即可访问宿主机服务,兼容性更好,步骤如下:
- 修改prometheus.yml中的采集target,将
localhost:8080替换为适合当前环境的宿主机地址:- 所有Docker 20.10+版本通用写法:
host.docker.internal:8080 - Linux环境旧版本Docker可替换为docker0网桥默认网关地址,通常为
172.17.0.1:8080
修改后的scrape_configs片段:
scrape_configs: - job_name: 'spring boot scrape' metrics_path: '/actuator/prometheus' scrape_interval: 5s static_configs: - targets: ['host.docker.internal:8080'] - 所有Docker 20.10+版本通用写法:
- 修改docker-compose.yaml,移除host网络配置,正确挂载配置文件和数据目录,添加宿主机域名映射兼容旧版本Docker,最终配置如下:
version: '3.7' networks: back-tier: services: prometheus: image: prom/prometheus:v2.36.2 volumes: # 直接挂载配置文件到镜像默认配置路径,避免目录挂载覆盖其他内置配置 - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml # 挂载采集数据目录,避免容器重启数据丢失 - ./prometheus/data:/prometheus ports: - 9090:9090 networks: - back-tier # 兼容旧版本Docker添加宿主机域名映射 extra_hosts: - "host.docker.internal:host-gateway" # 显式指定启动参数,确保监听所有网卡地址、配置和存储路径正确 command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.listen-address=0.0.0.0:9090' restart: always - 提前创建本地数据目录并配置权限,避免Prometheus无写入权限报错:
mkdir -p ./prometheus/data chmod -R 777 ./prometheus/data - 清理旧容器后重新启动:
docker-compose down docker-compose up -d
若坚持使用host网络模式,需删除compose中的
ports配置段,保留上述command中--web.listen-address=0.0.0.0:9090配置,仅Linux环境可正常使用该模式,Windows/Mac的Docker Desktop存在已知兼容问题不推荐使用。
验证步骤
- 启动后访问
http://localhost:9090/config,确认自定义配置已加载 - 访问
http://localhost:9090/targets,确认spring boot scrape任务的端点状态为UP - 进入Metrics查询页面,搜索
greeting_time_seconds指标,确认可以正常查询到数据
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

