Skip to content

geoserver image: add non-root / arbitrary-UID support (root remains default) - #84

Open
jwkaltz wants to merge 2 commits into
GeoNode:masterfrom
jwkaltz:rootless_geoserver_image
Open

geoserver image: add non-root / arbitrary-UID support (root remains default)#84
jwkaltz wants to merge 2 commits into
GeoNode:masterfrom
jwkaltz:rootless_geoserver_image

Conversation

@jwkaltz

@jwkaltz jwkaltz commented Jun 26, 2026

Copy link
Copy Markdown

Fixes #83

Makes the geoserver image able to run as a non-root user, including an arbitrary UID assigned at runtime. The image continues to run as root by default, so this is backward compatible.

Rebased onto #85, so this now builds on the current layout (Java 17 / GeoServer 2.28.4, helper scripts in /usr/local/bin, data dir populated at runtime from the skeleton archive). The points below are the non-root adjustments on top of that.

Changes

Scripts (/usr/local/bin):

  • entrypoint.sh / set_geoserver_auth.sh: replace the hardcoded /root home with
    ${GEOSERVER_HOME} (defaults to /root, preserving current behavior when running as
    root). The .bashrc / .override_env sourcing is guarded with [ -f ] so missing
    files are skipped instead of aborting under set -e.
  • entrypoint.sh: check that GEOSERVER_HOME is writable, so a non-root run without a
    writable home fails early with a clear message.
  • set_geoserver_auth.sh: write the temp file via mktemp instead of xml.tmp in the
    current working directory (not writable for a non-root user), and add explicit error
    handling on the write-back.

Dockerfile:

  • Add a geoserver user (configurable GEOSERVER_UID, default 1000) in group 0, with
    chmod g=u on the writable dirs so the image can run as any UID in group 0. No USER
    statement is added — root stays the default. Ownership is set to ${GEOSERVER_UID}:0;
    running as root is unaffected since root ignores file permissions.
  • Move two always-constant runtime edits to build time (the xom/bcprov exclusion in
    catalina.properties, and creating conf/Catalina/localhost) and set -XX:LogFile
    to /tmp/jvm.log. This lets the image also run under readOnlyRootFilesystem when the
    scratch dirs are mounted writable — optional, not required.

Backward compatibility

Root remains the default user and the default GEOSERVER_HOME falls back to /root, so
existing root-based deployments are unaffected. GEOSERVER_HOME is configurable for
non-root use (e.g. /tmp, or a writable volume mounted over /home/geoserver).

Testing

Verified the rebased image (GeoServer 2.28.4) in these modes:

  • root (default, no flags): starts and self-populates the data dir as before;
    GEOSERVER_HOME falls back to /root.
  • non-root without GEOSERVER_HOME: fails fast with a clear message.
  • non-root with a writable GEOSERVER_HOME, both --user 1000:0 and an arbitrary UID
    (e.g. 4711:0): starts correctly and is fully functional.
  • In the geonode-k8s chart with readOnlyRootFilesystem: runs non-root with
    GEOSERVER_HOME=/home/geoserver; raster upload via GeoNode and serving via GeoServer
    both work (shared statics volume mounted read-only into GeoServer, common fsGroup).

@giohappy

Copy link
Copy Markdown
Contributor

@jwkaltz I haven't reviewed the changes (and the conflicts yet), but how did you manage the shared raster data between GeoNode and GeoServer? You know that raster uploads are stored and served from a shared volume.

@jwkaltz

jwkaltz commented Aug 11, 2026

Copy link
Copy Markdown
Author

@jwkaltz I haven't reviewed the changes (and the conflicts yet), but how did you manage the shared raster data between GeoNode and GeoServer? You know that raster uploads are stored and served from a shared volume.

@giohappy thanks for the note, I see that #85 made significant differences to these files. I will try to rewrite my pull request (resolving the conflicts), redo tests and get back to you.

@jwkaltz
jwkaltz force-pushed the rootless_geoserver_image branch from b9f3c3b to d9f2e80 Compare August 11, 2026 11:36
@jwkaltz

jwkaltz commented Aug 11, 2026

Copy link
Copy Markdown
Author

@jwkaltz I haven't reviewed the changes (and the conflicts yet), but how did you manage the shared raster data between GeoNode and GeoServer? You know that raster uploads are stored and served from a shared volume.

@giohappy I have rebased the pull request and tested the new version successfully (see "Testing" section in the description). Regarding your question,

  • by default, this image will still run as root (but allow to run as non-root),
  • in my environment, GeoNode and GeoServer run with the same user ID, the shared raster data therefore belongs to this one user ID,
  • but I also tested just now when deploying GeoServer with a different user ID than GeoNode: that also works, because of the generous directory and file permissions GeoNode uses for uploads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make the geoserver image runnable as a non-root user (incremental hardening)

2 participants