Self-hosted service
dadoonet/fscrawler avatar
dadoonet/fscrawler

FSCrawler for indexing binary documents in Elasticsearch

Elasticsearch File System Crawler (FS Crawler)

1,455 stars308 forksJavaApache-2.0

At a glance

What is it?
FSCrawler is a Java-based crawler for indexing binary documents from local or remote file systems into Elasticsearch. Its Docker quick start is direct, but crawler configuration, Elasticsearch version pairing, and snapshot images require deliberate selection.
Who is it for?
Adopt FSCrawler when binary files already live in file systems that the crawler can access and Elasticsearch is the intended search destination. Do not choose it merely to upload arbitrary files through a browser or operate without persistent crawler configuration.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why FSCrawler targets binary document collections

FSCrawler addresses a specific gap between ordinary file storage and text search in Elasticsearch. Directories commonly contain PDFs, Open Office files, and MS Office files whose contents are not immediately available to ordinary file-based indexing. FSCrawler crawls a local file system or mounted drive, indexes new files, updates existing documents, and removes old ones. Its intended audience is an Elasticsearch user who needs searchable document collections rather than someone looking only for a file transfer utility.

The README also lists remote file systems accessed over SSH or FTP, plus a REST interface that can be used to upload binary documents to Elasticsearch. That range makes FSCrawler relevant to users combining several storage locations, although it does not mean every source or destination is equally convenient. The quick start concentrates on a local directory mounted into a Docker container. SSH, FTP, and REST are listed as supported modes, but their settings are not reproduced in the README.

FSCrawler is primarily a Java project. The repository layout separates its code into areas including `core`, `cli`, `distribution`, `rest`, `elasticsearch-client`, `kibana-client`, `framework`, `settings`, `plugins`, and `tika`. These names identify distinct concerns for crawling and document processing, command-line use, Elasticsearch integration, REST access, configuration, and extensions. The repository also includes integration tests, test documents, release scripts, and Docker-related distribution work. That organization points to an ingestion system with multiple integration surfaces rather than a small script that copies filenames into Elasticsearch.

How FSCrawler moves files into Elasticsearch

The documented quick start establishes a concrete data path. Files begin in a directory such as `~/resumes`, Docker mounts that directory read-only at `/tmp/es`, and FSCrawler receives the Elasticsearch location through `FSCRAWLER_ELASTICSEARCH_URLS`. The crawler processes the mounted documents and places them behind the `fscrawler` alias. Kibana then queries that alias for document totals, text matches, or groupings based on `file.content_type`.

The source directory is mounted as read-only in the Docker command. That boundary fits indexing because the crawler can consume documents without requiring write access to the originals. The command separately mounts `~/.fscrawler` at `/root/.fscrawler`, preserving crawler state outside the container. According to the README, job settings are written to `~/.fscrawler/fscrawler/_settings.yaml`, so removing the container does not necessarily remove its persisted job configuration.

FSCrawler uses an Elasticsearch API key passed through `FSCRAWLER_ELASTICSEARCH_API_KEY`. The `.env` file created by the Elasticsearch startup command provides `ES_LOCAL_API_KEY`, which is expanded into that environment variable when Docker starts the crawler. Authentication and endpoint configuration are explicit deployment inputs rather than hidden parts of the quick start.

The listed update and removal behavior indicates that FSCrawler maintains indexed representations as a source changes. The README does not specify the change-detection algorithm, crawl scheduling controls, retry policy, or exact timing of deletions. Those details need verification against the linked tutorial before they are treated as synchronization guarantees.

Docker quick start for the first FSCrawler crawl

The README's first step starts Elasticsearch and Kibana with Elastic's `start-local` script. It writes configuration, including a generated API key, into an `elastic-start-local` environment file. Source that file before starting FSCrawler so Docker receives the key through the shell.

bash
curl -fsSL https://elastic.co/start-local | sh
source elastic-start-local/.env

After these commands succeed, the shell should contain the values needed by the Docker command. The quick start also assumes that `~/resumes` contains the binary documents to index.

Pull the image and run the crawler with the documented volume and network mappings. The host alias lets the container reach the local Elasticsearch endpoint. The two mounts separate readable source files from writable crawler state.

