Skip to content

Latest commit

 

History

531 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker for Fess

License

Official Docker images and Docker Compose configurations for Fess, an open-source enterprise search server built on OpenSearch.

About

Fess is an enterprise search server with a web-based administration UI, indexing web sites, file systems, and databases. It searches through OpenSearch, which runs as its own container here -- the compose files start both, so you do not have to install or operate OpenSearch by hand. For full documentation, see the official Fess site.

Features

  • Full-text search with faceted navigation, filtering, and suggestions
  • Built-in crawlers for web pages, file systems, and databases
  • Indexing for MS Office, PDF, HTML, XML, CSV, and 40+ other file formats
  • Authentication and access control via LDAP, Active Directory, and SSO
  • Web-based administration for crawlers, schedules, and dictionaries
  • Distributed architecture with horizontal scaling

Tech Stack

  • Search Engine: OpenSearch 3.x
  • Application Server: Apache Tomcat (embedded)
  • Runtime: Java 21 (Eclipse Temurin)
  • Base Images: Alpine Linux (production), Amazon Linux 2023, Ubuntu Noble
  • Containerization: Docker & Docker Compose
  • Optional Services: OpenSearch Dashboards, MinIO object storage

Quick Start

Prerequisites

System Requirements:

  • Docker and Docker Compose installed
  • At least 4GB RAM available
  • For OpenSearch: vm.max_map_count >= 262144

Set vm.max_map_count (Linux/WSL):

# Temporary
sudo sysctl -w vm.max_map_count=262144

# Permanent
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf

Standard Deployment

The Compose files live in the compose/ directory, so clone the repository and move there first. The commands that follow assume that working directory unless they change it themselves.

# Clone the repository
git clone https://github.com/codelibs/docker-fess.git
cd docker-fess/compose

# Start Fess with OpenSearch
docker compose -f compose.yaml -f compose-opensearch3.yaml up -d

Fess is then available at http://localhost:8080.

With OpenSearch Dashboards

docker compose -f compose.yaml -f compose-opensearch3.yaml -f compose-dashboards3.yaml up -d

Fess is at http://localhost:8080 and OpenSearch Dashboards at http://localhost:5601.

With Object Storage (MinIO)

docker compose -f compose.yaml -f compose-opensearch3.yaml -f compose-minio.yaml up -d

Fess is at http://localhost:8080 and the MinIO console at http://localhost:9001.

Development Snapshots

The snapshot stack runs the in-development Fess build. compose/snapshot/compose.yaml only defines the Fess service, so it has to be combined with a backend, exactly like compose.yaml:

cd docker-fess/compose/snapshot

# Single OpenSearch node
docker compose -f compose.yaml -f ../compose-opensearch3.yaml up -d

# Five-node OpenSearch cluster
docker compose -f compose.yaml -f compose-cluster.yaml up -d

Usage

Basic Search Setup

  1. Access Fess Admin: Navigate to http://localhost:8080/admin

    • Default credentials: admin / admin
  2. Create a Web Crawler:

    • Go to Crawler > Web
    • Add URL: https://example.com/*
    • Start crawling from System > Scheduler
  3. Configure Search:

    • Set crawl schedules, filters, and permissions
    • Monitor crawl status and logs

Environment Variables

Configure Fess behavior through environment variables:

environment:
  # Search backend configuration
  - SEARCH_ENGINE_HTTP_URL=http://search01:9200
  
  # Dictionary and data paths
  - FESS_DICTIONARY_PATH=/usr/share/opensearch/config/dictionary/
  
  # Heap size (see Memory Settings below)
  - FESS_HEAP_SIZE=1g

  # Extra JVM options. Do not put -Xms / -Xmx here.
  - FESS_JAVA_OPTS=-Djavax.net.ssl.trustStore=/opt/fess/truststore.jks

  # Plugin installation
  - FESS_PLUGINS=fess-ds-wikipedia:15.8.0 fess-ds-git:15.8.0

