Docker容器中启动FSCrawler+Elasticsearch/Kibana遇NoSuchElementException错误
问题:Docker部署FSCrawler、Elasticsearch和Kibana时,FSCrawler抛出NoSuchElementException异常
启动docker compose up后,FSCrawler容器输出以下异常:
fscrawler | Exception in thread "main" java.util.NoSuchElementException fscrawler | at java.base/java.util.Scanner.throwFor(Scanner.java:937) fscrawler | at java.base/java.util.Scanner.next(Scanner.java:1478) fscrawler | at fr.pilato.elasticsearch.crawler.fs.cli.FsCrawlerCli.main(FsCrawlerCli.java:254)
当前配置文件
docker-compose.yml
--- version: "2.2" services: setup: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs user: "0" command: > bash -c ' if [ x${ELASTIC_PASSWORD} == x ]; then echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; exit 1; elif [ x${KIBANA_PASSWORD} == x ]; then echo "Set the KIBANA_PASSWORD environment variable in the .env file"; exit 1; fi; if [ ! -f certs/ca.zip ]; then echo "Creating CA"; bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; unzip config/certs/ca.zip -d config/certs; fi; if [ ! -f certs/certs.zip ]; then echo "Creating certs"; echo -ne \ "instances:\n"\ " - name: elasticsearch\n"\ " dns:\n"\ " - elasticsearch\n"\ " - localhost\n"\ " ip:\n"\ " - 127.0.0.1\n"\ > config/certs/instances.yml; bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; unzip config/certs/certs.zip -d config/certs; fi; echo "Setting file permissions" chown -R root:root config/certs; find . -type d -exec chmod 750 \{\} \;; find . -type f -exec chmod 640 \{\} \;; echo "Waiting for Elasticsearch availability"; until curl -s --cacert config/certs/ca/ca.crt https://elasticsearch:9200 | grep -q "missing authentication credentials"; do sleep 30; done; echo "Setting kibana_system password"; until curl -s -X POST --cacert config/certs/ca/ca.crt -u elastic:${ELASTIC_PASSWORD} -H "Content-Type: application/json" https://elasticsearch:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; echo "All done!"; ' healthcheck: test: ["CMD-SHELL", "[ -f config/certs/elasticsearch/elasticsearch.crt ]"] interval: 1s timeout: 5s retries: 120 elasticsearch: depends_on: setup: condition: service_healthy image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs - esdata:/usr/share/elasticsearch/data ports: - ${ES_PORT}:9200 environment: - node.name=elasticsearch - cluster.name=${CLUSTER_NAME} - cluster.initial_master_nodes=elasticsearch - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - bootstrap.memory_lock=true - xpack.security.enabled=true - xpack.security.http.ssl.enabled=true - xpack.security.http.ssl.key=certs/elasticsearch/elasticsearch.key - xpack.security.http.ssl.certificate=certs/elasticsearch/elasticsearch.crt - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.http.ssl.verification_mode=certificate - xpack.security.transport.ssl.enabled=true - xpack.security.transport.ssl.key=certs/elasticsearch/elasticsearch.key - xpack.security.transport.ssl.certificate=certs/elasticsearch/elasticsearch.crt - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.verification_mode=certificate - xpack.license.self_generated.type=${LICENSE} mem_limit: ${MEM_LIMIT} ulimits: memlock: soft: -1 hard: -1 healthcheck: test: [ "CMD-SHELL", "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", ] interval: 10s timeout: 10s retries: 120 kibana: depends_on: elasticsearch: condition: service_healthy image: docker.elastic.co/kibana/kibana:${STACK_VERSION} volumes: - certs:/usr/share/kibana/config/certs - kibanadata:/usr/share/kibana/data ports: - ${KIBANA_PORT}:5601 environment: - SERVERNAME=kibana - ELASTICSEARCH_HOSTS=https://elasticsearch:9200 - ELASTICSEARCH_USERNAME=kibana_system - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt - ENTERPRISESEARCH_HOST=http://enterprisesearch:${ENTERPRISE_SEARCH_PORT} mem_limit: ${MEM_LIMIT} healthcheck: test: [ "CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'", ] interval: 10s timeout: 10s retries: 120 # FSCrawler fscrawler: image: dadoonet/fscrawler:$FSCRAWLER_VERSION container_name: fscrawler restart: always volumes: - ../../test-documents/src/main/resources/documents/:/tmp/es:ro - ${PWD}/config:/root/.fscrawler - ${PWD}/logs:/usr/share/fscrawler/logs depends_on: elasticsearch: condition: service_healthy ports: - ${FSCRAWLER_PORT}:8080 command: fscrawler idx --restart --rest volumes: certs: driver: local esdata: driver: local kibanadata: driver: local
.env
# FSCrawler Settings FSCRAWLER_VERSION=2.10-SNAPSHOT FSCRAWLER_PORT=8080 # Password for the 'elastic' user (at least 6 characters) ELASTIC_PASSWORD=changeme # Password for the 'kibana_system' user (at least 6 characters) KIBANA_PASSWORD=changeme # Version of Elastic products STACK_VERSION=8.6.2 # Set the cluster name CLUSTER_NAME=docker-cluster # Set to 'basic' or 'trial' to automatically start the 30-day trial #LICENSE=basic LICENSE=trial # Port to expose Elasticsearch HTTP API to the host ES_PORT=9200 # Port to expose Kibana to the host KIBANA_PORT=5601 # Enterprise Search settings ENTERPRISE_SEARCH_PORT=3002 # Increase or decrease based on the available host memory (in bytes) MEM_LIMIT=1073741824 # Project namespace (defaults to the current folder name if not set) COMPOSE_PROJECT_NAME=fscrawler
原因分析
这个异常是因为FSCrawler启动时尝试从交互式控制台读取Elasticsearch的认证信息(如用户名、密码),但Docker容器默认以非交互式模式运行,没有输入源,导致Scanner类抛出NoSuchElementException。
解决方案
1. 提前生成FSCrawler配置文件
在本地运行交互式容器,引导生成包含Elasticsearch认证和SSL配置的文件:
docker run -it -v ${PWD}/config:/root/.fscrawler dadoonet/fscrawler:$FSCRAWLER_VERSION fscrawler idx
按照提示输入以下信息:
- Elasticsearch地址:
https://elasticsearch:9200 - 用户名:
elastic - 密码:
changeme - 是否启用SSL:
Y - CA证书路径:后续挂载后设置为
/usr/share/fscrawler/certs/ca/ca.crt
生成的配置文件会保存在本地config/idx目录下。
2. 修改FSCrawler容器配置
在docker-compose.yml的FSCrawler服务中添加certs卷挂载,以便容器访问Elasticsearch的CA证书:
fscrawler: image: dadoonet/fscrawler:$FSCRAWLER_VERSION container_name: fscrawler restart: always volumes: - ../../test-documents/src/main/resources/documents/:/tmp/es:ro - ${PWD}/config:/root/.fscrawler - ${PWD}/logs:/usr/share/fscrawler/logs - certs:/usr/share/fscrawler/certs # 添加CA证书卷挂载 depends_on: elasticsearch: condition: service_healthy ports: - ${FSCRAWLER_PORT}:8080 command: fscrawler idx --restart --rest
3. 完善FSCrawler配置文件
编辑config/idx/_settings.json,补充SSL认证相关配置:
{ "name": "idx", "fs": { "url": "/tmp/es", "update_rate": "15m", "remove_deleted": true, "index_content": true }, "elasticsearch": { "nodes": [ { "url": "https://elasticsearch:9200" } ], "username": "elastic", "password": "changeme", "ssl": { "enabled": true, "certificate_authorities": ["/usr/share/fscrawler/certs/ca/ca.crt"] } }, "rest": { "enabled": true, "port": 8080 } }
4. 重新启动容器
执行docker compose up -d,FSCrawler会读取配置文件中的信息,无需交互式输入即可连接Elasticsearch,解决异常问题。
内容的提问来源于stack exchange,提问作者lenchester
相关产品推荐
相关产品推荐