bash
docker pull dadoonet/fscrawler
docker run -it --rm \
  --add-host=host.docker.internal:host-gateway \
  -v ~/.fscrawler:/root/.fscrawler \
  -v $(pwd)/resumes:/tmp/es:ro \
  -e FSCRAWLER_ELASTICSEARCH_URLS=http://host.docker.internal:9200 \
  -e FSCRAWLER_ELASTICSEARCH_API_KEY="${ES_LOCAL_API_KEY}" \
  -e FS_JAVA_OPTS="-DLOG_LEVEL=debug" \
  dadoonet/fscrawler

The command expects the current directory to contain `resumes`, even though the explanatory note refers to `~/resumes`. Job settings should appear under `~/.fscrawler/fscrawler/_settings.yaml` as the crawler runs. Debug logging is enabled for this example through `FS_JAVA_OPTS`.

Kibana is then opened at `http://localhost:5601`. The following query verifies that documents reached the `fscrawler` alias and presents their count.

sql
FROM fscrawler 
| STATS numDocs = COUNT(*)

There is no fixed expected count because it depends on the source documents. The next query checks extracted text, but its result still depends on a document containing the specified term.

sql
FROM fscrawler
| WHERE content : "David"

A successful setup therefore produces a queryable `fscrawler` alias, while a text match requires relevant content in the source files.

FSCrawler image tags and Elasticsearch compatibility

Image selection matters because the untagged image and the development snapshot are not equivalent. The README states that untagged `dadoonet/fscrawler`, including `:latest`, points to the last stable release. The `snapshot` tag points to the version currently in preparation. For Docker Compose, the documented setting is `FSCRAWLER_VERSION=snapshot` in `.env`.

Use `snapshot` when the deployment specifically needs the image published from the current `main` branch. The untagged quick start deliberately selects the stable image instead. The repository also publishes a `snapshot-noocr` tag for users who do not need OCR. The README excerpt does not give a corresponding stable no-OCR selection, so users should not infer one.

The compatibility table prevents FSCrawler from being treated as independent software that works with every Elasticsearch cluster. FSCrawler 3.0 is listed for Elasticsearch 7.x, 8.x, and 9.x. FSCrawler 3.1-SNAPSHOT is listed for Elasticsearch 8.x and 9.x. The older FSCrawler 2.9 release is listed for Elasticsearch 6.x and 7.x and was released on 2022-03-08.

The repository is not archived, and its last push was on 2026-10-15. FSCrawler 3.0 was released on 2026-08-26, followed by a 3.1-SNAPSHOT publication on 2026-08-27. These dates show recent repository activity, but they do not remove the need to choose a release according to the cluster version.

Configuration persistence, upgrades, and licensing

FSCrawler separates source data from its own state. The quick start mounts `~/.fscrawler` into `/root/.fscrawler`, and the README identifies `~/.fscrawler/fscrawler/_settings.yaml` as the job-settings file. This persistence reduces the need to recreate settings whenever the temporary container is removed by `--rm`. The README does not document configuration backups, the full settings schema, or whether every option remains valid across major versions.

Upgrades carry at least two coordination costs. The Docker image and Elasticsearch cluster need a listed compatibility combination, and a persisted `_settings.yaml` may contain options whose behavior changes between FSCrawler versions. The README does not provide migration instructions for moving a 2.9 job to 3.0 or from 3.0 to the snapshot line. The linked tutorial and version-specific documentation should be checked before reusing a production job configuration.

The repository is organized as a multi-module Java project with a root `pom.xml` and directories for integration tests, test documents, distribution, CLI, REST, and Elasticsearch-related clients. The README does not give a Maven build command, required Java version, or local packaging procedure. Those details should not be inferred from the repository layout.

The repository declares the Apache-2.0 license and includes `LICENSE` and `NOTICE` files. That identifies the declared licensing model, but an adopter still needs to review the relevant notices and obligations for the specific source, image, and dependencies being used. This is a compliance consideration rather than a claim that every deployment has identical obligations.

Where FSCrawler differs from custom ingestion pipelines

FSCrawler is a poor fit when the requirement is only to send one known file to Elasticsearch. Its feature set centers on crawling files and maintaining document indexes, with local, SSH, FTP, and REST ingestion paths listed by the README. A one-off upload workflow may require less configuration and state management than a persistent crawler.