The full set the images understand:

Variable Default Description
SEARCH_ENGINE_HTTP_URL http://localhost:9200 Backend search engine URL
SEARCH_ENGINE_TYPE (none) Set to cloud for a plain OpenSearch without the Fess plugins. That mode loses the Japanese analyzers, minhash near-duplicate detection and the dictionary admin UI
SEARCH_ENGINE_USERNAME (none) Username, when the search engine requires authentication
SEARCH_ENGINE_PASSWORD (none) Password, when the search engine requires authentication
FESS_DICTIONARY_PATH /var/lib/opensearch/config/ Dictionary directory shared with OpenSearch
FESS_PORT 8080 Port Fess listens on inside the container
FESS_CONTEXT_PATH / Context path Fess is served under, e.g. /fess
FESS_HEAP_SIZE 512m Heap size; see Memory Settings below
FESS_MIN_MEM / FESS_MAX_MEM (none) Asymmetric heap bounds; see Memory Settings below
FESS_JAVA_OPTS (none) Extra JVM options, mainly -Dfess.config.* and -Dfess.system.*
FESS_PLUGINS (none) Space-separated plugin-name:version list to install at startup
FESS_CONF_PATH /etc/fess Configuration directory
FESS_OVERRIDE_CONF_PATH /opt/fess Extra configuration directory placed ahead of FESS_CONF_PATH on the classpath, so a file mounted here replaces the packaged one
PING_INTERVAL 60 Seconds between the entrypoint's health probes
PING_RETRIES 5 Consecutive failed probes, once Fess has answered at least once, before the entrypoint gives up and the container exits
PING_STARTUP_RETRIES 10 Failed probes allowed before Fess has answered for the first time

The health check builds its URL from FESS_PORT and FESS_CONTEXT_PATH, so moving Fess to another port or context path does not make the container report unhealthy.

Startup is counted separately from an outage. Fess has not answered yet while it is still starting, and on a loaded host that takes longer than a running instance ever goes unanswered; counting those probes against PING_RETRIES used to kill a container that was only slow to come up. With the defaults, Fess has ten minutes to answer for the first time, and five consecutive failed probes after that end the container.

FESS_JAVA_OPTS is split on whitespace, so an option whose value contains a space breaks the JVM command line: the container fails with Could not find or load main class and then exits. Options with such a value belong in /opt/fess/fess_config.properties (see FESS_OVERRIDE_CONF_PATH) instead.

Memory Settings

The heap comes from FESS_HEAP_SIZE, or from the FESS_MIN_MEM / FESS_MAX_MEM pair when you want an asymmetric heap:

Variables Resulting JVM flags
FESS_HEAP_SIZE=1g -Xms1g -Xmx1g
FESS_MIN_MEM=512m and FESS_MAX_MEM=2g -Xms512m -Xmx2g
both of the above -Xms1g -Xmx1g; FESS_HEAP_SIZE wins
none of them -Xms512m -Xmx512m, the container default

Set both halves of the pair. An unset half falls back to the Fess default (256m for the minimum, 2g for the maximum), not to the container default.

Do not pass -Xms or -Xmx through FESS_JAVA_OPTS. Fess appends the pair it derives from the variables above after everything in FESS_JAVA_OPTS, and the JVM keeps the last value it is given, so heap flags placed there are discarded without a warning.

Multi-Instance Deployment

Run multiple Fess instances sharing one OpenSearch cluster:

cd docker-fess/compose/multi-instance

# Start OpenSearch + 2 Fess instances
docker compose -f compose.yaml -f compose-fess01.yaml -f compose-fess02.yaml up -d

Instance 1 is at http://localhost:8080 and instance 2 at http://localhost:8081. Each instance uses separate indices for data isolation.

Service URLs

