Skip to content

Add graceful shutdown handling in docker entrypoint scripts#613

Open
manodyaSenevirathne wants to merge 2 commits intowso2:masterfrom
manodyaSenevirathne:master
Open

Add graceful shutdown handling in docker entrypoint scripts#613
manodyaSenevirathne wants to merge 2 commits intowso2:masterfrom
manodyaSenevirathne:master

Conversation

@manodyaSenevirathne
Copy link
Copy Markdown

@manodyaSenevirathne manodyaSenevirathne commented Apr 9, 2026

Purpose

$Subject

Summary by CodeRabbit

  • Bug Fixes
    • Improved graceful shutdown and signal handling across Alpine, Rocky, and Ubuntu container images for API Manager, Key Manager, Traffic Manager, and Universal Gateway — containers now run server processes in the background, respond to SIGTERM/SIGINT, invoke orderly stop actions, and wait for clean termination.
  • Chores
    • Minor metadata updates (copyright year) in entrypoint scripts.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

Entrypoint scripts now start the WSO2 server processes in the background, record their PIDs, register a SIGTERM/SIGINT trap that runs a stop_handler calling the profile-specific stop command (errors ignored), and wait on the recorded PID to coordinate graceful shutdown.

Changes

Cohort / File(s) Summary
ACP / Key-Manager Entrypoints
dockerfiles/alpine/apim-acp/docker-entrypoint.sh, dockerfiles/rocky/apim-acp/docker-entrypoint.sh, dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh
Start key-manager / api-cp in background, capture server_pid, add stop_handler() that invokes *.sh stop (using `
Traffic Manager Entrypoints
dockerfiles/alpine/apim-tm/docker-entrypoint.sh, dockerfiles/rocky/apim-tm/docker-entrypoint.sh, dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh
Run traffic-manager.sh in background, set server_pid, add stop_handler() to call traffic-manager.sh stop (errors ignored), trap SIGTERM/SIGINT, then wait on the server PID.
Universal Gateway Entrypoints
dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh, dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh, dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
Launch gateway.sh in background, record server_pid, add stop_handler() that invokes gateway.sh stop (with `
API Manager Entrypoints
dockerfiles/alpine/apim/docker-entrypoint.sh, dockerfiles/rocky/apim/docker-entrypoint.sh, dockerfiles/ubuntu/apim/docker-entrypoint.sh
Start api-manager.sh in background, capture server_pid, add stop_handler() to call api-manager.sh stop (ignore failures), trap SIGTERM/SIGINT, and wait on the tracked PID.
Cross-cutting edits
dockerfiles/.../docker-entrypoint.sh (multiple)
Updated invocations to use quoted ${WSO2_SERVER_HOME} paths; backgrounded start commands (&) and added `

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Entrypoint
participant Server
participant OS
Entrypoint->>Server: start (background) and record PID
Entrypoint->>Entrypoint: wait ${server_pid}
OS-->>Entrypoint: SIGTERM / SIGINT
Entrypoint->>Entrypoint: stop_handler()
Entrypoint->>Server: invoke .sh stop (|| true)
Entrypoint->>Entrypoint: wait ${server_pid} (if set)
Server-->>Entrypoint: exit

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged the servers to sleep in the night,
PIDs in my basket, kept tidy and bright.
If a signal should whisper and wake up the land,
I'll call "stop" with a paw and hold their small hand. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete, missing most required template sections like Goals, Approach, User stories, Release notes, Documentation, Training, Certification, Marketing, Test details, and Learning. Complete the PR description by filling in required sections: Goals, Approach, User stories, Release note, Documentation, Automation tests with coverage, Security checks, Test environment details, and Learning section.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the primary change across all modified files: adding graceful shutdown handling to Docker entrypoint scripts.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 20

🧹 Nitpick comments (1)
dockerfiles/alpine/apim-acp/docker-entrypoint.sh (1)

84-87: Quote variable to prevent globbing and word splitting.

For consistency with the quoting used in stop_handler (lines 70, 72) and to address ShellCheck SC2086, quote ${WSO2_SERVER_HOME}.

♻️ Proposed fix
-  sh ${WSO2_SERVER_HOME}/bin/key-manager.sh "$@" &
+  sh "${WSO2_SERVER_HOME}/bin/key-manager.sh" "$@" &
 else
   # start the server with the control-plane and provided startup arguments
-  sh ${WSO2_SERVER_HOME}/bin/api-cp.sh "$@" &
+  sh "${WSO2_SERVER_HOME}/bin/api-cp.sh" "$@" &
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dockerfiles/alpine/apim-acp/docker-entrypoint.sh` around lines 84 - 87, The
shell calls launching the server use an unquoted variable ${WSO2_SERVER_HOME},
which can cause globbing/word-splitting; update the two invocations (the calls
to key-manager.sh and api-cp.sh) to quote the expansion so they become sh
"${WSO2_SERVER_HOME}/bin/key-manager.sh" "$@" & and sh
"${WSO2_SERVER_HOME}/bin/api-cp.sh" "$@" & respectively, mirroring the quoting
used in stop_handler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dockerfiles/alpine/apim-acp/docker-entrypoint.sh`:
- Around line 66-75: The stop_handler currently calls wait "${server_pid}" which
will error if server_pid is empty; update stop_handler to guard before waiting
by checking that server_pid is non-empty and a valid PID (e.g., [ -n
"${server_pid}" ] and/or kill -0 "${server_pid}" >/dev/null 2>&1) and only
invoke wait "${server_pid}" when that check passes; keep the existing logic that
invokes key-manager.sh or api-cp.sh and ensure the guard prevents wait from
running when server_pid is unset to avoid failures under set -e.

In `@dockerfiles/alpine/apim-tm/docker-entrypoint.sh`:
- Line 69: The sh invocation on line 69 uses an unquoted expansion of
${WSO2_SERVER_HOME}/bin/traffic-manager.sh which can cause
word-splitting/globbing issues; change that invocation to quote the script path
the same way as on line 61 (i.e., use a quoted expansion for the
WSO2_SERVER_HOME/bin/traffic-manager.sh argument) while preserving the "$@"
parameter and background operator.

In `@dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh`:
- Line 69: The gateway start command uses an unquoted ${WSO2_SERVER_HOME} which
can cause word-splitting or globbing if the path contains spaces; update the
invocation of gateway.sh (the sh ${WSO2_SERVER_HOME}/bin/gateway.sh "$@" &) to
quote the path variable consistently (use "${WSO2_SERVER_HOME}/bin/gateway.sh"
"$@" &) so it matches the quoting used elsewhere in docker-entrypoint.sh and
avoids shell parsing issues.
- Around line 57-63: The stop_handler's unconditional wait on server_pid can
fail if the PID isn't yet set (causing set -e to abort); update the stop_handler
(and any other places that call wait on server_pid) to first guard that
server_pid is non-empty and refers to a running process (e.g., test [ -n
"$server_pid" ] and kill -0 "$server_pid" or check /proc/"$server_pid") before
calling wait, and fall back to a safe no-op (or use wait || true) when the PID
is absent or the process is already gone so the script won't terminate early
under set -e.

In `@dockerfiles/alpine/apim/docker-entrypoint.sh`:
- Line 69: The shell invocation is unquoted and can suffer
word-splitting/globbing: update the call to the server script in
docker-entrypoint.sh to quote the ${WSO2_SERVER_HOME}/bin/api-manager.sh path
and keep "$@" quoted; specifically change the invocation that uses
${WSO2_SERVER_HOME} and api-manager.sh so the script path is wrapped in double
quotes (e.g., "…/bin/api-manager.sh") and preserve the existing backgrounding
(&) if intended.
- Around line 59-63: The stop_handler currently can fail if a signal arrives
before server_pid is set and can exit early due to set -e when api-manager.sh
returns non-zero; update stop_handler to (1) guard the wait by testing that
server_pid is a non-empty, numeric PID before calling wait, and (2) prevent the
script from aborting on a non-zero stop by capturing the exit code of sh
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop (e.g., temporarily disable errexit
or append || true) and log or handle the stop exit status instead of letting set
-e terminate the handler; reference the stop_handler function, the server_pid
variable, and the call to api-manager.sh to locate and apply the changes.

In `@dockerfiles/rocky/apim-acp/docker-entrypoint.sh`:
- Around line 84-87: The startup commands in docker-entrypoint.sh use unquoted
${WSO2_SERVER_HOME} which can cause word-splitting if the path contains spaces;
update the two invocations that run key-manager.sh and api-cp.sh to wrap the
expanded path in double quotes (e.g., " ${WSO2_SERVER_HOME}/bin/key-manager.sh "
and " ${WSO2_SERVER_HOME}/bin/api-cp.sh ") so the shell treats the full path as
one argument while preserving the existing "$@" forwarding.
- Around line 66-75: The stop_handler calls wait unconditionally using
server_pid which can be empty if a signal arrives before the server is launched;
update stop_handler to guard the wait by first verifying that server_pid is
non-empty and refers to a running process (e.g., check variable is set and the
PID exists) before invoking wait, so the trap registered earlier won't run wait
"" and fail under set -e; adjust stop_handler to only call wait when that check
passes.

In `@dockerfiles/rocky/apim-tm/docker-entrypoint.sh`:
- Line 69: The invocation on line 69 uses an unquoted variable (sh
${WSO2_SERVER_HOME}/bin/traffic-manager.sh "$@" &), which can break with spaces
or special chars; update this to use the same quoted form as the stop_handler
(i.e., call sh "${WSO2_SERVER_HOME}/bin/traffic-manager.sh" "$@" &), ensuring
consistent quoting of the WSO2_SERVER_HOME expansion and preserving the
background ampersand.

In `@dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh`:
- Line 69: The unquoted expansion of ${WSO2_SERVER_HOME} when invoking
gateway.sh risks word-splitting and is inconsistent with the quoted usage in
stop_handler; update the invocation in docker-entrypoint.sh (the line that calls
gateway.sh with "$@") to quote the variable expansion like the stop_handler does
so the command becomes sh "<${WSO2_SERVER_HOME}/bin/gateway.sh>" with "$@"
preserved (i.e., use the same quoting pattern as stop_handler to prevent word
splitting).
- Around line 57-63: The stop_handler function uses wait on server_pid which may
be empty if a SIGTERM/SIGINT arrives before server_pid is set (and with set -e
this causes the script to exit); update stop_handler to guard the wait by
checking that server_pid is non-empty (and ideally a running PID) before calling
wait (e.g., test -n "$server_pid" and/or verify the process exists) so wait is
only invoked for a valid PID; reference server_pid and stop_handler and replace
the unconditional wait "${server_pid}" with a guarded conditional that skips
wait when server_pid is unset or invalid.

In `@dockerfiles/rocky/apim/docker-entrypoint.sh`:
- Line 69: Update the start command in docker-entrypoint.sh to quote the
WSO2_SERVER_HOME expansion so the shell won't perform word-splitting or
globbing; locate the line that invokes api-manager.sh using the WSO2_SERVER_HOME
variable and change it to use a quoted path (i.e., reference
"${WSO2_SERVER_HOME}/bin/api-manager.sh") while keeping the "$@" and background
ampersand intact.
- Around line 59-63: The stop_handler currently calls sh
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop and then wait "${server_pid}"
which can fail under set -e if the stop command returns non-zero and will fail
when server_pid is empty; modify stop_handler to guard both actions: check that
server_pid is non-empty before calling wait (use an if [ -n "$server_pid" ]
guard around wait "${server_pid}"), and prevent set -e from aborting the handler
by either temporarily disabling errexit around the call to api-manager.sh (set
+e / set -e) or capturing the stop command's exit code and handling/logging it
instead of letting it propagate (e.g., run the stop command and if it fails log
a warning but continue to the wait guard).

In `@dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh`:
- Around line 84-87: The startup commands use unquoted variable expansion for
${WSO2_SERVER_HOME} in the calls to key-manager.sh and api-cp.sh causing
potential word-splitting/globbing; update the two invocations that call sh
${WSO2_SERVER_HOME}/bin/key-manager.sh "$@" & and sh
${WSO2_SERVER_HOME}/bin/api-cp.sh "$@" & to quote the path variable (i.e., use
"${WSO2_SERVER_HOME}/bin/key-manager.sh" and
"${WSO2_SERVER_HOME}/bin/api-cp.sh") so they match the quoting used elsewhere
and avoid SC2086.
- Around line 64-75: The stop_handler currently calls wait "${server_pid}"
unconditionally which can fail if server_pid is empty; modify stop_handler to
first check that server_pid is non-empty and corresponds to a running process
before calling wait. Specifically, in stop_handler (and where server_pid is
set), guard the wait call by testing that server_pid is not empty (e.g., [ -n
"${server_pid}" ]) and optionally that the PID exists (e.g., kill -0
"${server_pid}" >/dev/null 2>&1) before invoking wait to avoid wait "" under set
-e; keep the existing logic that stops via
"${WSO2_SERVER_HOME}/bin/key-manager.sh" or api-cp.sh intact.

In `@dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh`:
- Line 69: The command launching traffic-manager.sh uses an unquoted
${WSO2_SERVER_HOME} which can break on paths with spaces or glob characters;
update the line that executes traffic-manager.sh to use a quoted expansion
(match the quoting used for the stop path), i.e., ensure you reference
"${WSO2_SERVER_HOME}/bin/traffic-manager.sh" and preserve the "$@" and trailing
& so the shell invocation remains identical aside from adding the quotes.

In `@dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh`:
- Line 69: The startup command calling gateway.sh uses an unquoted variable
(${WSO2_SERVER_HOME}) which can lead to word splitting/globbing; update the
invocation in the startup path where sh ${WSO2_SERVER_HOME}/bin/gateway.sh "$@"
& is used to quote the variable (same style as stop_handler) so it becomes sh
"${WSO2_SERVER_HOME}/bin/gateway.sh" "$@" & ensuring consistent, safe quoting
around WSO2_SERVER_HOME.
- Around line 57-63: The stop_handler currently calls wait "${server_pid}"
unguarded which can fail if server_pid is empty (race between trap registration
and server start) and, under set -e, abort the handler; update stop_handler to
only call wait when server_pid is non-empty and appears numeric (e.g., test -n
"$server_pid" and use a numeric check) or otherwise skip/wrap wait so it cannot
return a failing status (apply the same fix in the three entrypoint scripts),
keeping the echo and sh "${WSO2_SERVER_HOME}/bin/gateway.sh" stop call intact.

In `@dockerfiles/ubuntu/apim/docker-entrypoint.sh`:
- Line 69: The entrypoint uses an unquoted expansion for ${WSO2_SERVER_HOME}
which can cause word-splitting/globbing; update the command in
docker-entrypoint.sh so the path is quoted, e.g. invoke sh
"${WSO2_SERVER_HOME}/bin/api-manager.sh" "$@" & instead of sh
${WSO2_SERVER_HOME}/bin/api-manager.sh "$@" & to safely handle spaces or special
chars in WSO2_SERVER_HOME.
- Around line 59-63: The stop_handler currently can exit early due to set -e
when api-manager.sh returns non-zero and can call wait with an empty server_pid;
change stop_handler (function name) to 1) capture/validate server_pid before
using it (ensure it's non-empty and numeric or that a PID file/process exists)
and only call wait when valid, and 2) invoke
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop but do not let its non-zero exit
abort the handler — e.g. capture its exit code or append || true so the handler
continues to the wait/cleanup logic; ensure you reference server_pid and the
api-manager.sh invocation when applying these guards.

---

Nitpick comments:
In `@dockerfiles/alpine/apim-acp/docker-entrypoint.sh`:
- Around line 84-87: The shell calls launching the server use an unquoted
variable ${WSO2_SERVER_HOME}, which can cause globbing/word-splitting; update
the two invocations (the calls to key-manager.sh and api-cp.sh) to quote the
expansion so they become sh "${WSO2_SERVER_HOME}/bin/key-manager.sh" "$@" & and
sh "${WSO2_SERVER_HOME}/bin/api-cp.sh" "$@" & respectively, mirroring the
quoting used in stop_handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94aa41d0-b2a3-4e1f-a71c-f42851a27ce0

📥 Commits

Reviewing files that changed from the base of the PR and between 3e6e3cb and cd97e41.

📒 Files selected for processing (12)
  • dockerfiles/alpine/apim-acp/docker-entrypoint.sh
  • dockerfiles/alpine/apim-tm/docker-entrypoint.sh
  • dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim/docker-entrypoint.sh
  • dockerfiles/rocky/apim-acp/docker-entrypoint.sh
  • dockerfiles/rocky/apim-tm/docker-entrypoint.sh
  • dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/rocky/apim/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim/docker-entrypoint.sh

Comment thread dockerfiles/alpine/apim-acp/docker-entrypoint.sh
Comment thread dockerfiles/alpine/apim-tm/docker-entrypoint.sh Outdated
Comment thread dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
Comment thread dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh Outdated
Comment thread dockerfiles/alpine/apim/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh Outdated
Comment thread dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh Outdated
Comment thread dockerfiles/ubuntu/apim/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim/docker-entrypoint.sh Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dockerfiles/alpine/apim-tm/docker-entrypoint.sh`:
- Around line 59-67: The stop_handler currently returns after performing
shutdown which allows the script to resume and possibly restart the server;
change stop_handler to clear/disable the SIGTERM and SIGINT traps at its start
(e.g. trap - SIGTERM SIGINT), stop the server via sh
"${WSO2_SERVER_HOME}/bin/traffic-manager.sh" stop, wait for the background
server_pid if set (if [[ -n "${server_pid}" ]]; then wait "${server_pid}"; fi),
and then explicitly exit (e.g. exit 0) so the script does not continue; keep the
trap 'stop_handler' SIGTERM SIGINT setup but ensure the handler disables traps
before waiting and exits when finished.

In `@dockerfiles/alpine/apim/docker-entrypoint.sh`:
- Around line 59-67: The trap handler stop_handler currently performs shutdown
tasks but returns to the main flow allowing startup to continue; modify
stop_handler (used by trap 'stop_handler' SIGTERM SIGINT) to explicitly
terminate the script after completing shutdown work (e.g., after calling
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop and waiting on server_pid) by
invoking a clean exit (exit 0) so the script does not fall through to the normal
startup/wait logic.

In `@dockerfiles/rocky/apim-tm/docker-entrypoint.sh`:
- Around line 59-67: The stop_handler currently returns after attempting to stop
WSO2 which allows the main script to continue and potentially start the server
after a SIGTERM/SIGINT; modify stop_handler (used by trap on SIGTERM SIGINT) to
explicitly terminate the process (e.g., call exit with a non-zero or zero code)
after stopping the server and waiting on server_pid so the handler is a terminal
branch and the script cannot proceed to start the server; ensure the change is
applied to the stop_handler function that calls
"${WSO2_SERVER_HOME}/bin/traffic-manager.sh" stop and references server_pid and
the trap installation.

In `@dockerfiles/rocky/apim/docker-entrypoint.sh`:
- Around line 59-67: The stop_handler currently returns after attempting to stop
WSO2 and waiting on server_pid, which allows the main script to continue; modify
the stop_handler function to terminate the script after cleanup by adding an
exit (e.g., exit 0) at the end of stop_handler (after the sh
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop and after any conditional wait
"${server_pid}") so the trap ('stop_handler' SIGTERM SIGINT) always halts
further execution once cleanup completes.

In `@dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh`:
- Around line 66-79: The stop_handler function can be re-entered and allow the
script to continue startup if a signal arrives before server_pid is set; update
stop_handler to be a terminal path by disabling the trap at the start (trap -
SIGTERM SIGINT) to prevent re-entry, call the appropriate shutdown script as
before (key-manager.sh or api-cp.sh), then perform a safe wait on server_pid
using wait "${server_pid}" 2>/dev/null || true to handle empty/invalid pid, and
finish the handler with exit 0 so the handler always terminates the script;
references: stop_handler, server_pid, and the existing trap SIGTERM SIGINT.

In `@dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh`:
- Around line 59-67: The stop_handler currently can return without terminating
the script (using sh "${WSO2_SERVER_HOME}/bin/gateway.sh" stop and conditional
wait on server_pid), which allows startup to continue if a signal arrives before
server_pid is set; modify stop_handler so it always exits the script after
performing shutdown steps (call gateway.sh stop, attempt wait if server_pid
present, then call exit with an appropriate status like exit 0 or exit 143) so
the trap ('stop_handler' SIGTERM SIGINT) will never resume the startup path even
when server_pid is empty.

In `@dockerfiles/ubuntu/apim/docker-entrypoint.sh`:
- Around line 59-67: The stop_handler function can return and let the script
continue into startup when a signal arrives before the server_pid is set; update
stop_handler (the function referenced by trap) to terminate the script after
handling the signal by adding an explicit exit 0 (or another appropriate exit
code) after the guarded wait that checks server_pid, ensuring the handler never
falls through into the startup code executed later in the script.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fde6d2d8-53d9-4e0f-b164-db9b43db946c

📥 Commits

Reviewing files that changed from the base of the PR and between cd97e41 and fd23321.

📒 Files selected for processing (12)
  • dockerfiles/alpine/apim-acp/docker-entrypoint.sh
  • dockerfiles/alpine/apim-tm/docker-entrypoint.sh
  • dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim/docker-entrypoint.sh
  • dockerfiles/rocky/apim-acp/docker-entrypoint.sh
  • dockerfiles/rocky/apim-tm/docker-entrypoint.sh
  • dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/rocky/apim/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim/docker-entrypoint.sh
✅ Files skipped from review due to trivial changes (1)
  • dockerfiles/rocky/apim-acp/docker-entrypoint.sh
🚧 Files skipped from review as they are similar to previous changes (4)
  • dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim-acp/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh

Comment thread dockerfiles/alpine/apim-tm/docker-entrypoint.sh
Comment thread dockerfiles/alpine/apim/docker-entrypoint.sh
Comment thread dockerfiles/rocky/apim-tm/docker-entrypoint.sh
Comment thread dockerfiles/rocky/apim/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
Comment thread dockerfiles/ubuntu/apim/docker-entrypoint.sh
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
dockerfiles/ubuntu/apim/docker-entrypoint.sh (1)

59-65: ⚠️ Potential issue | 🟠 Major

stop_handler should terminate the script to prevent startup after signal.

A signal received between trap installation (line 67) and server start (line 71) will invoke stop_handler with an empty server_pid. The handler completes and returns normally, allowing the script to continue and start the server anyway—defeating the graceful shutdown intent.

Add exit 0 at the end of the handler to make it a terminal path.

,

Proposed fix
 stop_handler() {
   echo "Stopping WSO2 gracefully..." >&2
   sh "${WSO2_SERVER_HOME}/bin/api-manager.sh" stop || true
   if [[ -n "${server_pid}" ]]; then
     wait "${server_pid}"
   fi
+  exit 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dockerfiles/ubuntu/apim/docker-entrypoint.sh` around lines 59 - 65, The
stop_handler currently returns when run during shutdown (e.g., if server_pid is
empty) which allows the script to continue and start the server; modify
stop_handler (the function named stop_handler in docker-entrypoint.sh that
references server_pid and calls "${WSO2_SERVER_HOME}/bin/api-manager.sh" stop)
to make it a terminal path by adding an explicit exit 0 at the end of the
function so the script terminates after handling the signal.
dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh (1)

66-77: ⚠️ Potential issue | 🟠 Major

stop_handler should be a terminal path.

Same issue flagged in prior review: the handler should end with exit 0 to prevent startup from proceeding after handling a shutdown signal received before the server is launched.

,

Proposed fix
 stop_handler() {
   echo "Stopping WSO2 gracefully..." >&2
   if [[ "${PROFILE_NAME}" == "key-manager" ]]
   then
     sh "${WSO2_SERVER_HOME}/bin/key-manager.sh" stop || true
   else
     sh "${WSO2_SERVER_HOME}/bin/api-cp.sh" stop || true
   fi
   if [[ -n "${server_pid}" ]]; then
     wait "${server_pid}"
   fi
+  exit 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh` around lines 66 - 77, The
stop_handler function currently lacks a terminal exit path so if a shutdown
signal arrives before the server starts the script can continue; modify the
stop_handler (the function that inspects PROFILE_NAME, calls key-manager.sh or
api-cp.sh, and waits on server_pid) to ensure it always terminates the script by
adding an explicit exit 0 at the end of the function (after the wait and any
cleanup) so the handler is a terminal path and prevents further startup logic
from running.
dockerfiles/rocky/apim-tm/docker-entrypoint.sh (1)

59-65: ⚠️ Potential issue | 🟠 Major

stop_handler should terminate the script to prevent startup after signal.

Same issue flagged in prior review: without exit 0, the handler returns normally if signaled before server_pid is set, allowing startup to proceed.

,

Proposed fix
 stop_handler() {
   echo "Stopping WSO2 gracefully..." >&2
   sh "${WSO2_SERVER_HOME}/bin/traffic-manager.sh" stop || true
   if [[ -n "${server_pid}" ]]; then
     wait "${server_pid}"
   fi
+  exit 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dockerfiles/rocky/apim-tm/docker-entrypoint.sh` around lines 59 - 65, The
stop_handler function can return without exiting if signaled before server_pid
is set, allowing the script to continue startup; modify stop_handler (in
docker-entrypoint.sh) to always terminate the entrypoint after handling the
signal by ensuring it calls exit 0 (or another appropriate exit code) after
stopping WSO2 (the sh "${WSO2_SERVER_HOME}/bin/traffic-manager.sh" stop
invocation and any wait on server_pid) so the process does not resume startup
when interrupted.
dockerfiles/alpine/apim-acp/docker-entrypoint.sh (1)

66-77: ⚠️ Potential issue | 🟠 Major

stop_handler should exit to prevent startup after early signal.

Same race condition as other entrypoints: if SIGTERM/SIGINT arrives between trap (line 79) and server start (lines 86/89), stop_handler executes with empty server_pid, returns normally, and the script proceeds to start the server.

Terminate the handler with exit 0.

Proposed fix
 stop_handler() {
   echo "Stopping WSO2 gracefully..." >&2
   if [[ "${PROFILE_NAME}" == "key-manager" ]]
   then
     sh "${WSO2_SERVER_HOME}/bin/key-manager.sh" stop || true
   else
     sh "${WSO2_SERVER_HOME}/bin/api-cp.sh" stop || true
   fi
   if [[ -n "${server_pid}" ]]; then
     wait "${server_pid}"
   fi
+  exit 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dockerfiles/alpine/apim-acp/docker-entrypoint.sh` around lines 66 - 77, The
stop_handler function can return and allow startup after an early SIGTERM/SIGINT
because server_pid may be empty; modify stop_handler (the function that calls
key-manager.sh or api-cp.sh and waits on server_pid) to terminate the script
after handling the signal by calling exit 0 at the end of the function so the
entrypoint does not continue to start the server when a signal arrived before
the server was launched.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dockerfiles/rocky/apim-acp/docker-entrypoint.sh`:
- Around line 66-77: The stop_handler currently returns after stopping the
process and waiting on server_pid, which allows the entrypoint to continue and
possibly start the server after an early signal; modify stop_handler (the
function handling signals in docker-entrypoint.sh) to terminate the script after
successful shutdown by adding an explicit exit 0 (or equivalent immediate exit)
at the end of stop_handler so the entrypoint does not resume startup when
PROFILE_NAME logic or server_pid handling runs.

---

Duplicate comments:
In `@dockerfiles/alpine/apim-acp/docker-entrypoint.sh`:
- Around line 66-77: The stop_handler function can return and allow startup
after an early SIGTERM/SIGINT because server_pid may be empty; modify
stop_handler (the function that calls key-manager.sh or api-cp.sh and waits on
server_pid) to terminate the script after handling the signal by calling exit 0
at the end of the function so the entrypoint does not continue to start the
server when a signal arrived before the server was launched.

In `@dockerfiles/rocky/apim-tm/docker-entrypoint.sh`:
- Around line 59-65: The stop_handler function can return without exiting if
signaled before server_pid is set, allowing the script to continue startup;
modify stop_handler (in docker-entrypoint.sh) to always terminate the entrypoint
after handling the signal by ensuring it calls exit 0 (or another appropriate
exit code) after stopping WSO2 (the sh
"${WSO2_SERVER_HOME}/bin/traffic-manager.sh" stop invocation and any wait on
server_pid) so the process does not resume startup when interrupted.

In `@dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh`:
- Around line 66-77: The stop_handler function currently lacks a terminal exit
path so if a shutdown signal arrives before the server starts the script can
continue; modify the stop_handler (the function that inspects PROFILE_NAME,
calls key-manager.sh or api-cp.sh, and waits on server_pid) to ensure it always
terminates the script by adding an explicit exit 0 at the end of the function
(after the wait and any cleanup) so the handler is a terminal path and prevents
further startup logic from running.

In `@dockerfiles/ubuntu/apim/docker-entrypoint.sh`:
- Around line 59-65: The stop_handler currently returns when run during shutdown
(e.g., if server_pid is empty) which allows the script to continue and start the
server; modify stop_handler (the function named stop_handler in
docker-entrypoint.sh that references server_pid and calls
"${WSO2_SERVER_HOME}/bin/api-manager.sh" stop) to make it a terminal path by
adding an explicit exit 0 at the end of the function so the script terminates
after handling the signal.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0d10ee60-c08c-497b-92ca-8c975fb623d9

📥 Commits

Reviewing files that changed from the base of the PR and between fd23321 and b1a62c3.

📒 Files selected for processing (12)
  • dockerfiles/alpine/apim-acp/docker-entrypoint.sh
  • dockerfiles/alpine/apim-tm/docker-entrypoint.sh
  • dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim/docker-entrypoint.sh
  • dockerfiles/rocky/apim-acp/docker-entrypoint.sh
  • dockerfiles/rocky/apim-tm/docker-entrypoint.sh
  • dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/rocky/apim/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-acp/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim/docker-entrypoint.sh
🚧 Files skipped from review as they are similar to previous changes (7)
  • dockerfiles/alpine/apim/docker-entrypoint.sh
  • dockerfiles/alpine/apim-tm/docker-entrypoint.sh
  • dockerfiles/rocky/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/alpine/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-tm/docker-entrypoint.sh
  • dockerfiles/ubuntu/apim-universal-gw/docker-entrypoint.sh
  • dockerfiles/rocky/apim/docker-entrypoint.sh

Comment thread dockerfiles/rocky/apim-acp/docker-entrypoint.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add graceful shutdown behaviour for docker images

1 participant