Skip to content
Closed
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
75 changes: 75 additions & 0 deletions core/docker/usr/local/tomcat/bin/docker-start-print
Original file line number Diff line number Diff line change
@@ -1,7 +1,82 @@
#!/bin/bash -e

export JAVA_OPTS="--add-opens=java.desktop/sun.awt.image=ALL-UNNAMED ${JAVA_OPTS}"

normalize_context_path() {
local raw="${1:-}"
if [[ -z "${raw}" || "${raw}" == "/" ]]; then
echo ""
return 0
fi

if [[ "${raw}" != /* ]]; then
raw="/${raw}"
fi

# Remove trailing slashes (keep the leading slash)
while [[ "${raw}" != "/" && "${raw}" == */ ]]; do
raw="${raw%/}"
done

# Conservative validation: allow common URL path chars
if [[ ! "${raw}" =~ ^/[A-Za-z0-9._/-]+$ ]]; then
echo "ERROR: Invalid CONTEXT_PATH: '${1}'. Expected like '/print' or '/foo/bar'." >&2
exit 2
fi

echo "${raw}"
}

apply_context_path() {
local context_path="${1}"
if [[ -z "${context_path}" ]]; then
return 0
fi

echo "Configuring CONTEXT_PATH='${context_path}'"

local web_xml="WEB-INF/web.xml"
if [[ ! -w "${web_xml}" ]]; then
echo "ERROR: CONTEXT_PATH is set but '${web_xml}' is not writable." >&2
echo " If you run with a read-only root filesystem, mount a writable volume over" >&2
echo " /usr/local/tomcat/webapps/ROOT (or at least WEB-INF and the context-path folder)." >&2
exit 1
fi

# Prefix servlet url-patterns. This makes deployments behind a reverse proxy under a sub path
# (where the proxy does NOT strip the prefix) work out of the box.
# Idempotent: only rewrites the original patterns.
sed -i \
-e "s|<url-pattern>/metrics</url-pattern>|<url-pattern>${context_path}/metrics</url-pattern>|g" \
-e "s|<url-pattern>/metrics/\*</url-pattern>|<url-pattern>${context_path}/metrics/*</url-pattern>|g" \
-e "s|<url-pattern>/print/\*</url-pattern>|<url-pattern>${context_path}/print/*</url-pattern>|g" \
-e "s|<url-pattern>/sec/print/\*</url-pattern>|<url-pattern>${context_path}/sec/print/*</url-pattern>|g" \
"${web_xml}"

# Make the UI reachable under the context path by copying the static files.
# Example: CONTEXT_PATH=/print -> /usr/local/tomcat/webapps/ROOT/print/index.html
local ui_dir=".${context_path}"
mkdir -p "${ui_dir}"
for f in index.html favicon.ico mapfish_transparent.png; do
if [[ -f "${f}" ]]; then
cp -f "${f}" "${ui_dir}/"
fi
done

if [[ -w "${ui_dir}/index.html" ]]; then
# Ensure exactly one <base> tag, so relative links resolve via the external prefix.
sed -i '/<base[[:space:]]\+href=/d' "${ui_dir}/index.html"
sed -i "/<\/head>/i\\ <base href=\"${context_path}/\" />" "${ui_dir}/index.html"
else
echo "WARNING: Unable to update '${ui_dir}/index.html' to set <base href>." >&2
fi
}

cd /usr/local/tomcat/webapps/ROOT

CONTEXT_PATH_NORMALIZED="$(normalize_context_path "${CONTEXT_PATH:-}")"
apply_context_path "${CONTEXT_PATH_NORMALIZED}"

PG_LIB=$(find WEB-INF/lib -name "postgresql-*")

# Checks if Database is present (DB is compulsory in cluster mode)
Expand Down
52 changes: 52 additions & 0 deletions docs/src/main/resources/templates/docker.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ <h4 id="docker_tunings">
<p>The docker image can be tuned with several environment variables:</p>
<ul>
<li><code>CATALINA_OPTS</code>: Java startup parameters.</li>
<li>
<code>CONTEXT_PATH</code>: Optional external URL prefix (sub path) when the service is exposed behind a
reverse proxy under a sub path (for example <code>/print</code> or <code>/foo/bar</code>). When set, the
container entrypoint will:
<ul>
<li>
Prefix the servlet mappings (for example <code>/metrics</code> becomes <code>/print/metrics</code>).
</li>
Comment on lines +34 to +35

Copilot AI Feb 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation example is slightly misleading. It states that /metrics becomes /print/metrics, which is correct. However, it doesn't clarify what happens to the existing /print/* servlet mapping. With CONTEXT_PATH=/print, the servlet mapping /print/* would become /print/print/*, meaning the print API would be accessible at /print/print/... rather than just /print/.... This could confuse users.

Consider adding a note that the CONTEXT_PATH should not conflict with existing servlet paths (/print or /sec/print), or document the resulting double-path behavior explicitly.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

<li>
Copy the UI assets (index + icons) under the sub path (for example <code>/print/index.html</code>).
</li>
<li>
Inject a <code>&lt;base href=&quot;/print/&quot;&gt;</code> tag into the copied UI page so relative
links work.
</li>
</ul>
This mode is intended for proxies/ingresses that forward the prefixed path as-is (no path rewrite).
</li>
<li><code>DEFAULT_LOG_LEVEL</code>: Set the default log level (defaults to <code>INFO</code>)</li>
<li><code>TOMCAT_LOG_LEVEL</code>: Set the tomcat log level (defaults to <code>INFO</code>)</li>
<li><code>LOG_LEVEL</code>: Set the mapfish print log level (defaults to <code>INFO</code>)</li>
Expand Down Expand Up @@ -79,6 +97,40 @@ <h4 id="docker_tunings">
</li>
</ul>

<h4 id="docker_filesystem">
Filesystem writes
<a class="headerlink" href="#docker_filesystem" title="Permalink to this headline">¶</a>
</h4>

<p>
The container expects to be able to write to some paths at runtime. If you run with a read-only root
filesystem, ensure those locations are writable (for example by mounting an <code>emptyDir</code> or other
volume), or use an init container to copy the webapp content to a writable volume.
</p>

<ul>
<li><code>/usr/local/tomcat/webapps/ROOT/print-apps</code>: created at startup (print apps directory).</li>
<li>
<code>/usr/local/tomcat/temp/mapfish-print/ROOT</code>: used by the graceful shutdown mechanism (<code
>docker-pre-stop-print</code
>
creates <code>stop</code>/<code>stopped</code> files here).
</li>
<li>
If <code>CONTEXT_PATH</code> is set:
<ul>
<li>
<code>/usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml</code>: rewritten at startup to prefix URL
mappings.
</li>
<li>
<code>/usr/local/tomcat/webapps/ROOT&lt;CONTEXT_PATH&gt;</code>: created and populated with UI assets
(for example <code>/usr/local/tomcat/webapps/ROOT/print</code>).
</li>
</ul>
</li>
</ul>

<p>
If you want to tune properties from
<a
Expand Down
Loading