Optimize codebase: Refactor start.sh, clean up elasticsearch.yml, and streamline Dockerfile
This commit is contained in:
parent
43f3babba5
commit
e538faa594
33
Dockerfile
33
Dockerfile
@ -1,23 +1,28 @@
|
|||||||
FROM cloudron/base:4.0.0
|
FROM cloudron/base:4.0.0
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies and OpenJDK 17
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && \
|
||||||
|
apt-get install -y software-properties-common && \
|
||||||
|
add-apt-repository -y ppa:openjdk-r/ppa && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
apt-transport-https \
|
apt-transport-https \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
curl \
|
curl \
|
||||||
gnupg-agent \
|
gnupg-agent \
|
||||||
unzip \
|
unzip \
|
||||||
wget \
|
wget \
|
||||||
default-jre \
|
|
||||||
iproute2 \
|
iproute2 \
|
||||||
net-tools \
|
net-tools \
|
||||||
iputils-ping \
|
iputils-ping \
|
||||||
dnsutils
|
dnsutils \
|
||||||
|
openjdk-17-jdk
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV ELASTIC_VERSION=8.17.3
|
ENV ELASTIC_VERSION=8.17.3
|
||||||
|
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
||||||
|
|
||||||
# Create elasticsearch user and group with dynamic ID allocation
|
# Create elasticsearch user and group
|
||||||
RUN groupadd elasticsearch && \
|
RUN groupadd elasticsearch && \
|
||||||
useradd -g elasticsearch -s /bin/bash elasticsearch
|
useradd -g elasticsearch -s /bin/bash elasticsearch
|
||||||
|
|
||||||
@ -26,27 +31,21 @@ RUN mkdir -p /usr/share/elasticsearch && \
|
|||||||
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz && \
|
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz && \
|
||||||
tar -xzf elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz -C /usr/share/ && \
|
tar -xzf elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz -C /usr/share/ && \
|
||||||
mv /usr/share/elasticsearch-${ELASTIC_VERSION}/* /usr/share/elasticsearch/ && \
|
mv /usr/share/elasticsearch-${ELASTIC_VERSION}/* /usr/share/elasticsearch/ && \
|
||||||
rm -rf /usr/share/elasticsearch-${ELASTIC_VERSION} && \
|
rm -rf /usr/share/elasticsearch-${ELASTIC_VERSION} elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz
|
||||||
rm elasticsearch-${ELASTIC_VERSION}-linux-x86_64.tar.gz
|
|
||||||
|
|
||||||
# Set up directories
|
# Create necessary directories for data and configuration
|
||||||
RUN mkdir -p /app/data/elasticsearch && \
|
RUN mkdir -p /app/data/{elasticsearch,logs,config,secrets,jdk/bin,run} && \
|
||||||
mkdir -p /app/data/logs && \
|
chown -R elasticsearch:elasticsearch /app/data
|
||||||
mkdir -p /app/data/config && \
|
|
||||||
mkdir -p /app/data/secrets
|
|
||||||
|
|
||||||
# Copy configuration files
|
# Copy configuration files
|
||||||
COPY elasticsearch.yml /app/data/config/elasticsearch.yml.orig
|
|
||||||
COPY elasticsearch.yml /app/elasticsearch.yml
|
COPY elasticsearch.yml /app/elasticsearch.yml
|
||||||
COPY .env /app/.env
|
COPY .env /app/.env
|
||||||
COPY start.sh /app/start.sh
|
COPY start.sh /app/start.sh
|
||||||
COPY stop.sh /app/stop.sh
|
COPY stop.sh /app/stop.sh
|
||||||
|
|
||||||
# Make scripts executable
|
|
||||||
RUN chmod +x /app/start.sh /app/stop.sh
|
RUN chmod +x /app/start.sh /app/stop.sh
|
||||||
|
|
||||||
# Add healthcheck
|
# Add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --start-period=60s --retries=3 \
|
HEALTHCHECK --interval=15s --timeout=10s --start-period=120s --retries=5 \
|
||||||
CMD curl -f -u elastic:$(cat /app/data/secrets/elastic_password 2>/dev/null || echo "cloudron") http://localhost:9200 || exit 1
|
CMD curl -fs -u elastic:$(cat /app/data/secrets/elastic_password 2>/dev/null || echo "cloudron") http://localhost:9200/_cluster/health?pretty || exit 1
|
||||||
|
|
||||||
CMD ["/app/start.sh"]
|
CMD ["/app/start.sh"]
|
@ -5,12 +5,8 @@ cluster.name: cloudron-cluster
|
|||||||
|
|
||||||
# ------------------------------------ Node ------------------------------------
|
# ------------------------------------ Node ------------------------------------
|
||||||
node.name: ${HOSTNAME}
|
node.name: ${HOSTNAME}
|
||||||
# The following settings are deprecated in Elasticsearch 8.x
|
|
||||||
# node.master: true
|
|
||||||
# node.data: true
|
|
||||||
# In Elasticsearch 8.x, a node is both a master-eligible and data node by default
|
# In Elasticsearch 8.x, a node is both a master-eligible and data node by default
|
||||||
# To change this behavior, use roles instead
|
# To change this behavior, use roles instead: node.roles: [ master, data, ...]
|
||||||
#node.roles: [ master, data ]
|
|
||||||
|
|
||||||
# ----------------------------------- Paths ------------------------------------
|
# ----------------------------------- Paths ------------------------------------
|
||||||
path.data: /app/data/elasticsearch
|
path.data: /app/data/elasticsearch
|
||||||
@ -26,35 +22,26 @@ discovery.type: single-node
|
|||||||
|
|
||||||
# --------------------------------- Security ----------------------------------
|
# --------------------------------- Security ----------------------------------
|
||||||
xpack.security.enabled: true
|
xpack.security.enabled: true
|
||||||
|
|
||||||
# Transport layer settings (for node-to-node communication)
|
|
||||||
xpack.security.transport.ssl.enabled: false
|
xpack.security.transport.ssl.enabled: false
|
||||||
# xpack.security.transport.ssl.verification_mode: none
|
|
||||||
# xpack.security.transport.ssl.keystore.path: /app/data/config/elastic-certificates.p12
|
|
||||||
# xpack.security.transport.ssl.truststore.path: /app/data/config/elastic-certificates.p12
|
|
||||||
|
|
||||||
# HTTP layer settings (for client connections)
|
|
||||||
xpack.security.http.ssl.enabled: false
|
xpack.security.http.ssl.enabled: false
|
||||||
|
|
||||||
# Allow basic auth
|
|
||||||
xpack.security.authc.token.enabled: false
|
xpack.security.authc.token.enabled: false
|
||||||
xpack.security.authc.api_key.enabled: false
|
xpack.security.authc.api_key.enabled: false
|
||||||
|
|
||||||
# Required password hashing algorithm
|
|
||||||
xpack.security.authc.password_hashing.algorithm: bcrypt
|
xpack.security.authc.password_hashing.algorithm: bcrypt
|
||||||
|
|
||||||
# ----------------------------------- Memory ----------------------------------
|
# ----------------------------------- Memory ----------------------------------
|
||||||
bootstrap.memory_lock: false
|
# Memory locking to prevent swapping
|
||||||
|
bootstrap.memory_lock: true
|
||||||
|
|
||||||
# ---------------------------------- Various ----------------------------------
|
# ---------------------------------- HTTP/REST API ---------------------------
|
||||||
http.cors.enabled: true
|
http.cors.enabled: true
|
||||||
http.cors.allow-origin: "*"
|
http.cors.allow-origin: "*"
|
||||||
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
|
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
|
||||||
http.cors.allow-headers: "X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization"
|
http.cors.allow-headers: "X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization"
|
||||||
|
|
||||||
|
# Allow auto-creation of system indices
|
||||||
action.auto_create_index: .security,.monitoring*,.watches,.triggered_watches,.watcher-history*,.ml*
|
action.auto_create_index: .security,.monitoring*,.watches,.triggered_watches,.watcher-history*,.ml*
|
||||||
|
|
||||||
# ---------------------------------- Performance Optimizations ----------------------------------
|
# ---------------------------------- Performance Optimizations ------------------
|
||||||
|
|
||||||
# Circuit breaker settings
|
# Circuit breaker settings
|
||||||
indices.breaker.total.limit: 70%
|
indices.breaker.total.limit: 70%
|
||||||
@ -62,23 +49,16 @@ indices.breaker.total.limit: 70%
|
|||||||
# Memory optimization
|
# Memory optimization
|
||||||
indices.fielddata.cache.size: 20%
|
indices.fielddata.cache.size: 20%
|
||||||
indices.memory.index_buffer_size: 20%
|
indices.memory.index_buffer_size: 20%
|
||||||
|
indices.queries.cache.size: 15%
|
||||||
|
|
||||||
# Thread pool and queue sizes
|
# Thread pool and queue sizes
|
||||||
thread_pool.write.queue_size: 1000
|
thread_pool.write.queue_size: 1000
|
||||||
thread_pool.search.queue_size: 1000
|
thread_pool.search.queue_size: 1000
|
||||||
|
|
||||||
# Indexing settings
|
|
||||||
indices.queries.cache.size: 15%
|
|
||||||
bootstrap.memory_lock: true
|
|
||||||
|
|
||||||
# I/O optimization
|
# I/O optimization
|
||||||
bootstrap.system_call_filter: false
|
bootstrap.system_call_filter: false
|
||||||
|
|
||||||
# Refresh interval - Set to a higher value if you prioritize indexing speed over search freshness
|
# Default index settings
|
||||||
# indices.refresh_interval: 30s
|
|
||||||
# This setting should be applied per index, not globally
|
|
||||||
|
|
||||||
# Index defaults
|
|
||||||
index.number_of_shards: 1
|
index.number_of_shards: 1
|
||||||
index.number_of_replicas: 0
|
index.number_of_replicas: 0
|
||||||
|
|
||||||
@ -88,5 +68,5 @@ index.merge.policy.floor_segment: 2mb
|
|||||||
index.merge.policy.max_merge_at_once: 4
|
index.merge.policy.max_merge_at_once: 4
|
||||||
index.merge.policy.segments_per_tier: 8
|
index.merge.policy.segments_per_tier: 8
|
||||||
|
|
||||||
# GC settings - these complement the JVM options set in start.sh
|
# Set processors based on container configuration
|
||||||
processors: ${PROCESSORS:1}
|
processors: ${PROCESSORS:1}
|
451
start.sh
451
start.sh
@ -4,324 +4,213 @@ set -e
|
|||||||
# Source environment variables
|
# Source environment variables
|
||||||
source /app/.env
|
source /app/.env
|
||||||
|
|
||||||
# Create a secrets directory in data (which is writable)
|
# Set constants
|
||||||
mkdir -p /app/data/secrets
|
|
||||||
|
|
||||||
# Set the elastic user password - will be used throughout the script
|
|
||||||
ELASTIC_PASSWORD="cloudron"
|
ELASTIC_PASSWORD="cloudron"
|
||||||
|
ES_HOME=/usr/share/elasticsearch
|
||||||
|
ES_PATH_CONF=/app/data/config
|
||||||
|
export ES_HOME ES_PATH_CONF
|
||||||
|
|
||||||
|
# Create directory structure
|
||||||
|
mkdir -p /app/data/{elasticsearch,logs/gc,config,run,secrets,jdk/bin}
|
||||||
echo "$ELASTIC_PASSWORD" > /app/data/secrets/elastic_password
|
echo "$ELASTIC_PASSWORD" > /app/data/secrets/elastic_password
|
||||||
|
|
||||||
# Set up the correct directories first
|
# Set up Java environment
|
||||||
mkdir -p /app/data/elasticsearch
|
setup_java() {
|
||||||
mkdir -p /app/data/logs
|
if [ -L /app/data/jdk/bin/java ]; then
|
||||||
mkdir -p /app/data/logs/gc
|
return 0
|
||||||
mkdir -p /app/data/config
|
fi
|
||||||
mkdir -p /app/data/run # Directory for PID file
|
|
||||||
|
|
||||||
# Create a writable JDK directory for Elasticsearch FIRST
|
|
||||||
# This must be done before trying to use Java
|
|
||||||
mkdir -p /app/data/jdk/bin
|
|
||||||
if [ ! -L /app/data/jdk/bin/java ]; then
|
|
||||||
echo "Setting up Java environment..."
|
echo "Setting up Java environment..."
|
||||||
# First check if Java is available
|
|
||||||
if [ ! -f /usr/lib/jvm/java-17-openjdk-amd64/bin/java ]; then
|
# Try Java 17 first, then fall back to system Java
|
||||||
echo "ERROR: Java is not found at expected location /usr/lib/jvm/java-17-openjdk-amd64/bin/java"
|
if [ -f /usr/lib/jvm/java-17-openjdk-amd64/bin/java ]; then
|
||||||
# Try to find it elsewhere
|
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/{java,javac,javadoc,jar} /app/data/jdk/bin/
|
||||||
echo "Available Java installations:"
|
else
|
||||||
find /usr -name java | grep -i jdk
|
|
||||||
ls -la /usr/lib/jvm/
|
|
||||||
echo "Will try default system Java instead"
|
|
||||||
# Try to use default Java
|
|
||||||
which java
|
|
||||||
JAVA_PATH=$(which java)
|
JAVA_PATH=$(which java)
|
||||||
if [ -n "$JAVA_PATH" ]; then
|
if [ -n "$JAVA_PATH" ]; then
|
||||||
ln -sf $JAVA_PATH /app/data/jdk/bin/java
|
ln -sf $JAVA_PATH /app/data/jdk/bin/java
|
||||||
ln -sf $(which javac 2>/dev/null) /app/data/jdk/bin/javac 2>/dev/null
|
for tool in javac javadoc jar; do
|
||||||
ln -sf $(which javadoc 2>/dev/null) /app/data/jdk/bin/javadoc 2>/dev/null
|
ln -sf $(which $tool 2>/dev/null) /app/data/jdk/bin/$tool 2>/dev/null || true
|
||||||
ln -sf $(which jar 2>/dev/null) /app/data/jdk/bin/jar 2>/dev/null
|
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."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
# Create symbolic links from Java 17 to our writable JDK directory
|
|
||||||
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/java /app/data/jdk/bin/java
|
|
||||||
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/javac /app/data/jdk/bin/javac
|
|
||||||
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/javadoc /app/data/jdk/bin/javadoc
|
|
||||||
ln -sf /usr/lib/jvm/java-17-openjdk-amd64/bin/jar /app/data/jdk/bin/jar
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify Java is available and linked correctly
|
# Verify Java is available
|
||||||
if [ -L /app/data/jdk/bin/java ]; then
|
if [ -L /app/data/jdk/bin/java ]; then
|
||||||
echo "Checking Java version:"
|
echo "Java version: $(/app/data/jdk/bin/java -version 2>&1 | head -n 1)"
|
||||||
/app/data/jdk/bin/java -version || echo "WARNING: Java is linked but not working!"
|
|
||||||
else
|
else
|
||||||
echo "ERROR: Failed to link Java executable"
|
echo "ERROR: Failed to link Java executable"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo "Java environment setup complete"
|
# Configure Elasticsearch
|
||||||
fi
|
configure_elasticsearch() {
|
||||||
|
cd $ES_HOME
|
||||||
|
|
||||||
# Check for initialization status
|
# Handle keystore creation and password
|
||||||
if [[ ! -f /app/data/.initialized ]]; then
|
if [ ! -f $ES_PATH_CONF/elasticsearch.keystore ] || [ "$1" = "force" ]; then
|
||||||
echo "Fresh installation, initializing..."
|
|
||||||
|
|
||||||
# Create an initial keystore and add bootstrap password for first startup
|
|
||||||
cd /usr/share/elasticsearch
|
|
||||||
# Set config path for Elasticsearch
|
|
||||||
export ES_PATH_CONF=/app/data/config
|
|
||||||
|
|
||||||
# Ensure proper ownership of config directory
|
|
||||||
chown -R elasticsearch:elasticsearch /app/data/config
|
|
||||||
|
|
||||||
# Initialize the elasticsearch keystore if it doesn't exist
|
|
||||||
if [ ! -f /app/data/config/elasticsearch.keystore ]; then
|
|
||||||
echo "Creating Elasticsearch keystore..."
|
echo "Creating Elasticsearch keystore..."
|
||||||
# Create keystore as the elasticsearch user
|
[ -f $ES_PATH_CONF/elasticsearch.keystore ] && rm -f $ES_PATH_CONF/elasticsearch.keystore
|
||||||
su -c "ES_PATH_CONF=/app/data/config ES_JAVA_HOME=/app/data/jdk /usr/share/elasticsearch/bin/elasticsearch-keystore create" elasticsearch
|
su -c "ES_PATH_CONF=$ES_PATH_CONF ES_JAVA_HOME=/app/data/jdk $ES_HOME/bin/elasticsearch-keystore create" elasticsearch
|
||||||
else
|
|
||||||
# If keystore exists but needs to be recreated (e.g. due to permission issues)
|
|
||||||
echo "Keystore already exists. Ensuring proper permissions..."
|
|
||||||
rm -f /app/data/config/elasticsearch.keystore
|
|
||||||
su -c "ES_PATH_CONF=/app/data/config ES_JAVA_HOME=/app/data/jdk /usr/share/elasticsearch/bin/elasticsearch-keystore create" elasticsearch
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add the bootstrap password to the keystore - this is needed for first startup
|
# Add bootstrap password to keystore
|
||||||
echo "Setting bootstrap password..."
|
echo "Setting bootstrap password..."
|
||||||
echo "$ELASTIC_PASSWORD" | su -c "ES_PATH_CONF=/app/data/config ES_JAVA_HOME=/app/data/jdk /usr/share/elasticsearch/bin/elasticsearch-keystore add -f -x 'bootstrap.password' --stdin" elasticsearch
|
echo "$ELASTIC_PASSWORD" | su -c "ES_PATH_CONF=$ES_PATH_CONF ES_JAVA_HOME=/app/data/jdk $ES_HOME/bin/elasticsearch-keystore add -f -x 'bootstrap.password' --stdin" elasticsearch
|
||||||
|
|
||||||
# Mark as initialized
|
# Copy configuration files if needed
|
||||||
touch /app/data/.initialized
|
if [ ! -f $ES_PATH_CONF/elasticsearch.yml ]; then
|
||||||
echo "Initialization complete."
|
echo "Setting up configuration files..."
|
||||||
else
|
cp -r $ES_HOME/config/* $ES_PATH_CONF/ || true
|
||||||
echo "Loading existing configuration..."
|
cp /app/elasticsearch.yml $ES_PATH_CONF/elasticsearch.yml || true
|
||||||
# Re-add the bootstrap password to ensure it's set correctly
|
|
||||||
cd /usr/share/elasticsearch
|
|
||||||
# Set config path for Elasticsearch
|
|
||||||
export ES_PATH_CONF=/app/data/config
|
|
||||||
|
|
||||||
# Ensure elasticsearch user owns the keystore
|
|
||||||
chown -R elasticsearch:elasticsearch /app/data/config
|
|
||||||
|
|
||||||
echo "Updating bootstrap password in keystore..."
|
|
||||||
echo "$ELASTIC_PASSWORD" | su -c "ES_PATH_CONF=/app/data/config ES_JAVA_HOME=/app/data/jdk /usr/share/elasticsearch/bin/elasticsearch-keystore add -f -x 'bootstrap.password' --stdin" elasticsearch
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy the entire Elasticsearch config directory if not already set up
|
|
||||||
if [ ! -f /app/data/config/elasticsearch.yml ]; then
|
|
||||||
echo "Copying Elasticsearch configuration files..."
|
|
||||||
cp -r /usr/share/elasticsearch/config/* /app/data/config/ || true
|
|
||||||
# Override with our custom elasticsearch.yml
|
|
||||||
cp /app/elasticsearch.yml /app/data/config/elasticsearch.yml || true
|
|
||||||
echo "Elasticsearch configuration files copied"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Modify jvm.options to use a writable location for GC logs
|
|
||||||
if [ -f /app/data/config/jvm.options ]; then
|
|
||||||
echo "Updating JVM options for GC logs..."
|
|
||||||
# Create a temporary file with updated options
|
|
||||||
cat /app/data/config/jvm.options | sed 's|logs/gc.log|/app/data/logs/gc/gc.log|g' > /tmp/jvm.options.new
|
|
||||||
mv /tmp/jvm.options.new /app/data/config/jvm.options
|
|
||||||
echo "JVM options updated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate SSL certificates for Elasticsearch if they don't exist
|
|
||||||
if [ ! -f /app/data/config/elastic-certificates.p12 ]; then
|
|
||||||
echo "Generating self-signed certificates for Elasticsearch transport layer..."
|
|
||||||
|
|
||||||
# Create a temporary directory for certificate generation
|
|
||||||
mkdir -p /tmp/elastic-certs
|
|
||||||
|
|
||||||
# Run the elasticsearch-certutil command to generate the certificate
|
|
||||||
cd /usr/share/elasticsearch
|
|
||||||
ES_JAVA_HOME=/app/data/jdk bin/elasticsearch-certutil ca \
|
|
||||||
--out /tmp/elastic-certs/elastic-stack-ca.p12 \
|
|
||||||
--pass "" \
|
|
||||||
--silent
|
|
||||||
|
|
||||||
# Generate the certificates for nodes
|
|
||||||
ES_JAVA_HOME=/app/data/jdk bin/elasticsearch-certutil cert \
|
|
||||||
--ca /tmp/elastic-certs/elastic-stack-ca.p12 \
|
|
||||||
--ca-pass "" \
|
|
||||||
--out /app/data/config/elastic-certificates.p12 \
|
|
||||||
--pass "" \
|
|
||||||
--silent
|
|
||||||
|
|
||||||
# Set proper permissions for the certificates
|
|
||||||
chown elasticsearch:elasticsearch /app/data/config/elastic-certificates.p12
|
|
||||||
chmod 600 /app/data/config/elastic-certificates.p12
|
|
||||||
|
|
||||||
echo "SSL certificates generated successfully"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create users file if it doesn't exist
|
|
||||||
if [ ! -f /app/data/config/users ]; then
|
|
||||||
echo "Creating initial users file..."
|
|
||||||
# Create users file with elastic user and password
|
|
||||||
echo 'elastic:$2a$10$BtVRGAoL8AbgEKnlvYj8cewQF3QkUz1pyL.Ga3j.jFKNUk2yh7.zW' > /app/data/config/users
|
|
||||||
echo 'kibana_system:$2a$10$BtVRGAoL8AbgEKnlvYj8cewQF3QkUz1pyL.Ga3j.jFKNUk2yh7.zW' >> /app/data/config/users
|
|
||||||
|
|
||||||
# Set permissions for the users file
|
|
||||||
chown elasticsearch:elasticsearch /app/data/config/users
|
|
||||||
chmod 600 /app/data/config/users
|
|
||||||
|
|
||||||
# Create users_roles file
|
|
||||||
echo 'superuser:elastic' > /app/data/config/users_roles
|
|
||||||
chown elasticsearch:elasticsearch /app/data/config/users_roles
|
|
||||||
chmod 600 /app/data/config/users_roles
|
|
||||||
|
|
||||||
echo "Users file created"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add a special setting to elasticsearch.yml to disable TLS security for HTTP
|
|
||||||
echo "Adding security settings to elasticsearch.yml..."
|
|
||||||
if ! grep -q "xpack.security.http.ssl.enabled" /app/data/config/elasticsearch.yml; then
|
|
||||||
echo "" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "# Security settings for Elasticsearch 8.x" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "xpack.security.enabled: true" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "xpack.security.http.ssl.enabled: false" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "xpack.security.transport.ssl.enabled: true" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "xpack.security.transport.ssl.verification_mode: none" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "xpack.security.authc.password_hashing.algorithm: bcrypt" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "Security settings added to elasticsearch.yml"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure network.host is set to 0.0.0.0 in elasticsearch.yml
|
|
||||||
if ! grep -q "network.host: 0.0.0.0" /app/data/config/elasticsearch.yml; then
|
|
||||||
echo "" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "# Set network host to all interfaces" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "network.host: 0.0.0.0" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "Network settings updated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure discovery.type is set to single-node
|
|
||||||
if ! grep -q "discovery.type: single-node" /app/data/config/elasticsearch.yml; then
|
|
||||||
echo "" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "# Single node setup" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "discovery.type: single-node" >> /app/data/config/elasticsearch.yml
|
|
||||||
echo "Discovery settings updated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure permissions are correct for writable directories
|
|
||||||
chown -R elasticsearch:elasticsearch /app/data/elasticsearch /app/data/logs /app/data/config /app/data/jdk /app/data/run /app/data/secrets
|
|
||||||
|
|
||||||
# Display network interfaces for debugging
|
|
||||||
ip a
|
|
||||||
|
|
||||||
# Enable system limits for elasticsearch
|
|
||||||
echo "Setting system limits for Elasticsearch..."
|
|
||||||
# Increase file descriptor limit
|
|
||||||
ulimit -n 65536 || echo "Warning: Could not set file descriptor limit"
|
|
||||||
# Allow memory locking
|
|
||||||
ulimit -l unlimited || echo "Warning: Could not set memory lock limit"
|
|
||||||
# Enable huge pages if available
|
|
||||||
echo never > /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null || true
|
|
||||||
# Set max map count if we have permission
|
|
||||||
sysctl -w vm.max_map_count=262144 2>/dev/null || echo "Warning: Could not set vm.max_map_count"
|
|
||||||
|
|
||||||
# Set required environment variables for Elasticsearch
|
|
||||||
export ES_HOME=/usr/share/elasticsearch
|
|
||||||
export ES_PATH_CONF=/app/data/config
|
|
||||||
|
|
||||||
# Calculate optimal heap size (50% of available memory, with 4GB default container limit)
|
|
||||||
# Default to 2GB if we can't determine container memory
|
|
||||||
CONTAINER_MEM=$(cat /sys/fs/cgroup/memory.max 2>/dev/null || echo "4294967296")
|
|
||||||
if [ "$CONTAINER_MEM" = "max" ]; then
|
|
||||||
CONTAINER_MEM="4294967296" # Default to 4GB if unlimited
|
|
||||||
fi
|
|
||||||
HEAP_SIZE=$(expr $CONTAINER_MEM / 2097152) # Convert to MB and take 50%
|
|
||||||
if [ $HEAP_SIZE -gt 31744 ]; then
|
|
||||||
# Elasticsearch has a maximum recommended heap size of 31GB
|
|
||||||
HEAP_SIZE=31744
|
|
||||||
fi
|
|
||||||
if [ $HEAP_SIZE -lt 512 ]; then
|
|
||||||
# Minimum recommended is 512MB
|
|
||||||
HEAP_SIZE=512
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set JVM options with calculated heap size
|
|
||||||
export ES_JAVA_OPTS="-Xms${HEAP_SIZE}m -Xmx${HEAP_SIZE}m"
|
|
||||||
|
|
||||||
# Add GC optimization flags
|
|
||||||
export ES_JAVA_OPTS="$ES_JAVA_OPTS -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30"
|
|
||||||
export PATH=$ES_HOME/bin:$PATH
|
|
||||||
|
|
||||||
# Additional JVM options to redirect GC logs
|
|
||||||
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"
|
|
||||||
|
|
||||||
# Pre-create PID file with proper permissions
|
|
||||||
touch /app/data/run/elasticsearch.pid
|
|
||||||
chown elasticsearch:elasticsearch /app/data/run/elasticsearch.pid
|
|
||||||
|
|
||||||
# Modify the Elasticsearch startup script to use our linked Java and writable PID file location
|
|
||||||
# Include additional parameters for security settings, using compatible settings for 8.x
|
|
||||||
ES_START_CMD="ES_PATH_CONF=/app/data/config ES_JAVA_HOME=/app/data/jdk /usr/share/elasticsearch/bin/elasticsearch -E xpack.security.enabled=true -E bootstrap.password=$ELASTIC_PASSWORD -d -p /app/data/run/elasticsearch.pid"
|
|
||||||
|
|
||||||
# Start Elasticsearch in the background
|
|
||||||
echo "Starting Elasticsearch..."
|
|
||||||
cd /usr/share/elasticsearch
|
|
||||||
|
|
||||||
# Execute Elasticsearch directly without using the elasticsearch-cli script
|
|
||||||
su -c "$ES_START_CMD" elasticsearch
|
|
||||||
|
|
||||||
# Wait for Elasticsearch to be up - checking for HTTP 200 response (without auth first)
|
|
||||||
echo "Waiting for Elasticsearch to start..."
|
|
||||||
attempts=0
|
|
||||||
max_attempts=60
|
|
||||||
until $(curl --output /dev/null --silent --head --fail http://localhost:9200); do
|
|
||||||
# Also check if Elasticsearch is running - sometimes it may have crashed
|
|
||||||
if ! ps -p $(cat /app/data/run/elasticsearch.pid 2>/dev/null) > /dev/null 2>&1; then
|
|
||||||
echo "Elasticsearch process is not running. Check logs at /app/data/logs/"
|
|
||||||
cat /app/data/logs/*.log
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf '.'
|
# Update JVM options for GC logs
|
||||||
sleep 5
|
if [ -f $ES_PATH_CONF/jvm.options ]; then
|
||||||
|
echo "Updating JVM options..."
|
||||||
attempts=$((attempts+1))
|
sed -i 's|logs/gc.log|/app/data/logs/gc/gc.log|g' $ES_PATH_CONF/jvm.options
|
||||||
|
|
||||||
if [ $attempts -ge $max_attempts ]; then
|
|
||||||
echo "Elasticsearch failed to start after 5 minutes. Check logs at /app/data/logs/"
|
|
||||||
cat /app/data/logs/*.log
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
echo "Elasticsearch is up and running!"
|
|
||||||
|
|
||||||
# Now that Elasticsearch is running, reset the elastic user password
|
# Generate SSL certificates if needed
|
||||||
echo "Setting elastic user password..."
|
if [ ! -f $ES_PATH_CONF/elastic-certificates.p12 ]; then
|
||||||
cd /usr/share/elasticsearch
|
echo "Generating self-signed certificates..."
|
||||||
echo "y" | ES_JAVA_HOME=/app/data/jdk bin/elasticsearch-reset-password -u elastic -b -p "$ELASTIC_PASSWORD" --url "http://localhost:9200" || true
|
|
||||||
|
|
||||||
# Test connection with the new password
|
mkdir -p /tmp/elastic-certs
|
||||||
echo "Testing connection with elastic user..."
|
ES_JAVA_HOME=/app/data/jdk $ES_HOME/bin/elasticsearch-certutil ca \
|
||||||
if curl -s -u elastic:$ELASTIC_PASSWORD http://localhost:9200; then
|
--out /tmp/elastic-certs/elastic-stack-ca.p12 \
|
||||||
echo "Authentication successful!"
|
--pass "" \
|
||||||
else
|
--silent
|
||||||
echo "Warning: Authentication failed. Check logs for details."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Display the credentials
|
ES_JAVA_HOME=/app/data/jdk $ES_HOME/bin/elasticsearch-certutil cert \
|
||||||
echo "-----------------------------"
|
--ca /tmp/elastic-certs/elastic-stack-ca.p12 \
|
||||||
echo "Elasticsearch is ready to use!"
|
--ca-pass "" \
|
||||||
echo "URL: http://localhost:9200"
|
--out $ES_PATH_CONF/elastic-certificates.p12 \
|
||||||
echo ""
|
--pass "" \
|
||||||
echo "Authentication credentials:"
|
--silent
|
||||||
echo " User: elastic"
|
|
||||||
echo " Password: $ELASTIC_PASSWORD"
|
|
||||||
echo " Note: Always use HTTP port 9200 for REST API connections"
|
|
||||||
echo "-----------------------------"
|
|
||||||
|
|
||||||
# Create a credentials file for reference
|
chown elasticsearch:elasticsearch $ES_PATH_CONF/elastic-certificates.p12
|
||||||
cat > /app/data/credentials.txt << EOL
|
chmod 600 $ES_PATH_CONF/elastic-certificates.p12
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create users file if needed
|
||||||
|
if [ ! -f $ES_PATH_CONF/users ]; then
|
||||||
|
echo "Creating users file..."
|
||||||
|
echo 'elastic:$2a$10$BtVRGAoL8AbgEKnlvYj8cewQF3QkUz1pyL.Ga3j.jFKNUk2yh7.zW' > $ES_PATH_CONF/users
|
||||||
|
echo 'kibana_system:$2a$10$BtVRGAoL8AbgEKnlvYj8cewQF3QkUz1pyL.Ga3j.jFKNUk2yh7.zW' >> $ES_PATH_CONF/users
|
||||||
|
|
||||||
|
echo 'superuser:elastic' > $ES_PATH_CONF/users_roles
|
||||||
|
|
||||||
|
chown elasticsearch:elasticsearch $ES_PATH_CONF/{users,users_roles}
|
||||||
|
chmod 600 $ES_PATH_CONF/{users,users_roles}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure basic settings in elasticsearch.yml
|
||||||
|
for setting in "xpack.security.http.ssl.enabled: false" "network.host: 0.0.0.0" "discovery.type: single-node"; do
|
||||||
|
if ! grep -q "$setting" $ES_PATH_CONF/elasticsearch.yml; then
|
||||||
|
echo "$setting" >> $ES_PATH_CONF/elasticsearch.yml
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set system limits
|
||||||
|
set_system_limits() {
|
||||||
|
echo "Setting system limits for Elasticsearch..."
|
||||||
|
ulimit -n 65536 || echo "Warning: Could not set file descriptor limit"
|
||||||
|
ulimit -l unlimited || echo "Warning: Could not set memory lock limit"
|
||||||
|
echo never > /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null || true
|
||||||
|
sysctl -w vm.max_map_count=262144 2>/dev/null || echo "Warning: Could not set vm.max_map_count"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
export PATH=$ES_HOME/bin:$PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start Elasticsearch
|
||||||
|
start_elasticsearch() {
|
||||||
|
# Create PID file
|
||||||
|
touch /app/data/run/elasticsearch.pid
|
||||||
|
chown elasticsearch:elasticsearch /app/data/run/elasticsearch.pid
|
||||||
|
|
||||||
|
# Command to start Elasticsearch
|
||||||
|
ES_START_CMD="ES_PATH_CONF=$ES_PATH_CONF ES_JAVA_HOME=/app/data/jdk $ES_HOME/bin/elasticsearch"
|
||||||
|
ES_START_CMD="$ES_START_CMD -E xpack.security.enabled=true -E bootstrap.password=$ELASTIC_PASSWORD"
|
||||||
|
ES_START_CMD="$ES_START_CMD -d -p /app/data/run/elasticsearch.pid"
|
||||||
|
|
||||||
|
echo "Starting Elasticsearch..."
|
||||||
|
cd $ES_HOME
|
||||||
|
su -c "$ES_START_CMD" elasticsearch
|
||||||
|
|
||||||
|
# Wait for Elasticsearch to start
|
||||||
|
echo "Waiting for Elasticsearch to start..."
|
||||||
|
attempts=0
|
||||||
|
max_attempts=60
|
||||||
|
until $(curl --output /dev/null --silent --head --fail http://localhost:9200); do
|
||||||
|
if ! ps -p $(cat /app/data/run/elasticsearch.pid 2>/dev/null) > /dev/null 2>&1; then
|
||||||
|
echo "ERROR: Elasticsearch process is not running. Logs:"
|
||||||
|
cat /app/data/logs/*.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '.'
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
attempts=$((attempts+1))
|
||||||
|
if [ $attempts -ge $max_attempts ]; then
|
||||||
|
echo "ERROR: Elasticsearch failed to start after 5 minutes. Logs:"
|
||||||
|
cat /app/data/logs/*.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "Elasticsearch is up and running!"
|
||||||
|
|
||||||
|
# Reset the elastic user password
|
||||||
|
cd $ES_HOME
|
||||||
|
echo "y" | ES_JAVA_HOME=/app/data/jdk bin/elasticsearch-reset-password -u elastic -b -p "$ELASTIC_PASSWORD" --url "http://localhost:9200" || true
|
||||||
|
|
||||||
|
# Create credentials file
|
||||||
|
cat > /app/data/credentials.txt << EOL
|
||||||
Elasticsearch credentials:
|
Elasticsearch credentials:
|
||||||
URL: http://localhost:9200
|
URL: http://localhost:9200
|
||||||
User: elastic
|
User: elastic
|
||||||
Password: $ELASTIC_PASSWORD
|
Password: $ELASTIC_PASSWORD
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
echo "Credentials saved to /app/data/credentials.txt"
|
echo "-----------------------------"
|
||||||
|
echo "Elasticsearch is ready to use!"
|
||||||
|
echo "URL: http://localhost:9200"
|
||||||
|
echo "User: elastic"
|
||||||
|
echo "Password: $ELASTIC_PASSWORD"
|
||||||
|
echo "-----------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
# Keep the script running to prevent the container from exiting
|
# Main execution flow
|
||||||
|
setup_java
|
||||||
|
configure_elasticsearch
|
||||||
|
[ ! -f /app/data/.initialized ] && touch /app/data/.initialized
|
||||||
|
|
||||||
|
# Ensure correct permissions
|
||||||
|
chown -R elasticsearch:elasticsearch /app/data/{elasticsearch,logs,config,jdk,run,secrets}
|
||||||
|
|
||||||
|
set_system_limits
|
||||||
|
configure_heap
|
||||||
|
start_elasticsearch
|
||||||
|
|
||||||
|
# Keep container running
|
||||||
tail -f /app/data/logs/*.log 2>/dev/null || sleep infinity
|
tail -f /app/data/logs/*.log 2>/dev/null || sleep infinity
|
Loading…
x
Reference in New Issue
Block a user