Skip to content

Commit 33c30f3

Browse files
Merge branch 'graceful-shutdown-module'
2 parents 6121e34 + 9bf37f7 commit 33c30f3

14 files changed

+66
-5
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ DOCKER_COMPOSE_NGINX_SELECTIVE_VOLUMES=["./shared/nginx-error-logs:/var/log/ngin
6161
# Check if the host folder or file exists
6262
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
6363

64+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
65+
6466
NGINX_CLIENT_MAX_BODY_SIZE=50M
6567

6668
# Format : docker-compose-${project_name}-original-ready.yml

.env.example.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
DOCKER_COMPOSE_ENVIRONMENT={"TZ":"Asia/Seoul"}
4545
# This goes with "docker build ... in the 'run.sh' script file", and the command always contain "HOST_IP" and "APP_ENV" above.
4646
# docker exec -it CONTAINER_NAME cat /var/log/env_build_args.log
47-
DOCKER_BUILD_ARGS={"DOCKER_BUILDKIT":"1","PROJECT_ROOT_IN_CONTAINER":"/var/www/server/spring-sample-h-auth","FILE_STORAGE_ROOT_IN_CONTAINER":"/var/www/files","APP_ENV":"production"}
47+
DOCKER_BUILD_ARGS={"DOCKER_BUILDKIT":"1","PROJECT_ROOT_IN_CONTAINER":"/var/www/server/spring-sample-h-auth","FILE_STORAGE_ROOT_IN_CONTAINER":"/var/www/files","APP_ENV":"production","JVM_XMS":"1024","JVM_XMX":"2048"}
4848
DOCKER_BUILD_LABELS=["foo=happy","bar=sad"]
4949
# For Mac like, EX. DOCKER_BUILD_ADDITIONAL_RAW_PARAMS=--platform linux/amd64
5050
DOCKER_BUILD_ADDITIONAL_RAW_PARAMS=--platform linux/amd64
@@ -54,6 +54,8 @@
5454
DOCKER_COMPOSE_NGINX_SELECTIVE_VOLUMES=["./shared/nginx-error-logs:/var/log/nginx"]
5555
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
5656

57+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
58+
5759
NGINX_CLIENT_MAX_BODY_SIZE=50M
5860

5961
USE_MY_OWN_APP_YML=false

.env.example.java.commercial.ssl.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ DOCKER_COMPOSE_SELECTIVE_VOLUMES=["/var/web/files/spring-sample-h-auth:/var/www/
5454
DOCKER_COMPOSE_NGINX_SELECTIVE_VOLUMES=["/var/web/files/nginx/spring-sample-h-auth/logs:/var/log/nginx"]
5555
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
5656

57+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
58+
5759
NGINX_CLIENT_MAX_BODY_SIZE=50M
5860

5961
USE_MY_OWN_APP_YML=false

.env.example.node

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ DOCKER_COMPOSE_NGINX_SELECTIVE_VOLUMES=[]
4949
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
5050
DOCKER_COMPOSE_SELECTIVE_VOLUMES=[]
5151

52+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
53+
5254
NGINX_CLIENT_MAX_BODY_SIZE=50M
5355

5456
USE_MY_OWN_APP_YML=false

.env.example.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
DOCKER_COMPOSE_NGINX_SELECTIVE_VOLUMES=["./shared/nginx-error-logs:/var/log/nginx"]
5656
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
5757

58+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
59+
5860
NGINX_CLIENT_MAX_BODY_SIZE=50M
5961

6062
USE_MY_OWN_APP_YML=false

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ DOCKER_COMPOSE_SELECTIVE_VOLUMES=["/your-project-path:/var/www/app"]
238238
```shell
239239
# First, as the sample project requires MySQL8, run it separately.
240240
# You can use your own MySQL8 Docker or just clone "https://github.com/patternhelloworld/docker-mysql-8"
241+
# The SQL file is located at './samples/spring-sample-h-auth/.mysql/schema_all.sql'.
241242
```
242243

243244
```shell
@@ -287,6 +288,11 @@ GOOD_APP_HEALTH_CHECK_PATTERN=UP
287288
DOCKER_COMPOSE_SELECTIVE_VOLUMES=["/my-host/files/:/in-container/files", "/my-host/java-spring-project/src/main/resources:/in-container/java-spring-project/src/main/resources"]
288289
# Check if the host folder or file exists
289290
DOCKER_COMPOSE_HOST_VOLUME_CHECK=false
291+
292+
# Currently, a graceful shutdown example is only provided for the Java sample. To enable graceful termination, make sure to handle SIGTERM in both your application and the Dockerfile.
293+
# Refer to "docker-compose-app-original.yml" which uses this property.
294+
DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD=40s
295+
290296
# If APP_ENV is set to 'local', as specified in 'docker-compose-app-original.yml', synchronize your entire project as follows: "HOST_ROOT_LOCATION:PROJECT_LOCATION".
291297
# [IMPORTANT] If this is set to true, Nginx will be restarted, resulting in a short downtime.
292298
# This option should be used when upgrading the Runner. See the "Upgrade" section below.

docker-compose-app-original.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ services:
1515
env_file:
1616
- .env
1717
volumes: []
18+
# After sending SIGTERM, Docker waits for a grace period (default is 10 seconds) to allow the process to exit.
19+
# If the process does not terminate within this grace period,
20+
# Docker sends a SIGKILL signal to terminate the process forcibly.
21+
stop_signal: SIGTERM
22+
stop_grace_period: ${DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD}
1823
${PROJECT_NAME}-green:
1924
container_name: ${PROJECT_NAME}-green
2025
stdin_open: true
@@ -30,6 +35,8 @@ services:
3035
env_file:
3136
- .env
3237
volumes: []
38+
stop_signal: SIGTERM
39+
stop_grace_period: ${DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD}
3340
networks:
3441
dbgr-net:
3542
external:

docker-stack-app-original-blue.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ services:
1313
replicas: 2
1414
networks:
1515
- dbgr-net
16+
stop_signal: SIGTERM
17+
stop_grace_period: ${DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD}
1618
networks:
1719
dbgr-net:
1820
external: true

docker-stack-app-original-green.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ services:
1313
replicas: 2
1414
networks:
1515
- dbgr-net
16+
stop_signal: SIGTERM
17+
stop_grace_period: ${DOCKER_COMPOSE_STOP_GRACEFUL_SHUTDOWN_PERIOD}
1618
networks:
1719
dbgr-net:
1820
external: true

samples/spring-sample-h-auth/.docker/entrypoint/run-app.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,23 @@ if [ -z "$4" ]; then
1616
exit 1
1717
fi
1818

19+
echo "[INSIDE APP CONTAINER][NOTICE] Starting Spring Boot App with graceful shutdown..."
20+
21+
# graceful shutdown handler
22+
term_handler() {
23+
echo "[INSIDE APP CONTAINER][NOTICE] Caught SIGTERM, forwarding to Java process (PID $pid)..."
24+
if [ "$pid" -ne 0 ]; then
25+
kill -SIGTERM "$pid"
26+
wait "$pid"
27+
fi
28+
exit 143
29+
}
30+
31+
trap 'term_handler' SIGTERM
32+
1933
echo "[INSIDE APP CONTAINER][NOTICE] Run : java -Xms${3}m -Xmx${4}m -XX:+PrintGCDetails -Xloggc:${2}/logs/auth-gc.log -Dspring.config.location=file:${1}/src/main/resources/application.properties -Dlogging.config=file:${1}/src/main/resources/logback-spring.xml -jar /app.jar > ${2}/logs/auth-start.log 2>&1 &"
2034
java -Xms${3}m -Xmx${4}m -XX:+PrintGCDetails -Xloggc:${2}/auth-gc.log -Dspring.config.location=file:${1}/src/main/resources/application.properties -jar /app.jar > ${2}/auth-start.log 2>&1 &
35+
pid=$!
36+
37+
# foreground wait
38+
wait "$pid"

samples/spring-sample-h-auth/Dockerfile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,19 @@ WORKDIR $PROJECT_ROOT_IN_CONTAINER
2424
RUN cp $PROJECT_ROOT_IN_CONTAINER/target/*.jar /app.jar
2525

2626
RUN ln -s $PROJECT_ROOT_IN_CONTAINER/.docker/entrypoint/run-app.sh /run-app.sh
27+
RUN chmod 755 /run-app.sh
2728

28-
RUN apk --no-cache add curl bash
29+
# dumb-init added!
30+
RUN apk update && apk add --no-cache bash curl dumb-init
31+
32+
# dumb-init : https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html
33+
##ENTRYPOINT ["/usr/bin/dumb-init", "--", "/my/script"]
2934

3035
ENV PROJECT_ROOT_IN_CONTAINER=$PROJECT_ROOT_IN_CONTAINER
3136
ENV FILE_STORAGE_ROOT_IN_CONTAINER=$FILE_STORAGE_ROOT_IN_CONTAINER
3237
ENV JVM_XMS=$JVM_XMS
3338
ENV JVM_XMX=$JVM_XMX
3439

35-
ENTRYPOINT sh /run-app.sh $PROJECT_ROOT_IN_CONTAINER $FILE_STORAGE_ROOT_IN_CONTAINER $JVM_XMS $JVM_XMX && /bin/sh
40+
#ENTRYPOINT ["/usr/bin/dumb-init", "--", "/my/script"]
41+
#ENTRYPOINT sh /run-app.sh $PROJECT_ROOT_IN_CONTAINER $FILE_STORAGE_ROOT_IN_CONTAINER $JVM_XMS $JVM_XMX && /bin/sh
42+
ENTRYPOINT ["/usr/bin/dumb-init", "--", "sh", "-c", "/run-app.sh $PROJECT_ROOT_IN_CONTAINER $FILE_STORAGE_ROOT_IN_CONTAINER $JVM_XMS $JVM_XMX && exec /bin/sh"]

samples/spring-sample-h-auth/src/main/resources/application.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,7 @@ app.test.auth.password=ee
6060
spring.mail.username=aaa@dd.com
6161
spring.mail.password=aaa
6262

63-
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
63+
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
64+
65+
server.shutdown=graceful
66+
spring.lifecycle.timeout-per-shutdown-phase=30s

samples/spring-sample-h-auth/src/main/resources/application.properties.commerical.ssl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,6 @@ server.ssl.key-store-password=11111
6666
server.ssl.key-store=/var/www/server/spring-sample-h-auth/yourdomain.com.jks
6767
server.ssl.key-store-type=jks
6868
server.ssl.key-alias=server
69+
70+
server.shutdown=graceful
71+
spring.lifecycle.timeout-per-shutdown-phase=30s

samples/spring-sample-h-auth/src/main/resources/application.properties.sample

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,7 @@ app.test.auth.password=ee
5858
spring.mail.username=aaa@dd.com
5959
spring.mail.password=aaa
6060

61-
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
61+
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
62+
63+
server.shutdown=graceful
64+
spring.lifecycle.timeout-per-shutdown-phase=30s

0 commit comments

Comments
 (0)