Docker环境下ELK Stack中Docker Secrets配置失效问题求助
Let's break down why your current setup isn't working and how to fix it, plus a more native alternative aligned with Elasticsearch's best practices.
Root Cause of Your Issue
When you run source /env_secrets_expand.sh in your custom entrypoint, the script modifies variables in the current shell—but only exported variables get passed to the child process (the original Elasticsearch entrypoint you exec into). If your script doesn't explicitly export the updated values, the Elasticsearch process will never see them.
Also, your test method using docker exec is misleading: the shell spawned by docker exec inherits the container's initial environment variables, not the modified ones from your entrypoint's shell. To verify if the Elasticsearch process sees the correct values, you need to check the environment of the running container process (PID 1).
Fix for Your Current Setup
Step 1: Update env_secrets_expand.sh to Export Variables
Modify your script to explicitly export the updated environment variables so they're passed to the child process:
#!/bin/bash # Expand environment variables referencing Docker Secrets for env_var in $(printenv | grep -E '={{DOCKER-SECRET:[a-z0-9-]+}}' | cut -d'=' -f1); do # Extract secret name from the placeholder secret_name=$(echo "${!env_var}" | sed -e 's/={{DOCKER-SECRET://' -e 's/}}$//') # Read secret value from Docker Secrets mount secret_value=$(cat "/run/secrets/$secret_name") # Update and export the variable export "$env_var=$secret_value" done
Step 2: Verify the Fix Correctly
Instead of using docker exec to check variables, inspect the environment of the running Elasticsearch process:
# Get your container's name/ID CONTAINER_ID=$(docker compose ps -q setup) # Check PID 1's environment variables (the Elasticsearch process) docker exec "$CONTAINER_ID" cat /proc/1/environ | tr '\0' '\n' | grep ELASTIC_PASSWORD
This should return the correct secret value (pass4elastic) instead of the placeholder.
Better Alternative: Use Elasticsearch Keystore (Native Approach)
Elasticsearch provides a built-in keystore for sensitive configuration, which is more secure and aligned with official best practices than environment variables. Here's how to set it up:
1. Simplify docker-compose.yml
Remove the environment variable placeholder—we'll use the keystore instead:
version: "3.8" services: setup: build: . secrets: - elk-elastic-password secrets: elk-elastic-password: file: ./elk-elastic-password.txt
2. Update Custom docker-entrypoint.sh
Import the secret directly into Elasticsearch's keystore before starting the service:
#!/bin/bash # Create keystore if it doesn't exist elasticsearch-keystore create # Add bootstrap password from Docker Secret (suppress output with -x) elasticsearch-keystore add -x bootstrap.password < /run/secrets/elk-elastic-password # Launch Elasticsearch with the original entrypoint exec /bin/tini -- /usr/local/bin/docker-entrypoint.sh "$@"
3. Simplify Dockerfile
You no longer need env_secrets_expand.sh, so streamline your Dockerfile:
FROM docker.elastic.co/elasticsearch/elasticsearch:8.0.0 COPY docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh ENTRYPOINT ["/docker-entrypoint.sh"]
This approach avoids environment variable manipulation entirely and uses Elasticsearch's native secure configuration system.
内容的提问来源于stack exchange,提问作者Marcin

