小易说IT 小易说IT

ES + Kibana + Filebeat组合的docker-compose配置

说明:

  • ES 版本:8.15.0(稳定,LogsDB 可用,本地测试)

  • 关闭 SSL、安全认证,仅本地开发验证使用,禁止上生产!

  • Filebeat 采集宿主机 ./logs 目录下日志,同时自带多行合并(Java 堆栈)

  • 目录结构:

elk-demo/
├── docker-compose.yml
├── filebeat/
│   └── filebeat.yml
└── logs/      # 你往这里放日志文件

1. docker-compose.yml

version: '3.8'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
    container_name: es
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - xpack.security.enrollment.enabled=false
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - xpack.monitoring.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es-data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - elk-net
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 20

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - xpack.security.enabled=false
    ports:
      - "5601:5601"
    networks:
      - elk-net
    depends_on:
      elasticsearch:
        condition: service_healthy

  filebeat:
    image: docker.elastic.co/beats/filebeat:8.15.0
    container_name: filebeat
    user: root
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - ./logs:/var/log/app:ro
      - filebeat-data:/usr/share/filebeat/data
    environment:
      - NODE_NAME=local-filebeat
    networks:
      - elk-net
    depends_on:
      elasticsearch:
        condition: service_healthy

volumes:
  es-data:
  filebeat-data:

networks:
  elk-net:

2. filebeat/filebeat.yml

filebeat.inputs:
  - type: filestream
    id: app-log
    paths:
      - /var/log/app/*.log
    # 多行合并:匹配 Java 堆栈(以日期开头的行作为新日志起始行)
    multiline.type: pattern
    multiline.pattern: '^\d{4}-\d{2}-\d{2}'
    multiline.negate: true
    multiline.match: after
    parsers:
      - ndjson:
          overwrite_keys: true
          add_error_key: true

# 全局附加字段
processors:
  - add_fields:
      target: ''
      fields:
        service.name: demo-app
        env: local

# 输出直连ES,使用 data stream(日志标准方式,自动ILM)
output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  index: "logs-demo-app"
  # 开启 data stream
  data_stream:
    enabled: true

# 关闭kibana连接(不需要agent fleet)
setup.kibana:
  enabled: false

# 关闭内置模块(避免自动加载nginx等模块报错)
filebeat.modules:
  - module: none

logging.level: info
logging.to_files: false

3. 启动步骤(复制执行)

# 1. 创建目录
mkdir -p elk-demo/filebeat elk-demo/logs
cd elk-demo

# 2. 上面两个文件分别写入
# 3. 给filebeat配置权限(重要!不然filebeat启动报权限拒绝)
chmod go-w filebeat/filebeat.yml

# 4. 启动
docker compose up -d

# 查看日志
docker compose logs -f filebeat
docker compose logs -f elasticsearch

4. 访问地址

进入 Kibana 之后:

  1. 打开 Discover

  2. 创建数据视图(Data View):匹配 logs-demo-app

  3. 时间字段选择 @timestamp

  4. 往 ./logs 下面丢日志,就能实时看到

5. 测试日志示例(logs/app.log,支持 JSON 和普通文本)

{"@timestamp":"2026-10-21T10:00:00.123Z","log.level":"ERROR","message":"接口调用超时","trace.id":"trace-001","http.path":"/api/order"}