The documented quick start also requires infrastructure that a container deployment cannot ignore. It needs a running Elasticsearch endpoint, an API key, a source directory mounted into the container, the documented host gateway and endpoint mapping, and persistent storage for job settings. A read-only source mount fits indexing, but a workflow that expects FSCrawler to rename, move, or modify files would need different configuration. The README does not say that the shown setup performs those source-side operations.

Release choice is another boundary. Elasticsearch 6.x is paired with the older FSCrawler 2.9 line, while versions 3.0 and 3.1-SNAPSHOT cover newer combinations. Selecting the newest Docker tag for an older cluster would depart from the documented compatibility table.

A real alternative is a general-purpose ETL pipeline that extracts document content and explicitly writes it through an Elasticsearch client. That approach gives the adopter control over transformations between extraction and indexing, but it also requires assembling document parsing, incremental state, deletion handling, and Elasticsearch mappings. FSCrawler packages those ingestion concerns into a dedicated crawler. The practical distinction is filesystem-oriented synchronization versus a custom transformation pipeline.

Kibana checks for FSCrawler document metadata

The first count query verifies that Elasticsearch holds documents under the expected alias. The README also provides a metadata grouping query, which separates indexed files by `file.content_type`. This is more informative than checking only that an index exists because it shows which types of documents reached Elasticsearch.

sql
FROM fscrawler 
| STATS numDocs = COUNT(*) BY file.content_type

The output should contain the content types represented among the crawled files. The README does not promise a fixed list because that depends on the files placed under `resumes` and the processing applied to them.

Kibana access is separate from the Elasticsearch API key configured for FSCrawler. The startup command launches both services, but the README does not document additional Kibana authentication beyond the generated environment. Failure to open Kibana should not automatically be interpreted as an indexing failure.

For the documented container, the immediate checks are tied to known configuration points. Confirm that the container remains running, inspect whether it can reach `FSCRAWLER_ELASTICSEARCH_URLS`, verify that the source is visible at `/tmp/es`, and inspect the persisted job file. `LOG_LEVEL=debug` is already enabled in the quick start through `FS_JAVA_OPTS`. Once Kibana is available, the `fscrawler` alias queries distinguish connection problems from empty source directories and content extraction problems.

Editorial conclusion

Adopt FSCrawler when binary files already live in file systems that the crawler can access and Elasticsearch is the intended search destination. Do not choose it merely to upload arbitrary files through a browser or operate without persistent crawler configuration. Verify the supported Elasticsearch and FSCrawler version pair first, then confirm the mounted path, generated API key, and whether the untagged or `snapshot` Docker image is appropriate for the deployment.

Frequently asked questions

How do I install FSCrawler and index documents in Elasticsearch?

The README uses the `dadoonet/fscrawler` Docker image, mounts a `resumes` directory read-only at `/tmp/es`, and sets `FSCRAWLER_ELASTICSEARCH_URLS` and `FSCRAWLER_ELASTICSEARCH_API_KEY`. Documents are queried through the `fscrawler` alias in Kibana.

Which FSCrawler version supports my Elasticsearch cluster?

The compatibility table lists FSCrawler 3.0 for Elasticsearch 7.x, 8.x, and 9.x, and FSCrawler 3.1-SNAPSHOT for Elasticsearch 8.x and 9.x. For Elasticsearch 6.x, it lists FSCrawler 2.9.

What is the difference between the stable and snapshot FSCrawler Docker images?

The untagged `dadoonet/fscrawler` image, including `:latest`, is the last stable release according to the README. The `snapshot` tag contains the version in preparation, while `snapshot-noocr` is available when OCR is not needed.

Where does FSCrawler store its job settings?

The README identifies `~/.fscrawler/fscrawler/_settings.yaml` as the job-settings path. Its Docker quick start mounts `~/.fscrawler` at `/root/.fscrawler` so the state persists outside the container.

Can FSCrawler crawl remote file systems?

Yes. The README lists remote file systems over SSH and FTP as supported crawling modes, along with local or mounted drives and a REST interface for uploading binary documents to Elasticsearch.

Official sources

  1. dadoonet/fscrawler on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dadoonet-fscrawler.svg)](https://hysenlabs.com/projects/dadoonet-fscrawler)

Was this useful?