Service URL Purpose
Fess Web UI http://localhost:8080 Main search interface
Fess Admin http://localhost:8080/admin Administration panel
OpenSearch API http://localhost:9200 Direct search engine access
OpenSearch Dashboards http://localhost:5601 Data visualization
MinIO Console http://localhost:9001 Object storage management

Development

Building Images

Fess Application:

# Build specific version
docker build --rm -t ghcr.io/codelibs/fess:15.8.0 ./fess/15.8/

# Build with custom args
docker build --build-arg FESS_VERSION=15.8.0 -t my-fess ./fess/15.8/

OpenSearch with Fess Plugins:

# Build OpenSearch image
docker build --rm -t ghcr.io/codelibs/fess-opensearch:3.8.0 ./opensearch/3.8/

Project Structure

docker-fess/
├── fess/                    # Fess Docker images
│   ├── 15.8/               # Latest stable version
│   ├── 15.7/               # Previous versions
│   └── snapshot/           # Development builds
├── opensearch/             # OpenSearch images with Fess plugins
│   ├── 3.8/               # Latest OpenSearch
│   └── 3.7/               # Previous versions
├── elasticsearch/          # Elasticsearch images (legacy)
└── compose/                # Docker Compose configurations
    ├── compose.yaml        # Base Fess service
    ├── compose-opensearch3.yaml  # OpenSearch 3.x
    ├── compose-dashboards3.yaml  # OpenSearch Dashboards
    ├── compose-minio.yaml  # MinIO object storage
    ├── multi-instance/     # Multi-instance setup
    ├── snapshot/           # Development snapshot builds
    └── vanilla/            # Stock OpenSearch, without the Fess plugins

Configuration Files

Key Configuration Locations:

  • /etc/fess/ - Main configuration directory
  • /opt/fess/ - Custom configuration overrides
  • /var/log/fess/ - Application logs
  • /var/lib/fess/ - Variable data storage

Custom Index Configuration:

# Configure separate indices for multi-instance
FESS_JAVA_OPTS="-Dfess.config.index.document.search.index=myapp.search \
                -Dfess.config.index.document.update.index=myapp.update \
                -Dfess.config.index.config.index=myapp_config"

Version Matrix

Fess Version OpenSearch Elasticsearch Java Base Image
15.9.0-SNAPSHOT (snapshot tag) 3.8.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.8.0 3.8.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.7.0 3.7.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.6.0 3.6.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.5.1 3.5.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.4.0 3.4.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.3.0 3.3.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.2.0 3.2.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.1.0 3.1.0 - 21 Alpine/Ubuntu Noble/Amazon Linux 2023
15.0.0 2.15 8.10+ 17 Alpine
14.x 2.x 7.17/8.x 11 Alpine

Upgrading to 15.9

Fess 15.9 removed the embedded search engine, so a Fess container always needs an OpenSearch to talk to. The compose files here already start one, so nothing changes for them, but three behaviours differ:

  • A search engine older than OpenSearch 3 now stops startup instead of logging an error and continuing. Earlier engines do not implement the _shard_doc sort that document export, purge, backup and suggest dictionary builds rely on, and over HTTP those requests hang rather than fail, so the mismatch is refused up front.
  • SEARCH_ENGINE_HOME no longer does anything. It pointed at the bundled engine's directory.
  • The legacy elasticsearch.* configuration keys are gone. The ES_* environment variables these images accept are unaffected; the entrypoint translates them to SEARCH_ENGINE_*.

15.9 also moved several features out of the war and into plugins. The images install all seven at build time with bin/fess-setup install plugin, so they behave as the 15.8 images did and none of these belongs in FESS_PLUGINS:

What stops working without it Plugin
script_type=groovy -- and any data store, job or crawler script that leaves script_type unset, which still resolves to groovy fess-script-groovy
s3: crawling and the S3 storage backend fess-storage-s3
gcs: crawling and the GCS storage backend fess-storage-gcs
sso.type=saml fess-sso-saml
sso.type=spnego fess-sso-spnego
sso.type=entraid, and the legacy aad fess-sso-entraid
sso.type=oic -- the one name that differs from its plugin's fess-sso-oidc

