Merge pull request #2854 from alexbelgium/fix/elasticsearch-runtime-root-permission

fix(elasticsearch): stay root at runtime, fix upgrade permission failure
This commit is contained in:
Alexandre
2026-07-14 12:41:49 +02:00
committed by GitHub
3 changed files with 37 additions and 5 deletions

View File

@@ -8,8 +8,10 @@
- Removed the `ingest-attachment` plugin install: it is a bundled module since Elasticsearch 8.0.
- Startup persistence logic rewritten as a proper init script (`/usr/local/bin/addon-init.sh`) instead of line-number-based entrypoint patching.
- Added `updater.json` so upstream 8.19.x releases are tracked automatically (pinned to the 8.19 line: 9.x cannot read indices created in 7.x).
- The upstream 8.x image ends the build as a non-root user with a read-only entrypoint; the Dockerfile now switches to root for the build steps that patch/install into it and restores the Elasticsearch user before runtime.
- The upstream 8.x image ends the build as a non-root user with a read-only entrypoint; the Dockerfile now switches to root for the build steps that patch/install into it. The container also starts as root (unchanged from 7.17.9) so `addon-init.sh` can chown/move pre-existing `/data` content that may be owned by root from earlier installs; unlike 7.17.9's own entrypoint, the upstream 8.x entrypoint no longer drops privileges before starting Elasticsearch (which refuses to run as root), so `addon-init.sh` now does that itself via `chroot --userspec=1000:0` once its root-only work is done.
- `env_vars` names starting with a digit are now rejected before export instead of crashing the entrypoint.
- Fixed a startup failure (`mv: cannot move '/data/config' ... Permission denied`) on upgrade from an existing 7.17.9 install, caused by an earlier fix in this same release that switched the runtime user to non-root before this fix was in place.
- Fixed a second regression from that same fix: without a privilege drop before starting Elasticsearch, both fresh installs and upgrades would fail Elasticsearch's own root-check ("can not run elasticsearch as root").
## 8.14.3-3 (2026-06-19)
- Fix startup failing with `chroot: cannot change root directory` by allowing `capability sys_chroot` in the AppArmor profile (#2709)

View File

@@ -141,5 +141,10 @@ HEALTHCHECK \
--timeout=25s \
CMD curl -A "HealthCheck: Docker/1.0" -s -f "http://127.0.0.1:${HEALTH_PORT}${HEALTH_URL}" &>/dev/null || exit 1
# Restore the Elasticsearch user for runtime, matching the base image
USER 1000:0
# Start as root: addon-init.sh needs it to chown/move pre-existing /data
# content that may be owned by root from earlier installs. It drops to
# uid 1000 itself (via chroot --userspec) before Elasticsearch actually
# starts, since Elasticsearch refuses to run as root and the upstream 8.x
# entrypoint no longer does that drop on its own (7.x's did). This matches
# the addon's own AppArmor profile (chown, setuid, setgid, sys_chroot,
# mount capabilities).

View File

@@ -1,14 +1,25 @@
#!/bin/bash
# shellcheck shell=bash
# Sourced by /usr/local/bin/docker-entrypoint.sh (right after "set -e"),
# before Elasticsearch starts. Runs as root when the Supervisor starts the
# container; the official entrypoint then drops privileges itself.
# before Elasticsearch starts. The container starts as root (see
# Dockerfile) so this script can chown/move pre-existing /data content
# that may be owned by root from earlier installs. Elasticsearch itself
# refuses to run as root, and unlike 7.x the upstream 8.x entrypoint no
# longer drops privileges on its own, so this script does it at the end
# (section 6) by re-execing the entrypoint as uid 1000. On that re-exec'd
# pass this script just returns immediately (see the guard right below).
#
# Responsibilities:
# 1. Export user env_vars from /data/options.json
# 2. Default xpack.security.enabled=false (7.x behavior) unless user overrides
# 3. Relocate data & config to /data for persistence (idempotent)
# 4. Guard major-version data migrations (7.x -> 8.x is automatic)
# 5. Record the running version once Elasticsearch is confirmed healthy
# 6. Drop root privileges before Elasticsearch actually starts
if [ -n "${_ADDON_INIT_REEXEC:-}" ]; then
return 0
fi
echo "-----------------------------------------------------------"
echo " Add-on: Elasticsearch server"
@@ -140,3 +151,17 @@ if [ "$data_version" != "$current_version" ]; then
done
) &
fi
############################
# 6 Drop privileges #
############################
# Elasticsearch refuses to start as root ("can not run elasticsearch as
# root"). 7.x's own entrypoint dropped to uid 1000 via chroot before
# launching Elasticsearch; 8.x no longer does that, so do it here instead,
# then let the entrypoint continue as uid 1000 (matches the sys_chroot /
# setuid / setgid capabilities already granted in the AppArmor profile).
if [ "$(id -u)" -eq 0 ]; then
export _ADDON_INIT_REEXEC=1
exec chroot --userspec=1000:0 / /usr/local/bin/docker-entrypoint.sh "$@"
fi