diff --git a/.env b/.env new file mode 100644 index 0000000..e124360 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ + +# Vars for testing. Pipenv will load these automatically +PYTHONPATH=./shared-components/tests:$PYTHONPATH +DOCKERFILE='Dockerfile' +DOCKERFILE_VERSION_ARG='CONFLUENCE_VERSION' +MAC_PRODUCT_KEY='confluence' diff --git a/Dockerfile b/Dockerfile index efe13e6..e470ef7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ FROM $BASE_IMAGE LABEL maintainer="dc-deployments@atlassian.com" LABEL securitytxt="https://www.atlassian.com/.well-known/security.txt" +ENV APP_NAME confluence ENV RUN_USER confluence ENV RUN_GROUP confluence ENV RUN_UID 2002 @@ -55,6 +56,7 @@ RUN groupadd --gid ${RUN_GID} ${RUN_GROUP} \ VOLUME ["${CONFLUENCE_HOME}"] # Must be declared after setting perms COPY entrypoint.py \ + shutdown-wait.sh \ shared-components/image/entrypoint_helpers.py / COPY shared-components/support /opt/atlassian/support COPY config/* /opt/atlassian/etc/ diff --git a/README.md b/README.md index e176e7a..8772749 100644 --- a/README.md +++ b/README.md @@ -390,6 +390,17 @@ using an external database. Read more about data recovery and backups: [Site Backup and Restore][10] +# Shutdown + +Confluence allows a grace period of 20s for active operations to finish before +termination. If sending a `docker stop` this should be taken into account with +the `--time` flag. + +Alternatively, the script `/shutdown-wait.sh` is provided, which will initiate a +clean shutdown and wait for the process to complete. This is the recommended +method for shutdown in environments which provide for orderly shutdown, +e.g. Kubernetes via the `preStop` hook. + # Versioning The `latest` tag matches the most recent official release of Atlassian Confluence Server. diff --git a/shutdown-wait.sh b/shutdown-wait.sh new file mode 100755 index 0000000..d29fc4f --- /dev/null +++ b/shutdown-wait.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +############################################################################## +# +# This script will initiate a clean shutdown of the application, and +# then wait for the process to finish before returning. This is +# primarily intended for use in environments that provide an orderly +# shutdown mechanism, in particular the Kubernetes `preStop` hook. +# +# This script will wait for the process to exit indefinitely; however +# most run-time tools (including Docker and Kubernetes) have their own +# shutdown timeouts that will send a SIGKILL if the grace period is +# exceeded. +# +############################################################################## + +set -e + +source /opt/atlassian/support/common.sh + +echo "Shutting down Confluence..." +echo ${JVM_APP_PID} > ${CONFLUENCE_INSTALL_DIR}/work/catalina.pid + +if [[ "${UID}" == 0 ]]; then + /bin/su ${RUN_USER} -c ${CONFLUENCE_INSTALL_DIR}/bin/stop-confluence.sh; +else + ${CONFLUENCE_INSTALL_DIR}/bin/stop-confluence.sh; +fi + +/opt/atlassian/support/wait-pid.sh diff --git a/tests/test_image.py b/tests/test_image.py index d87bf53..192bb22 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -56,6 +56,17 @@ def test_clean_shutdown(docker_cli, image, run_user): wait_for_log(container, end) +def test_shutdown_script(docker_cli, image, run_user): + container = docker_cli.containers.run(image, detach=True, user=run_user, ports={PORT: PORT}) + host = testinfra.get_host("docker://"+container.id) + wait_for_state(STATUS_URL, expected_state='FIRST_RUN') + + container.exec_run('/shutdown-wait.sh') + + end = r'org\.apache\.coyote\.AbstractProtocol\.destroy Destroying ProtocolHandler' + wait_for_log(container, end) + + def test_server_xml_defaults(docker_cli, image): container = run_image(docker_cli, image) _jvm = wait_for_proc(container, get_bootstrap_proc(container))