Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ and includes the full set of [free
features](https://www.elastic.co/subscriptions).

View the detailed release notes
[here](https://www.elastic.co/guide/en/elasticsearch/reference/8.17/es-release-notes.html).
[here](https://www.elastic.co/guide/en/elasticsearch/reference/9.3/es-release-notes.html).
142 changes: 142 additions & 0 deletions elasticsearch/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@


################################################################################
# Build stage 1 `builder`:
# Extract Elasticsearch artifact
################################################################################

FROM redhat/ubi9-minimal:latest AS builder

RUN microdnf install -y findutils tar gzip

# `tini` is a tiny but valid init for containers. This is used to cleanly
# control how ES and any child processes are shut down.
#
# The tini GitHub page gives instructions for verifying the binary using
# gpg, but the keyservers are slow to return the key and this can fail the
# build. Instead, we check the binary against the published checksum.
RUN set -eux; \
arch="$(rpm --query --queryformat='%{ARCH}' rpm)"; \
case "$arch" in \
aarch64) tini_bin='tini-arm64'; tini_sum='07952557df20bfd2a95f9bef198b445e006171969499a1d361bd9e6f8e5e0e81' ;; \
x86_64) tini_bin='tini-amd64'; tini_sum='93dcc18adc78c65a028a84799ecf8ad40c936fdfc5f2a57b1acda5a8117fa82c' ;; \
*) echo >&2 "Unsupported architecture $arch"; exit 1 ;; \
esac ; \
curl -f --retry 10 -S -L -o /tmp/tini https://github.com/krallin/tini/releases/download/v0.19.0/${tini_bin}; \
echo "${tini_sum} /tmp/tini" | sha256sum -c -; \
mv /tmp/tini /bin/tini; \
chmod 0555 /bin/tini

