diff --git a/CloudronManifest.json b/CloudronManifest.json index b80983a..f5c1d12 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -4,7 +4,7 @@ "author": "Elastic and Cloudron Community", "description": "Elasticsearch is a distributed, open source search and analytics engine for all types of data. This package is designed for internal use only.", "tagline": "Distributed search and analytics engine", - "version": "1.0.14", + "version": "1.0.17", "healthCheckPath": "/_cluster/health?pretty", "httpPort": 9200, "manifestVersion": 2, diff --git a/README.md b/README.md index bfe8608..a30a30a 100644 --- a/README.md +++ b/README.md @@ -93,10 +93,17 @@ Look for `analysis-icu` in the output before running `occ fulltextsearch:index`. The package automatically configures Elasticsearch based on the container's available resources: -- Java heap size is set to 50% of available memory +- Java heap size defaults to 50% of the app's memory allocation - GC optimization for container environments - Index settings tuned for single-node operation +You can override the automatic heap sizing when necessary: + +- Define `ES_JAVA_HEAP` (e.g. `export ES_JAVA_HEAP=8g`) in `/app/data/.env` +- Provide a full `ES_JAVA_OPTS` string in `/app/data/.env` to take complete control +- Add explicit `-Xms`/`-Xmx` entries in `/app/data/config/jvm.options.d/heap.options` +- Set `ES_SKIP_AUTO_HEAP=1` in `/app/data/.env` to rely solely on the configuration files + ## Limitations - This package is for internal use only and is not exposed to the web by default diff --git a/start.sh b/start.sh index fa24b83..2b1c8e8 100644 --- a/start.sh +++ b/start.sh @@ -380,20 +380,109 @@ ensure_setting() { fi } +default_gc_opts() { + echo "-XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -Xlog:gc*,gc+age=trace,safepoint:file=/app/data/logs/gc/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m" +} + +normalize_heap_value() { + local raw="${1:-}" + raw=$(echo "$raw" | tr '[:upper:]' '[:lower:]') + + if [[ "$raw" =~ ^[0-9]+[mg]$ ]]; then + echo "$raw" + return 0 + fi + + if [[ "$raw" =~ ^[0-9]+$ ]]; then + echo "${raw}m" + return 0 + fi + + return 1 +} + +detect_memory_limit_bytes() { + local limit="" + + if [ -r /sys/fs/cgroup/memory.max ]; then + limit=$(cat /sys/fs/cgroup/memory.max) + if [ "$limit" != "max" ]; then + echo "$limit" + return 0 + fi + fi + + if [ -r /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then + limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) + echo "$limit" + return 0 + fi + + if [ -n "${CLOUDRON_MEMORY_LIMIT:-}" ]; then + # CLOUDRON_MEMORY_LIMIT is in MB + echo $((CLOUDRON_MEMORY_LIMIT * 1024 * 1024)) + return 0 + fi + + echo "" +} + +has_custom_heap_file() { + local heap_file="$ES_PATH_CONF/jvm.options.d/heap.options" + if [ -f "$heap_file" ] && grep -Eq '^-Xms|^-Xmx' "$heap_file"; then + return 0 + fi + return 1 +} + # Configure JVM heap size configure_heap() { - # Calculate optimal heap size (50% of available memory) - CONTAINER_MEM=$(cat /sys/fs/cgroup/memory.max 2>/dev/null || echo "4294967296") - [ "$CONTAINER_MEM" = "max" ] && CONTAINER_MEM="4294967296" # Default to 4GB if unlimited + if [ "${ES_SKIP_AUTO_HEAP:-0}" = "1" ]; then + echo "Skipping automatic heap sizing because ES_SKIP_AUTO_HEAP=1" + return 0 + fi - HEAP_SIZE=$(expr $CONTAINER_MEM / 2097152) # Convert to MB and take 50% - [ $HEAP_SIZE -gt 31744 ] && HEAP_SIZE=31744 # Max 31GB - [ $HEAP_SIZE -lt 512 ] && HEAP_SIZE=512 # Min 512MB + if [ -n "${ES_JAVA_OPTS:-}" ]; then + echo "Detected user-specified ES_JAVA_OPTS; not overriding heap settings." + return 0 + fi - # Set JVM options - export ES_JAVA_OPTS="-Xms${HEAP_SIZE}m -Xmx${HEAP_SIZE}m -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30" - export ES_JAVA_OPTS="$ES_JAVA_OPTS -Xlog:gc*,gc+age=trace,safepoint:file=/app/data/logs/gc/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m" + if has_custom_heap_file; then + echo "Detected custom heap options in jvm.options.d; not overriding heap settings." + return 0 + fi + local heap_value="" + + if [ -n "${ES_JAVA_HEAP:-}" ]; then + if heap_value=$(normalize_heap_value "$ES_JAVA_HEAP"); then + echo "Using heap size from ES_JAVA_HEAP (${heap_value})." + else + echo "Warning: ES_JAVA_HEAP value '$ES_JAVA_HEAP' is invalid; falling back to automatic sizing." + heap_value="" + fi + fi + + if [ -z "$heap_value" ]; then + local limit_bytes + limit_bytes=$(detect_memory_limit_bytes) + if [ -z "$limit_bytes" ] || [ "$limit_bytes" = "0" ]; then + limit_bytes=$((4 * 1024 * 1024 * 1024)) + fi + + # Treat huge values as "unlimited" and fall back to 4GB to avoid 31GB default + if [ "$limit_bytes" -gt $((256 * 1024 * 1024 * 1024)) ]; then + limit_bytes=$((4 * 1024 * 1024 * 1024)) + fi + + local heap_mb=$((limit_bytes / 1024 / 1024 / 2)) + [ "$heap_mb" -gt 31744 ] && heap_mb=31744 + [ "$heap_mb" -lt 512 ] && heap_mb=512 + heap_value="${heap_mb}m" + echo "Auto-configured heap size to ${heap_value} based on container limit." + fi + + export ES_JAVA_OPTS="-Xms${heap_value} -Xmx${heap_value} $(default_gc_opts)" export PATH=$ES_HOME/bin:$PATH }