Ensure plugin installation works on Cloudron
This commit is contained in:
@@ -4,6 +4,10 @@
|
|||||||
# Java memory settings - leave empty to auto-configure based on container limits
|
# Java memory settings - leave empty to auto-configure based on container limits
|
||||||
ES_JAVA_HEAP=
|
ES_JAVA_HEAP=
|
||||||
|
|
||||||
|
# Comma or space separated list of plugins to install automatically
|
||||||
|
# analysis-icu is required for Nextcloud full-text search with language analyzers
|
||||||
|
ES_PLUGINS_INSTALL=analysis-icu
|
||||||
|
|
||||||
# Security settings - DO NOT CHANGE
|
# Security settings - DO NOT CHANGE
|
||||||
ES_JAVA_HOME=/app/data/jdk
|
ES_JAVA_HOME=/app/data/jdk
|
||||||
ES_PATH_CONF=/app/data/config
|
ES_PATH_CONF=/app/data/config
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"author": "Elastic and Cloudron Community",
|
"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.",
|
"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",
|
"tagline": "Distributed search and analytics engine",
|
||||||
"version": "1.0.0",
|
"version": "1.0.7",
|
||||||
"healthCheckPath": "/_cluster/health?pretty",
|
"healthCheckPath": "/_cluster/health?pretty",
|
||||||
"httpPort": 9200,
|
"httpPort": 9200,
|
||||||
"manifestVersion": 2,
|
"manifestVersion": 2,
|
||||||
@@ -17,10 +17,6 @@
|
|||||||
"localDir": "/data"
|
"localDir": "/data"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"accessRestriction": {
|
|
||||||
"users": true,
|
|
||||||
"defaultValue": "internal"
|
|
||||||
},
|
|
||||||
"tags": [
|
"tags": [
|
||||||
"elasticsearch",
|
"elasticsearch",
|
||||||
"search",
|
"search",
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ RUN apt-get update && \
|
|||||||
net-tools \
|
net-tools \
|
||||||
iputils-ping \
|
iputils-ping \
|
||||||
dnsutils \
|
dnsutils \
|
||||||
openjdk-17-jdk
|
openjdk-21-jdk
|
||||||
|
|
||||||
# Set Elasticsearch version
|
# Set Elasticsearch version
|
||||||
ENV ELASTIC_VERSION=9.1.5
|
ENV ELASTIC_VERSION=9.1.5
|
||||||
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
|
||||||
|
|
||||||
# Create elasticsearch user and group
|
# Create elasticsearch user and group
|
||||||
RUN groupadd elasticsearch && \
|
RUN groupadd elasticsearch && \
|
||||||
@@ -39,6 +39,7 @@ RUN mkdir -p /app/data/{elasticsearch,logs,config,secrets,jdk/bin,run} && \
|
|||||||
|
|
||||||
# Copy configuration files
|
# Copy configuration files
|
||||||
COPY elasticsearch.yml /app/elasticsearch.yml
|
COPY elasticsearch.yml /app/elasticsearch.yml
|
||||||
|
COPY .env.template /app/.env.template
|
||||||
COPY start.sh /app/start.sh
|
COPY start.sh /app/start.sh
|
||||||
COPY stop.sh /app/stop.sh
|
COPY stop.sh /app/stop.sh
|
||||||
|
|
||||||
|
|||||||
11
INSTALL.md
11
INSTALL.md
@@ -32,6 +32,17 @@ After installation:
|
|||||||
1. Check the app logs to ensure Elasticsearch has started correctly
|
1. Check the app logs to ensure Elasticsearch has started correctly
|
||||||
2. Note the generated password from the logs or from `/app/data/credentials.txt`
|
2. Note the generated password from the logs or from `/app/data/credentials.txt`
|
||||||
3. Configure your other Cloudron apps to connect to Elasticsearch using the format: `http://elastic:<password>@localhost:9200`
|
3. Configure your other Cloudron apps to connect to Elasticsearch using the format: `http://elastic:<password>@localhost:9200`
|
||||||
|
4. (Recommended) Ensure the required analysis plugins are installed before integrating apps like Nextcloud:
|
||||||
|
1. Open the Cloudron File Manager for the Elasticsearch app and edit `/app/data/.env`
|
||||||
|
2. Set `ES_PLUGINS_INSTALL="analysis-icu"` (add extra plugins separated by spaces or commas)
|
||||||
|
3. Restart the Elasticsearch app so it installs the requested plugins on startup
|
||||||
|
4. Verify installation from the web terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET -u elastic:<password> "localhost:9200/_nodes/plugins?pretty"
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see `analysis-icu` listed before running any index commands.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -7,6 +7,7 @@ This package provides Elasticsearch for Cloudron, configured for internal use on
|
|||||||
- Elasticsearch 9.1.5
|
- Elasticsearch 9.1.5
|
||||||
- Single-node configuration optimized for Cloudron
|
- Single-node configuration optimized for Cloudron
|
||||||
- Security enabled with basic authentication
|
- Security enabled with basic authentication
|
||||||
|
- Automatically installs the `analysis-icu` plugin (configurable)
|
||||||
- Internal access only by default (not publicly exposed)
|
- Internal access only by default (not publicly exposed)
|
||||||
- Automatic optimization based on container resources
|
- Automatic optimization based on container resources
|
||||||
|
|
||||||
@@ -69,6 +70,22 @@ curl -X PUT "http://elastic:PASSWORD@IPADDRESS:9200/nextcloud" -H 'Content-Type:
|
|||||||
|
|
||||||
You can get the IP address from the Cloudron admin panel or by using the `cloudron status` command. The password is stored in `/app/data/credentials.txt`.
|
You can get the IP address from the Cloudron admin panel or by using the `cloudron status` command. The password is stored in `/app/data/credentials.txt`.
|
||||||
|
|
||||||
|
### Language Analysis Plugins
|
||||||
|
|
||||||
|
Many integrations (for example, Nextcloud Full-Text Search with German documents) require the `analysis-icu` plugin so Elasticsearch understands language-specific analyzers. This package installs `analysis-icu` automatically on every start. To add additional plugins, edit `/app/data/.env` via the Cloudron File Manager and tweak the `ES_PLUGINS_INSTALL` variable:
|
||||||
|
|
||||||
|
```
|
||||||
|
ES_PLUGINS_INSTALL="analysis-icu ingest-attachment"
|
||||||
|
```
|
||||||
|
|
||||||
|
Plugins are installed sequentially and skipped if already present. After restarting the app you can verify the installed plugins from the Elasticsearch web terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X GET -u elastic:<password> "localhost:9200/_nodes/plugins?pretty"
|
||||||
|
```
|
||||||
|
|
||||||
|
Look for `analysis-icu` (and any other requested plugins) in the output before running `occ fulltextsearch:index`.
|
||||||
|
|
||||||
## Security Notes
|
## Security Notes
|
||||||
|
|
||||||
- The app is configured as internal-only by default, so it's not exposed to the public internet
|
- The app is configured as internal-only by default, so it's not exposed to the public internet
|
||||||
|
|||||||
108
start.sh
108
start.sh
@@ -56,21 +56,34 @@ setup_password() {
|
|||||||
|
|
||||||
# Set up Java environment
|
# Set up Java environment
|
||||||
setup_java() {
|
setup_java() {
|
||||||
if [ -L /app/data/jdk/bin/java ]; then
|
mkdir -p /app/data/jdk/bin
|
||||||
|
|
||||||
|
if [ -x /app/data/jdk/bin/java ]; then
|
||||||
|
echo "Java already configured: $(/app/data/jdk/bin/java -version 2>&1 | head -n 1)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Setting up Java environment..."
|
echo "Setting up Java environment..."
|
||||||
|
|
||||||
# Try Java 17 first, then fall back to system Java
|
JAVA_FOUND=0
|
||||||
if [ -f /usr/lib/jvm/java-17-openjdk-amd64/bin/java ]; then
|
for candidate in /usr/lib/jvm/java-21-openjdk-amd64/bin /usr/lib/jvm/java-17-openjdk-amd64/bin; do
|
||||||
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/{java,javac,javadoc,jar} /app/data/jdk/bin/
|
if [ -x "$candidate/java" ]; then
|
||||||
else
|
ln -sf "$candidate/java" /app/data/jdk/bin/java
|
||||||
JAVA_PATH=$(which java)
|
|
||||||
if [ -n "$JAVA_PATH" ]; then
|
|
||||||
ln -sf $JAVA_PATH /app/data/jdk/bin/java
|
|
||||||
for tool in javac javadoc jar; do
|
for tool in javac javadoc jar; do
|
||||||
ln -sf $(which $tool 2>/dev/null) /app/data/jdk/bin/$tool 2>/dev/null || true
|
[ -x "$candidate/$tool" ] && ln -sf "$candidate/$tool" /app/data/jdk/bin/$tool
|
||||||
|
done
|
||||||
|
JAVA_FOUND=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $JAVA_FOUND -eq 0 ]; then
|
||||||
|
JAVA_PATH=$(command -v java || true)
|
||||||
|
if [ -n "$JAVA_PATH" ]; then
|
||||||
|
ln -sf "$JAVA_PATH" /app/data/jdk/bin/java
|
||||||
|
for tool in javac javadoc jar; do
|
||||||
|
TOOL_PATH=$(command -v $tool 2>/dev/null || true)
|
||||||
|
[ -n "$TOOL_PATH" ] && ln -sf "$TOOL_PATH" /app/data/jdk/bin/$tool
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
echo "ERROR: No Java found on system. Elasticsearch requires Java to run."
|
echo "ERROR: No Java found on system. Elasticsearch requires Java to run."
|
||||||
@@ -78,15 +91,13 @@ setup_java() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify Java is available
|
if [ ! -x /app/data/jdk/bin/java ]; then
|
||||||
if [ -L /app/data/jdk/bin/java ]; then
|
|
||||||
echo "Java version: $(/app/data/jdk/bin/java -version 2>&1 | head -n 1)"
|
|
||||||
else
|
|
||||||
echo "ERROR: Failed to link Java executable"
|
echo "ERROR: Failed to link Java executable"
|
||||||
|
ls -l /app/data/jdk/bin || true
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure Java symlinks have correct ownership
|
echo "Java version: $(/app/data/jdk/bin/java -version 2>&1 | head -n 1)"
|
||||||
chown -R elasticsearch:elasticsearch /app/data/jdk
|
chown -R elasticsearch:elasticsearch /app/data/jdk
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,12 +215,14 @@ configure_elasticsearch() {
|
|||||||
chmod 600 $ES_PATH_CONF/{users,users_roles}
|
chmod 600 $ES_PATH_CONF/{users,users_roles}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure basic settings in elasticsearch.yml
|
ensure_directory_structure
|
||||||
for setting in "xpack.security.http.ssl.enabled: false" "network.host: 0.0.0.0" "discovery.type: single-node"; do
|
clean_legacy_settings
|
||||||
if ! grep -q "$setting" $ES_PATH_CONF/elasticsearch.yml; then
|
ensure_setting "xpack.security.http.ssl.enabled" "false"
|
||||||
echo "$setting" >> $ES_PATH_CONF/elasticsearch.yml
|
ensure_setting "network.host" "0.0.0.0"
|
||||||
fi
|
ensure_setting "discovery.type" "single-node"
|
||||||
done
|
ensure_setting "path.data" "/app/data/elasticsearch/data"
|
||||||
|
ensure_setting "path.logs" "/app/data/logs"
|
||||||
|
ensure_setting "path.plugins" "/app/data/elasticsearch/plugins"
|
||||||
|
|
||||||
# Final permission check
|
# Final permission check
|
||||||
echo "Final permission check on all data directories..."
|
echo "Final permission check on all data directories..."
|
||||||
@@ -360,6 +373,60 @@ setup_keystore() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensure writable dirs exist
|
||||||
|
ensure_directory_structure() {
|
||||||
|
mkdir -p /app/data/elasticsearch/{data,plugins}
|
||||||
|
mkdir -p /app/data/logs
|
||||||
|
chown -R elasticsearch:elasticsearch /app/data/elasticsearch
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_legacy_settings() {
|
||||||
|
sed -i '/^path\.home:/d' "$ES_PATH_CONF/elasticsearch.yml"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_setting() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
if grep -q "^$key:" "$ES_PATH_CONF/elasticsearch.yml"; then
|
||||||
|
sed -i "s|^$key:.*|$key: $value|" "$ES_PATH_CONF/elasticsearch.yml"
|
||||||
|
else
|
||||||
|
echo "$key: $value" >> "$ES_PATH_CONF/elasticsearch.yml"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install optional Elasticsearch plugins (analysis-icu required for multi-language indexing)
|
||||||
|
install_plugins() {
|
||||||
|
local plugin_list="${ES_PLUGINS_INSTALL:-analysis-icu}"
|
||||||
|
local plugin_dir="/app/data/elasticsearch/plugins"
|
||||||
|
|
||||||
|
if [ -z "$plugin_list" ]; then
|
||||||
|
echo "No Elasticsearch plugins requested for installation."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Normalize separators (commas/semicolons/newlines) to whitespace
|
||||||
|
plugin_list=$(echo "$plugin_list" | tr ',;' ' ')
|
||||||
|
|
||||||
|
for plugin in $plugin_list; do
|
||||||
|
plugin=$(echo "$plugin" | xargs)
|
||||||
|
[ -z "$plugin" ] && continue
|
||||||
|
|
||||||
|
if [ -d "$plugin_dir/$plugin" ]; then
|
||||||
|
echo "Plugin '$plugin' already installed. Skipping."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing Elasticsearch plugin '$plugin'..."
|
||||||
|
if ! su -c "ES_PATH_CONF=$ES_PATH_CONF ES_JAVA_HOME=/app/data/jdk ES_TMPDIR=/tmp $ES_HOME/bin/elasticsearch-plugin install --batch $plugin" elasticsearch; then
|
||||||
|
echo "ERROR: Failed to install plugin '$plugin'."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Requested Elasticsearch plugins installed."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# Configure JVM heap size
|
# Configure JVM heap size
|
||||||
configure_heap() {
|
configure_heap() {
|
||||||
# Calculate optimal heap size (50% of available memory)
|
# Calculate optimal heap size (50% of available memory)
|
||||||
@@ -461,6 +528,7 @@ chmod 600 /app/data/secrets/elastic_password
|
|||||||
|
|
||||||
set_system_limits
|
set_system_limits
|
||||||
configure_heap
|
configure_heap
|
||||||
|
install_plugins
|
||||||
start_elasticsearch
|
start_elasticsearch
|
||||||
|
|
||||||
# Keep container running
|
# Keep container running
|
||||||
|
|||||||
Reference in New Issue
Block a user