diff --git a/Dockerfile b/Dockerfile index fe9e1de..7ad7415 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,36 +13,38 @@ ENV HOME="/" \ GID=1001 COPY prebuildfs / -SHELL ["/bin/bash", "-o", "pipefail", "-c"] +SHELL ["/bin/bash", "-o", "errexit", "-o", "nounset", "-o", "pipefail", "-c"] # Install required system packages and dependencies RUN install_packages ca-certificates curl libbrotli1 libcom-err2 libcurl4 libffi8 libgcc-s1 libgcrypt20 libgmp10 libgnutls30 \ libgpg-error0 libgssapi-krb5-2 libhogweed6 libidn2-0 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.5-0 liblzma5 \ libnettle8 libnghttp2-14 libp11-kit0 libpsl5 librtmp1 libsasl2-2 libssh2-1 libssl3 libtasn1-6 libunistring2 numactl procps zlib1g -RUN mkdir -p /tmp/bitnami/pkg/cache/ && cd /tmp/bitnami/pkg/cache/ && \ +RUN mkdir -p /tmp/bitnami/pkg/cache/ ; \ + cd /tmp/bitnami/pkg/cache/ ; \ COMPONENTS=( \ "mongodb-shell-2.0.2-0-linux-${OS_ARCH}-${OS_FLAVOUR}" \ "yq-4.35.2-3-linux-${OS_ARCH}-${OS_FLAVOUR}" \ "wait-for-port-1.0.7-2-linux-${OS_ARCH}-${OS_FLAVOUR}" \ "render-template-1.0.6-2-linux-${OS_ARCH}-${OS_FLAVOUR}" \ - ) && \ + ) ; \ for COMPONENT in "${COMPONENTS[@]}"; do \ if [ ! -f "${COMPONENT}.tar.gz" ]; then \ curl -SsLf "https://downloads.bitnami.com/files/stacksmith/${COMPONENT}.tar.gz" -O ; \ curl -SsLf "https://downloads.bitnami.com/files/stacksmith/${COMPONENT}.tar.gz.sha256" -O ; \ - fi && \ - sha256sum -c "${COMPONENT}.tar.gz.sha256" && \ - tar -zxf "${COMPONENT}.tar.gz" -C /opt/bitnami --strip-components=2 --no-same-owner --wildcards '*/files' && \ + fi ; \ + sha256sum -c "${COMPONENT}.tar.gz.sha256" ; \ + tar -zxf "${COMPONENT}.tar.gz" -C /opt/bitnami --strip-components=2 --no-same-owner --wildcards '*/files' ; \ rm -rf "${COMPONENT}".tar.gz{,.sha256} ; \ - done && \ - curl -SsLf "https://dist.flakybit.net/mongodb/mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz" -O && \ - curl -SsLf "https://dist.flakybit.net/mongodb/mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz.sha256" -O && \ - sha256sum -c "mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz.sha256" && \ - tar -zxf "mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz" -C /opt/bitnami/mongodb/bin --no-same-owner && \ + done ; \ + curl -SsLf "https://dist.flakybit.net/mongodb/mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz" -O ; \ + curl -SsLf "https://dist.flakybit.net/mongodb/mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz.sha256" -O ; \ + sha256sum -c "mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz.sha256" ; \ + tar -zxf "mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}.tar.gz" -C /opt/bitnami/mongodb/bin --no-same-owner ; \ rm -rf "mongodb-${VERSION}-0-linux-${OS_ARCH}-${OS_FLAVOUR}".tar.gz{,.sha256} RUN apt-get autoremove --purge -y curl && \ apt-get update && apt-get upgrade -y && \ apt-get clean && rm -rf /var/lib/apt/lists /var/cache/apt/archives RUN chmod g+rwX /opt/bitnami +RUN find / -perm /6000 -type f -exec chmod a-s {} \; || true COPY rootfs / RUN groupadd --gid $GID mongo && \ @@ -50,7 +52,7 @@ RUN groupadd --gid $GID mongo && \ RUN /opt/bitnami/scripts/mongodb/postunpack.sh ENV APP_VERSION="${VERSION}" \ BITNAMI_APP_NAME="mongodb" \ - PATH="/opt/bitnami/mongodb/bin:/opt/bitnami/common/bin:$PATH" + PATH="/opt/bitnami/common/bin:/opt/bitnami/mongodb/bin:$PATH" EXPOSE 27017 diff --git a/prebuildfs/opt/bitnami/.bitnami_components.json b/prebuildfs/opt/bitnami/.bitnami_components.json index 7783f1e..9943fab 100644 --- a/prebuildfs/opt/bitnami/.bitnami_components.json +++ b/prebuildfs/opt/bitnami/.bitnami_components.json @@ -3,24 +3,24 @@ "arch": "amd64", "distro": "debian-12", "type": "NAMI", - "version": "2.0.2-0" + "version": "2.1.5-0" }, "render-template": { "arch": "amd64", "distro": "debian-12", "type": "NAMI", - "version": "1.0.6-2" + "version": "1.0.6-9" }, "wait-for-port": { "arch": "amd64", "distro": "debian-12", "type": "NAMI", - "version": "1.0.7-2" + "version": "1.0.7-8" }, "yq": { "arch": "amd64", "distro": "debian-12", "type": "NAMI", - "version": "4.35.2-3" + "version": "4.41.1-0" } -} +} \ No newline at end of file diff --git a/prebuildfs/opt/bitnami/scripts/libbitnami.sh b/prebuildfs/opt/bitnami/scripts/libbitnami.sh index 184de8a..3853c78 100755 --- a/prebuildfs/opt/bitnami/scripts/libbitnami.sh +++ b/prebuildfs/opt/bitnami/scripts/libbitnami.sh @@ -44,10 +44,10 @@ print_welcome_page() { print_image_welcome_page() { local github_url="https://github.com/bitnami/containers" - log "" - log "${BOLD}Welcome to the Bitnami ${BITNAMI_APP_NAME} container${RESET}" - log "Subscribe to project updates by watching ${BOLD}${github_url}${RESET}" - log "Submit issues and feature requests at ${BOLD}${github_url}/issues${RESET}" - log "" + info "" + info "${BOLD}Welcome to the Bitnami ${BITNAMI_APP_NAME} container${RESET}" + info "Subscribe to project updates by watching ${BOLD}${github_url}${RESET}" + info "Submit issues and feature requests at ${BOLD}${github_url}/issues${RESET}" + info "" } diff --git a/rootfs/opt/bitnami/scripts/libmongodb.sh b/rootfs/opt/bitnami/scripts/libmongodb.sh index 4e6dc8c..ad0a0b1 100755 --- a/rootfs/opt/bitnami/scripts/libmongodb.sh +++ b/rootfs/opt/bitnami/scripts/libmongodb.sh @@ -383,7 +383,7 @@ mongodb_start_bg() { fi # wait until the server is up and answering queries - if ! retry_while "mongodb_is_mongodb_started" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_mongodb_started" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "MongoDB did not start" exit 1 fi @@ -423,7 +423,7 @@ mongodb_stop() { info "Stopping MongoDB..." stop_service_using_pid "$MONGODB_PID_FILE" - if ! retry_while "is_mongodb_not_running" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "is_mongodb_not_running" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "MongoDB failed to stop" exit 1 fi @@ -606,7 +606,7 @@ mongodb_set_auth_conf() { local authorization if ! mongodb_is_file_external "$conf_file_name"; then - if [[ -n "$MONGODB_ROOT_PASSWORD" ]] || [[ -n "$MONGODB_PASSWORD" ]]; then + if [[ -n "$MONGODB_ROOT_PASSWORD" ]] || [[ -n "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" ]] || [[ -n "$MONGODB_PASSWORD" ]]; then authorization="$(yq eval .security.authorization "$MONGODB_CONF_FILE")" if [[ "$authorization" = "disabled" ]]; then @@ -1003,7 +1003,7 @@ mongodb_configure_primary() { info "Configuring MongoDB primary node" wait-for-port --timeout 360 "$MONGODB_PORT_NUMBER" - if ! retry_while "mongodb_is_primary_node_initiated $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_primary_node_initiated $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "MongoDB primary node failed to get configured" exit 1 fi @@ -1024,7 +1024,7 @@ mongodb_wait_confirmation() { local -r port="${2:?port is required}" debug "Waiting until ${node}:${port} is added to the replica set..." - if ! retry_while "mongodb_node_currently_in_cluster ${node} ${port}" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_node_currently_in_cluster ${node} ${port}" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Unable to confirm that ${node}:${port} has been added to the replica set!" exit 1 else @@ -1052,7 +1052,7 @@ mongodb_is_primary_node_up() { db.isMaster().ismaster EOF ) - grep -q "true" <<<"$result" + grep -qE ".*\[direct:\s?\S+\]\s+admin>\s+true" <<<"$result" } ######################## @@ -1098,14 +1098,14 @@ mongodb_wait_for_node() { debug "Waiting for primary node..." info "Trying to connect to MongoDB server $host..." - if ! retry_while "wait-for-port --host $host --timeout 10 $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "wait-for-port --host $host --timeout 10 $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Unable to connect to host $host" exit 1 else info "Found MongoDB server listening at $host:$port !" fi - if ! retry_while "mongodb_is_node_available $host $port $user $password" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_node_available $host $port $user $password" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Node $host did not become available" exit 1 else @@ -1130,7 +1130,7 @@ mongodb_wait_for_primary_node() { mongodb_wait_for_node "$host" "$port" "$user" "$password" debug "Waiting for primary host $host to be ready..." - if ! retry_while "mongodb_is_primary_node_up $host $port $user $password" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_primary_node_up $host $port $user $password" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Unable to validate $host as primary node in the replica set scenario!" exit 1 else @@ -1158,7 +1158,7 @@ mongodb_configure_secondary() { info "Node currently in the cluster" else info "Adding node to the cluster" - if ! retry_while "mongodb_is_secondary_node_pending $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_secondary_node_pending $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Secondary node did not get ready" exit 1 fi @@ -1166,14 +1166,14 @@ mongodb_configure_secondary() { # Ensure that secondary nodes do not count as voting members until they are fully initialized # https://docs.mongodb.com/manual/reference/method/rs.add/#behavior - if ! retry_while "mongodb_is_secondary_node_ready $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_secondary_node_ready $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Secondary node did not get marked as secondary" exit 1 fi # Grant voting rights to node # https://docs.mongodb.com/manual/tutorial/modify-psa-replica-set-safely/ - if ! retry_while "mongodb_configure_secondary_node_voting $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_configure_secondary_node_voting $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Secondary node did not get marked as secondary" exit 1 fi @@ -1208,7 +1208,7 @@ mongodb_configure_hidden() { info "Node currently in the cluster" else info "Adding hidden node to the cluster" - if ! retry_while "mongodb_is_hidden_node_pending $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_hidden_node_pending $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Hidden node did not get ready" exit 1 fi @@ -1236,7 +1236,7 @@ mongodb_configure_arbiter() { info "Node currently in the cluster" else info "Configuring MongoDB arbiter node" - if ! retry_while "mongodb_is_arbiter_node_pending $node $port" "$MONGODB_MAX_TIMEOUT"; then + if ! retry_while "mongodb_is_arbiter_node_pending $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then error "Arbiter node did not get ready" exit 1 fi @@ -1277,8 +1277,8 @@ EOF mongodb_wait_until_sync_complete() { info "Waiting until initial data sync is complete..." - if ! retry_while "mongodb_is_not_in_sync" "$MONGODB_MAX_TIMEOUT" 1; then - error "Initial data sync did not finish after $MONGODB_MAX_TIMEOUT seconds" + if ! retry_while "mongodb_is_not_in_sync" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY" 1; then + error "Initial data sync did not finish after $((MONGODB_INIT_RETRY_ATTEMPTS * MONGODB_INIT_RETRY_DELAY)) seconds" exit 1 else info "initial data sync completed" diff --git a/rootfs/opt/bitnami/scripts/mongodb-env.sh b/rootfs/opt/bitnami/scripts/mongodb-env.sh index de9a36d..a405241 100755 --- a/rootfs/opt/bitnami/scripts/mongodb-env.sh +++ b/rootfs/opt/bitnami/scripts/mongodb-env.sh @@ -25,7 +25,8 @@ export BITNAMI_DEBUG="${BITNAMI_DEBUG:-false}" # variable will be overridden with the value specified in that file mongodb_env_vars=( MONGODB_MOUNTED_CONF_DIR - MONGODB_MAX_TIMEOUT + MONGODB_INIT_RETRY_ATTEMPTS + MONGODB_INIT_RETRY_DELAY MONGODB_PORT_NUMBER MONGODB_ENABLE_MAJORITY_READ MONGODB_DEFAULT_ENABLE_MAJORITY_READ @@ -84,6 +85,7 @@ export PATH="$BITNAMI_ROOT_DIR/mongodb/bin:$BITNAMI_ROOT_DIR/common/bin:$PATH" export MONGODB_VOLUME_DIR="$BITNAMI_VOLUME_DIR/mongodb" export MONGODB_BASE_DIR="$BITNAMI_ROOT_DIR/mongodb" export MONGODB_CONF_DIR="$MONGODB_BASE_DIR/conf" +export MONGODB_DEFAULT_CONF_DIR="$MONGODB_BASE_DIR/conf.default" export MONGODB_LOG_DIR="$MONGODB_BASE_DIR/logs" export MONGODB_DATA_DIR="${MONGODB_VOLUME_DIR}/data" export MONGODB_TMP_DIR="$MONGODB_BASE_DIR/tmp" @@ -106,7 +108,8 @@ export MONGODB_DAEMON_GROUP="mongo" # MongoDB configuration export MONGODB_MOUNTED_CONF_DIR="${MONGODB_MOUNTED_CONF_DIR:-${MONGODB_VOLUME_DIR}/conf}" -export MONGODB_MAX_TIMEOUT="${MONGODB_MAX_TIMEOUT:-35}" +export MONGODB_INIT_RETRY_ATTEMPTS="${MONGODB_INIT_RETRY_ATTEMPTS:-7}" +export MONGODB_INIT_RETRY_DELAY="${MONGODB_INIT_RETRY_DELAY:-5}" export MONGODB_DEFAULT_PORT_NUMBER="27017" export MONGODB_PORT_NUMBER="${MONGODB_PORT_NUMBER:-$MONGODB_DEFAULT_PORT_NUMBER}" export MONGODB_ENABLE_MAJORITY_READ="${MONGODB_ENABLE_MAJORITY_READ:-true}" diff --git a/rootfs/opt/bitnami/scripts/mongodb/entrypoint.sh b/rootfs/opt/bitnami/scripts/mongodb/entrypoint.sh index 15c4e2c..dbc13b7 100755 --- a/rootfs/opt/bitnami/scripts/mongodb/entrypoint.sh +++ b/rootfs/opt/bitnami/scripts/mongodb/entrypoint.sh @@ -18,6 +18,12 @@ set -o pipefail print_welcome_page +# We add the copy from default config in the entrypoint to not break users +# bypassing the setup.sh logic. If the file already exists do not overwrite (in +# case someone mounts a configuration file in /opt/bitnami/mongodb/conf) +debug "Copying files from $MONGODB_DEFAULT_CONF_DIR to $MONGODB_CONF_DIR" +cp -nr "$MONGODB_DEFAULT_CONF_DIR"/. "$MONGODB_CONF_DIR" + if [[ "$1" = "/opt/bitnami/scripts/mongodb/run.sh" ]]; then info "** Starting MongoDB setup **" /opt/bitnami/scripts/mongodb/setup.sh diff --git a/rootfs/opt/bitnami/scripts/mongodb/postunpack.sh b/rootfs/opt/bitnami/scripts/mongodb/postunpack.sh index ed67b0e..850da9a 100755 --- a/rootfs/opt/bitnami/scripts/mongodb/postunpack.sh +++ b/rootfs/opt/bitnami/scripts/mongodb/postunpack.sh @@ -17,11 +17,10 @@ set -o pipefail # Load environment . /opt/bitnami/scripts/mongodb-env.sh -for dir in "$MONGODB_TMP_DIR" "$MONGODB_LOG_DIR" "$MONGODB_CONF_DIR" "$MONGODB_DATA_DIR" "$MONGODB_VOLUME_DIR" "$MONGODB_INITSCRIPTS_DIR"; do +for dir in "$MONGODB_TMP_DIR" "$MONGODB_LOG_DIR" "$MONGODB_CONF_DIR" "$MONGODB_DEFAULT_CONF_DIR" "$MONGODB_DATA_DIR" "$MONGODB_VOLUME_DIR" "$MONGODB_INITSCRIPTS_DIR"; do ensure_dir_exists "$dir" done chmod -R g+rwX "$MONGODB_TMP_DIR" "$MONGODB_LOG_DIR" "$MONGODB_CONF_DIR" "$MONGODB_DATA_DIR" "$MONGODB_VOLUME_DIR" "$MONGODB_INITSCRIPTS_DIR" -chown -R $UID:$GID "$MONGODB_TMP_DIR" "$MONGODB_LOG_DIR" "$MONGODB_CONF_DIR" "$MONGODB_DATA_DIR" "$MONGODB_VOLUME_DIR" render-template "$MONGODB_MONGOD_TEMPLATES_FILE" >"$MONGODB_CONF_FILE" @@ -34,11 +33,15 @@ touch "$MONGOSH_RC_FILE" && chmod g+rw "$MONGOSH_RC_FILE" # Create .mongodb folder to avoid error message mkdir "$MONGOSH_DIR" && chmod g+rwX "$MONGOSH_DIR" -chown $UID:$GID "$MONGODB_CONF_FILE" chmod 660 "$MONGODB_CONF_FILE" # Redirect all logging to stdout ln -sf /dev/stdout "$MONGODB_LOG_FILE" +# Copy all initially generated configuration files to the default directory +# (this is to avoid breaking when entrypoint is being overridden) +cp -r "${MONGODB_CONF_DIR}/"* "$MONGODB_DEFAULT_CONF_DIR" +chmod o+r -R "$MONGODB_DEFAULT_CONF_DIR" + chown -R $UID:$GID "$MONGODB_TMP_DIR" "$MONGODB_LOG_DIR" "$MONGODB_CONF_DIR" "$MONGODB_DATA_DIR" "$MONGODB_VOLUME_DIR" "$MONGOSH_DIR" chown $UID:$GID "$MONGODB_DB_SHELL_FILE" "$MONGODB_RC_FILE" "$MONGOSH_RC_FILE"