When running an initialization script to create a new index on startup, authentication fails with default username and password (elastic:changeme). Waiting a few seconds then manually running the exact same command works perfectly. My current workaround is to call the health status endpoint in a loop until the request doesn't fail from an authentication error, then I run my index init script. This feels hacky and I'm wondering if there's a better way to create an index automatically when the container starts.
Elastic Search Version
Version: 5.4.0, Build: 780f8c4/2017-04-28T17:43:27.229Z
Plugins
analysis-icu
JVM
JVM: 1.8.0_131
OS
Linux 4464d613c8d6 4.9.60-linuxkit-aufs #1 SMP Mon Nov 6 16:00:12 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Inside official Docker image for 5.4, though with a different docker-entrypoint.sh script
Steps to reproduce:
Dockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:5.4.0
RUN bin/elasticsearch-plugin install analysis-icu
COPY docker-entrypoint.sh /docker-entrypoint.sh
COPY config/elasticsearch.yml config/elasticsearch.yml
COPY config/setup.sh config/setup.sh
RUN mkdir utils
COPY utils/wait-for-it.sh utils/wait-for-it.sh
USER root
RUN chmod +x /docker-entrypoint.sh utils/wait-for-it.sh config/setup.sh
RUN chown -R elasticsearch:elasticsearch /docker-entrypoint.sh utils/wait-for-it.sh config/setup.sh
USER elasticsearch
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/usr/share/elasticsearch/bin/elasticsearch"]
elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
# minimum_master_nodes need to be explicitly set when bound on a public IP
# set to 1 to allow single node clusters
# Details: https://github.com/elastic/elasticsearch/pull/17288
discovery.zen.minimum_master_nodes: 1
# By default the low water mark threshold will stop the node from starting
# if your dev machine doesn't have at least 15% free. This is generally
# less of a mission critical threshold when in Docker on a dev machine
cluster.routing.allocation.disk.threshold_enabled: false
docker-entrypoint.sh
#!/bin/sh
# wait for Elasticsearch to start, then run the setup script to
# create and configure the index.
exec /usr/share/elasticsearch/utils/wait-for-it.sh localhost:9200 -- /usr/share/elasticsearch/config/setup.sh &
exec $@
setup.sh
#!/bin/sh
echo Initiating Elasticsearch Custom Index
# move to the directory of this setup script
cd "$(dirname "$0")"
# for some reason even when port 9200 is open Elasticsearch is unable to be accessed as authentication fails
# a few seconds later it works
until $(curl -sSf -XGET --insecure --user elastic:changeme 'http://localhost:9200/_cluster/health?wait_for_status=yellow' > /dev/null); do
printf 'AUTHENTICATION ERROR DUE TO X-PACK, trying again in 5 seconds \n'
sleep 5
done
# create a new index with the settings in es_index_config.json
curl -v --insecure --user elastic:changeme -XPUT '0.0.0.0:9200/test?pretty' -H 'Content-Type: application/json' -d @es_index_config.json
logs:
[WARN ][o.e.x.s.a.AuthenticationService] [TL7bL2I] An unexpected error occurred while attempting to authenticate [elastic] against realm [reserved]
org.elasticsearch.ElasticsearchSecurityException: failed to authenticate user [elastic]
...
curl: (22) The requested URL returned error: 401
Then after the loop in setup.sh waits 5 seconds
[2018-04-03T02:00:17,596][INFO ][o.e.l.LicenseService ] [TL7bL2I] license [bafce55a-1a94-43a4-b3c2-827ec185e237] mode [trial] - valid
* About to connect() to 0.0.0.0 port 9200 (#0)
* Trying 0.0.0.0...
* Connected to 0.0.0.0 (0.0.0.0) port 9200 (#0)
* Server auth using Basic with user 'elastic'