WORKDIR /usr/share/elasticsearch
RUN arch="$(rpm --query --queryformat='%{ARCH}' rpm)" && curl -f --retry 10 -S -L --output /tmp/elasticsearch.tar.gz https://artifacts-no-kpi.elastic.co/downloads/elasticsearch/elasticsearch-9.3.0-linux-$arch.tar.gz
RUN tar -zxf /tmp/elasticsearch.tar.gz --strip-components=1 && \
# Configure the distribution for Docker
sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elasticsearch-env && \
# Create required directory
mkdir data && \
# Reset permissions on all directories
find . -type d -exec chmod 0555 {} + && \
# keep default elasticsearch log4j config
mv config/log4j2.properties config/log4j2.file.properties && \
# Reset permissions on all files
find . -type f -exec chmod 0444 {} + && \
# Make CLI tools executable
chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper modules/x-pack-ml/platform/linux-*/bin/* && \
# Make some directories writable. `bin` must be writable because
# plugins can install their own CLI utilities.
chmod 0775 bin config config/jvm.options.d data logs plugins && \
# Make some files writable
find config -type f -exec chmod 0664 {} + && \
# Tighten up permissions on the ES home dir (the permissions of the contents are handled below)
chmod 0775 . && \
# You can't install plugins that include configuration when running as `elasticsearch` and the `config`
# dir is owned by `root`, because the installed tries to manipulate the permissions on the plugin's
# config directory.
chown 1000:1000 bin config config/jvm.options.d data logs plugins

# The distribution includes a `config` directory, no need to create it
COPY --chmod=664 config/elasticsearch.yml config/log4j2.properties config/

################################################################################
# Build stage 2 (the actual Elasticsearch image):
#
# Copy elasticsearch from stage 1
# Add entrypoint
################################################################################

FROM redhat/ubi9-minimal:latest

RUN microdnf install --setopt=tsflags=nodocs -y \
nc shadow-utils zip unzip findutils procps-ng && \
microdnf clean all

RUN groupadd -g 1000 elasticsearch && \
adduser -u 1000 -g 1000 -G 0 -d /usr/share/elasticsearch elasticsearch && \
chown -R 0:0 /usr/share/elasticsearch

ENV ELASTIC_CONTAINER=true

COPY --from=builder /bin/tini /bin/tini

WORKDIR /usr/share/elasticsearch

COPY --from=builder --chown=0:0 /usr/share/elasticsearch .

# Replace OpenJDK's built-in CA certificate keystore with the one from the OS
# vendor. The latter is superior in several ways.
# REF: https://github.com/elastic/elasticsearch-docker/issues/171
RUN ln -sf /etc/pki/ca-trust/extracted/java/cacerts jdk/lib/security/cacerts

ENV PATH=/usr/share/elasticsearch/bin:$PATH
ENV SHELL=/bin/bash

COPY --chmod=0555 bin/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

RUN chmod g=u /etc/passwd && \
find / -xdev -perm -4000 -exec chmod ug-s {} + && \
chmod 0775 /usr/share/elasticsearch && \
chown elasticsearch bin config config/jvm.options.d data logs plugins

EXPOSE 9200 9300

LABEL org.label-schema.build-date="2026-01-29T10:05:46.708397977Z" \
org.label-schema.license="Elastic-License-2.0" \
org.label-schema.name="Elasticsearch" \
org.label-schema.schema-version="1.0" \
org.label-schema.url="https://www.elastic.co/products/elasticsearch" \
org.label-schema.usage="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \
org.label-schema.vcs-ref="17b451d8979a29e31935fe1eb901310350b30e62" \
org.label-schema.vcs-url="https://github.com/elastic/elasticsearch" \
org.label-schema.vendor="Elastic" \
org.label-schema.version="9.3.0" \
org.opencontainers.image.created="2026-01-29T10:05:46.708397977Z" \
org.opencontainers.image.documentation="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \
org.opencontainers.image.licenses="Elastic-License-2.0" \
org.opencontainers.image.revision="17b451d8979a29e31935fe1eb901310350b30e62" \
org.opencontainers.image.source="https://github.com/elastic/elasticsearch" \
org.opencontainers.image.title="Elasticsearch" \
org.opencontainers.image.url="https://www.elastic.co/products/elasticsearch" \
org.opencontainers.image.vendor="Elastic" \
org.opencontainers.image.version="9.3.0"

LABEL name="Elasticsearch" \
maintainer="infra@elastic.co" \
vendor="Elastic" \
version="9.3.0" \
release="1" \
summary="Elasticsearch" \
description="You know, for search."

RUN mkdir /licenses && ln LICENSE.txt /licenses/LICENSE

# Our actual entrypoint is `tini`, a minimal but functional init program. It
# calls the entrypoint we provide, while correctly forwarding signals.
ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
# Dummy overridable parameter parsed by entrypoint
CMD ["eswrapper"]

USER 1000:0

################################################################################
# End of multi-stage Dockerfile
################################################################################
84 changes: 84 additions & 0 deletions elasticsearch/bin/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash
set -e

# Files created by Elasticsearch should always be group writable too
umask 0002

# Allow user specify custom CMD, maybe bin/elasticsearch itself
# for example to directly specify `-E` style parameters for elasticsearch on k8s
# or simply to run /bin/bash to check the image
if [[ "$1" == "eswrapper" || $(basename "$1") == "elasticsearch" ]]; then
# Rewrite CMD args to remove the explicit command,
# so that we are backwards compatible with the docs
# from the previous Elasticsearch versions < 6
# and configuration option:
# https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docker.html#_d_override_the_image_8217_s_default_ulink_url_https_docs_docker_com_engine_reference_run_cmd_default_command_or_options_cmd_ulink
# Without this, user could specify `elasticsearch -E x.y=z` but
# `bin/elasticsearch -E x.y=z` would not work. In any case,
# we want to continue through this script, and not exec early.
set -- "${@:2}"
else
# Run whatever command the user wanted
exec "$@"
fi

# Allow environment variables to be set by creating a file with the
# contents, and setting an environment variable with the suffix _FILE to
# point to it. This can be used to provide secrets to a container, without
# the values being specified explicitly when running the container.
#
# This is also sourced in elasticsearch-env, and is only needed here
# as well because we use ELASTIC_PASSWORD below. Sourcing this script
# is idempotent.
source /usr/share/elasticsearch/bin/elasticsearch-env-from-file

if [[ -f bin/elasticsearch-users ]]; then
# Check for the ELASTIC_PASSWORD environment variable to set the
# bootstrap password for Security.
#
# This is only required for the first node in a cluster with Security
# enabled, but we have no way of knowing which node we are yet. We'll just
# honor the variable if it's present.
if [[ -n "$ELASTIC_PASSWORD" ]]; then
[[ -f /usr/share/elasticsearch/config/elasticsearch.keystore ]] || (elasticsearch-keystore create)
if ! (elasticsearch-keystore has-passwd --silent) ; then
# keystore is unencrypted
if ! (elasticsearch-keystore list | grep -q '^bootstrap.password$'); then
(echo "$ELASTIC_PASSWORD" | elasticsearch-keystore add -x 'bootstrap.password')
fi
else
# keystore requires password
if ! (echo "$KEYSTORE_PASSWORD" \
| elasticsearch-keystore list | grep -q '^bootstrap.password$') ; then
COMMANDS="$(printf "%s\n%s" "$KEYSTORE_PASSWORD" "$ELASTIC_PASSWORD")"
(echo "$COMMANDS" | elasticsearch-keystore add -x 'bootstrap.password')
fi
fi
fi
fi

if [[ -n "$ES_LOG_STYLE" ]]; then
case "$ES_LOG_STYLE" in
console)
# This is the default. Nothing to do.
;;
file)
# Overwrite the default config with the stack config. Do this as a
# copy, not a move, in case the container is restarted.
cp -f /usr/share/elasticsearch/config/log4j2.file.properties /usr/share/elasticsearch/config/log4j2.properties
;;
*)
echo "ERROR: ES_LOG_STYLE set to [$ES_LOG_STYLE]. Expected [console] or [file]" >&2
exit 1 ;;
esac
fi

if [[ -n "$ENROLLMENT_TOKEN" ]]; then
POSITIONAL_PARAMETERS="--enrollment-token $ENROLLMENT_TOKEN"
else
POSITIONAL_PARAMETERS=""
fi

# Signal forwarding and child reaping is handled by `tini`, which is the
# actual entrypoint of the container
exec /usr/share/elasticsearch/bin/elasticsearch "$@" $POSITIONAL_PARAMETERS <<<"$KEYSTORE_PASSWORD"
13 changes: 13 additions & 0 deletions elasticsearch/bin/docker-openjdk
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

set -Eeuo pipefail

# Update "cacerts" bundle to use Ubuntu's CA certificates (and make sure it
# stays up-to-date with changes to Ubuntu's store)

trust extract \
--overwrite \
--format=java-cacerts \
--filter=ca-anchors \
--purpose=server-auth \
/usr/share/elasticsearch/jdk/lib/security/cacerts
2 changes: 2 additions & 0 deletions elasticsearch/config/elasticsearch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cluster.name: "docker-cluster"
network.host: 0.0.0.0
Loading