Skip to content

Fix container signal handling so the JVM receives SIGTERM for clean shutdown#536

Merged
uhurusurfa merged 1 commit into
OpenAS2:masterfrom
igwtech:fix/docker-entrypoint-signal-handling
Jun 13, 2026
Merged

Fix container signal handling so the JVM receives SIGTERM for clean shutdown#536
uhurusurfa merged 1 commit into
OpenAS2:masterfrom
igwtech:fix/docker-entrypoint-signal-handling

Conversation

@GreicodexJM

Copy link
Copy Markdown
Contributor

Problem

The Docker image's ENTRYPOINT uses the shell form, so PID 1 inside the container is /bin/sh -c, not the OpenAS2 JVM. SIGTERM sent by docker stop (or by Kubernetes on pod termination) is delivered to the shell, which does not forward it. As a result:

  • The JVM's registered shutdown hook never runs — modules (including DbTrackingModule with the embedded H2 database) are never stopped cleanly.
  • Every container stop waits out the full grace period (10s by default) and ends in SIGKILL.
  • This is also what the Docker build check JSONArgsRecommended warns about on the current Dockerfile.

Fix

Three small changes so the signal chain reaches the JVM:

  1. Dockerfile — exec-form ENTRYPOINT ["/opt/openas2/bin/start-container.sh"] (exec form cannot expand variables; the path is already fixed by ENV OPENAS2_BASE in the same Dockerfile, and the scripts keep using the variable at runtime).
  2. start-container.shexec the startup script instead of forking it.
  3. start-openas2.shexec java in the foreground (non-daemon) branch so the JVM ends up as the final process. Daemon mode (OPENAS2_AS_DAEMON=true) is unchanged, and the exit code behavior of the foreground branch is preserved (exec makes the script's exit status the JVM's exit status).

Verification (on the 4.8.2 image)

Before:

  • docker stop takes 10.2s (full grace period, then SIGKILL)
  • No shutdown messages in the logs

After:

  • ps inside the container shows PID 1 = java
  • docker stop completes in ~0.2s
  • Logs show the shutdown hook running:
[Thread-0] INFO  org.openas2.processor.DefaultProcessor - DbTrackingModule stopped.
[Thread-0] INFO  org.openas2.processor.DefaultProcessor - AS2ReceiverModule stopped.
[Thread-0] INFO  org.openas2.processor.DefaultProcessor - AS2MDNReceiverModule stopped.
[Thread-0] INFO  org.openas2.processor.DefaultProcessor - DirectoryResenderModule stopped.
[Thread-0] INFO  org.openas2.processor.DefaultProcessor - 4 active module(s) stopped.
[Thread-0] INFO  org.openas2.app.OpenAS2Server - OpenAS2 has shut down

The docker build check warning JSONArgsRecommended is also gone.

…hutdown

The Docker entrypoint used the shell form, so PID 1 was /bin/sh and
SIGTERM from 'docker stop' (or a Kubernetes pod termination) never
reached the Java process. The JVM's registered shutdown hook never ran,
modules were not stopped cleanly, and every stop ended with SIGKILL
after the full grace period (10s default).

Changes:
- Dockerfile: use exec-form ENTRYPOINT (also fixes the
  JSONArgsRecommended build check warning)
- start-container.sh: exec the startup script instead of forking it
- start-openas2.sh: exec java in foreground (non-daemon) mode so the
  JVM is the final process in the chain; daemon mode is unchanged

Verified on the 4.8.2 image: before, 'docker stop' took 10.2s and ended
in SIGKILL with no shutdown logs; after, java runs as PID 1, stop
completes in ~0.2s and logs show all modules stopped and 'OpenAS2 has
shut down'.

@uhurusurfa uhurusurfa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@uhurusurfa uhurusurfa merged commit faf1ba6 into OpenAS2:master Jun 13, 2026
11 checks passed
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.

3 participants