To drop one from an image, run bin/fess-setup remove plugin <name> in a derived image. Keep a plugin on the same line as the Fess it runs in: a 15.9 SSO plugin in a 15.8 Fess registers a second copy of an authenticator that war already declares, and /sso/ then fails.

Troubleshooting

Common Issues

Container fails to start:

# Check vm.max_map_count
cat /proc/sys/vm/max_map_count  # Should be >= 262144

# Check container logs
docker compose logs fess01
docker compose logs search01

Out of memory errors:

Raise the heap in the environment: block of the Fess service. Exporting the variable in your shell has no effect, because compose.yaml does not pass the host environment through:

services:
  fess01:
    environment:
      - "FESS_HEAP_SIZE=2g"

Recreate the container afterwards so the new value is applied.

Search not working:

# Verify OpenSearch connection
curl http://localhost:9200/_cluster/health

# Check Fess connectivity
docker compose exec fess01 curl http://search01:9200

Data persistence:

# List volumes
docker volume ls | grep compose

# Remove volumes (WARNING: deletes data)
docker volume rm compose_search01_data compose_search01_dictionary

Performance Tuning

For production deployments:

  1. Memory allocation:

    • Fess: 2-4GB heap (FESS_HEAP_SIZE=2g)
    • OpenSearch: 50% of available RAM (OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g)
  2. Storage optimization:

    • Use SSD storage for OpenSearch data volumes
    • Separate OS disk from data volumes
  3. Network configuration:

    • Use dedicated network for container communication
    • Configure proper DNS resolution

Advanced Usage

Custom Plugins

Install additional Fess plugins:

environment:
  - FESS_PLUGINS=fess-ds-wikipedia:15.8.0 fess-ds-git:15.8.0

Entries are plugin-name:version pairs separated by spaces, and the name has to start with one of fess-ds-, fess-ingest-, fess-llm-, fess-script-, fess-sso-, fess-storage-, fess-theme-, fess-thumbnail- or fess-webapp-. A name that is not recognized, or a version that cannot be downloaded, is skipped and does not stop the container from starting, so check the boot log after adding a plugin.

Semantic search no longer needs a plugin. It became part of Fess in 15.8, and fess-webapp-semantic-search is not published for 15.8 or later.

Running Behind a Reverse Proxy

When TLS is terminated at a proxy in front of Fess, the container still speaks plain HTTP, and two settings have to be told about the public origin.

services:
  fess01:
    environment:
      - "FESS_JAVA_OPTS=-Dfess.config.session.cookie.secure=true -Dfess.config.theme.api.csrf.server.origins=https://fess.example.com"

session.cookie.secure ships blank, which leaves the Secure attribute to Tomcat, and Tomcat only adds it when the request it sees is HTTPS. Behind a TLS-terminating proxy that request is HTTP, so JSESSIONID goes out without Secure unless this is set to true. Keep it blank for plain-HTTP development, because the browser will not send the cookie back over HTTP once it is set.

theme.api.csrf.server.origins is the list of origins the v2 API treats as its own. It also ships blank, and the API then reconstructs the expected origin from the request, which does not match the proxy's public origin. POST /api/v2/login through a proxy is rejected with cross-site request blocked until the public origin is listed here.

Fess has no key store option of its own, so terminate TLS at the proxy rather than in the container.

Backup and Recovery

# Backup OpenSearch data
docker run --rm -v compose_search01_data:/data -v $(pwd):/backup alpine tar czf /backup/opensearch-backup.tar.gz /data

# Restore OpenSearch data
docker run --rm -v compose_search01_data:/data -v $(pwd):/backup alpine tar xzf /backup/opensearch-backup.tar.gz -C /

License

Apache License 2.0

Copyright 2016-2026 CodeLibs Project and the Others.

Releases

Packages

Used by

Contributors

Languages