diff --git a/4.4/Dockerfile b/4.4/Dockerfile new file mode 100644 index 000000000..8021f249e --- /dev/null +++ b/4.4/Dockerfile @@ -0,0 +1,119 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM ubuntu:focal + +# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added +RUN set -eux; \ + groupadd --gid 999 --system mongodb; \ + useradd --uid 999 --system --gid mongodb --home-dir /data/db mongodb; \ + mkdir -p /data/db /data/configdb; \ + chown -R mongodb:mongodb /data/db /data/configdb + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + jq \ + numactl \ + procps \ + ; \ + rm -rf /var/lib/apt/lists/* + +# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases) +ENV GOSU_VERSION 1.19 +# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases) +ENV JSYAML_VERSION 3.13.1 +ENV JSYAML_CHECKSUM 662e32319bdd378e91f67578e56a34954b0a2e33aca11d70ab9f4826af24b941 + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + gnupg \ + wget \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ +# download/install gosu + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ + wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ + wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ + \ +# download/install js-yaml + mkdir -p /opt/js-yaml/; \ + wget -O /opt/js-yaml/js-yaml.tgz https://registry.npmjs.org/js-yaml/-/js-yaml-${JSYAML_VERSION}.tgz; \ + echo "$JSYAML_CHECKSUM */opt/js-yaml/js-yaml.tgz" | sha256sum -c -; \ + tar -xz --strip-components=1 -f /opt/js-yaml/js-yaml.tgz -C /opt/js-yaml package/dist/js-yaml.js package/package.json; \ + rm /opt/js-yaml/js-yaml.tgz; \ + ln -s /opt/js-yaml/dist/js-yaml.js /js-yaml.js; \ + \ +# download/install MongoDB PGP keys + export GNUPGHOME="$(mktemp -d)"; \ + wget -O KEYS 'https://pgp.mongodb.com/server-4.4.asc'; \ + gpg --batch --import KEYS; \ + mkdir -p /etc/apt/keyrings; \ + gpg --batch --export --armor '20691EEC35216C63CAF66CE1656408E390CFB1F5' > /etc/apt/keyrings/mongodb.asc; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME" KEYS; \ + \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ +# smoke test + chmod +x /usr/local/bin/gosu; \ + gosu --version; \ + gosu nobody true + +RUN mkdir /docker-entrypoint-initdb.d + +# Allow build-time overrides (eg. to build image with MongoDB Enterprise version) +# Options for MONGO_PACKAGE: mongodb-org OR mongodb-enterprise +# Options for MONGO_REPO: repo.mongodb.org OR repo.mongodb.com +# Example: docker build --build-arg MONGO_PACKAGE=mongodb-enterprise --build-arg MONGO_REPO=repo.mongodb.com . +ARG MONGO_PACKAGE=mongodb-org +ARG MONGO_REPO=repo.mongodb.org +ENV MONGO_PACKAGE=${MONGO_PACKAGE} MONGO_REPO=${MONGO_REPO} + +ENV MONGO_MAJOR 4.4 +RUN echo "deb [ signed-by=/etc/apt/keyrings/mongodb.asc ] http://$MONGO_REPO/apt/ubuntu focal/${MONGO_PACKAGE%-unstable}/$MONGO_MAJOR multiverse" | tee "/etc/apt/sources.list.d/${MONGO_PACKAGE%-unstable}.list" + +# https://docs.mongodb.org/master/release-notes/4.4/ +ENV MONGO_VERSION 4.4.30 +# 12/18/2025, https://github.com/mongodb/mongo/tree/4d7fa6a6260d25c5caa971dce10561690cb79dea + +RUN set -x \ +# installing "mongodb-enterprise" pulls in "tzdata" which prompts for input + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install -y \ + ${MONGO_PACKAGE}=$MONGO_VERSION \ + ${MONGO_PACKAGE}-server=$MONGO_VERSION \ + ${MONGO_PACKAGE}-shell=$MONGO_VERSION \ + ${MONGO_PACKAGE}-mongos=$MONGO_VERSION \ + ${MONGO_PACKAGE}-tools=$MONGO_VERSION \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/lib/mongodb \ + && mv /etc/mongod.conf /etc/mongod.conf.orig + +VOLUME /data/db /data/configdb + +# ensure that if running as custom user that "mongosh" has a valid "HOME" +# https://github.com/docker-library/mongo/issues/524 +ENV HOME /data/db + +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 27017 +CMD ["mongod"] diff --git a/4.4/docker-entrypoint.sh b/4.4/docker-entrypoint.sh new file mode 100755 index 000000000..d37d1b92b --- /dev/null +++ b/4.4/docker-entrypoint.sh @@ -0,0 +1,420 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +if [ "${1:0:1}" = '-' ]; then + set -- mongod "$@" +fi + +originalArgOne="$1" + +# allow the container to be started with `--user` +# all mongo* commands should be dropped to the correct user +if [[ "$originalArgOne" == mongo* ]] && [ "$(id -u)" = '0' ]; then + if [ "$originalArgOne" = 'mongod' ]; then + find -L /data/configdb /data/db \! -user mongodb -exec chown mongodb '{}' + + fi + + # make sure we can write to stdout and stderr as "mongodb" + # (for our "initdb" code later; see "--logpath" below) + chown --dereference mongodb "/proc/$$/fd/1" "/proc/$$/fd/2" || : + # ignore errors thanks to https://github.com/docker-library/mongo/issues/149 + + exec gosu mongodb "$BASH_SOURCE" "$@" +fi + +dpkgArch="$(dpkg --print-architecture)" +case "$dpkgArch" in + amd64) # https://github.com/docker-library/mongo/issues/485#issuecomment-891991814 + if ! grep -qE '^flags.* avx( .*|$)' /proc/cpuinfo; then + { + echo + echo 'WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!' + echo ' see https://jira.mongodb.org/browse/SERVER-54407' + echo ' see also https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2' + echo ' see also https://github.com/docker-library/mongo/issues/485#issuecomment-891991814' + echo + } >&2 + fi + ;; + + arm64) # https://github.com/docker-library/mongo/issues/485#issuecomment-970864306 + # https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features + # http://javathunderx.blogspot.com/2018/11/cheat-sheet-for-cpuinfo-features-on.html + if ! grep -qE '^Features.* (fphp|dcpop|sha3|sm3|sm4|asimddp|sha512|sve)( .*|$)' /proc/cpuinfo; then + { + echo + echo 'WARNING: MongoDB requires ARMv8.2-A or higher, and your current system does not appear to implement any of the common features for that!' + echo ' applies to all versions ≥5.0, any of 4.4 ≥4.4.19' + echo ' see https://jira.mongodb.org/browse/SERVER-71772' + echo ' see https://jira.mongodb.org/browse/SERVER-55178' + echo ' see also https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features' + echo ' see also https://github.com/docker-library/mongo/issues/485#issuecomment-970864306' + echo + } >&2 + fi + ;; +esac + +# you should use numactl to start your mongod instances, including the config servers, mongos instances, and any clients. +# https://docs.mongodb.com/manual/administration/production-notes/#configuring-numa-on-linux +if [[ "$originalArgOne" == mongo* ]]; then + numa='numactl --interleave=all' + if $numa true &> /dev/null; then + set -- $numa "$@" + fi +fi + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# see https://github.com/docker-library/mongo/issues/147 (mongod is picky about duplicated arguments) +_mongod_hack_have_arg() { + local checkArg="$1"; shift + local arg + for arg; do + case "$arg" in + "$checkArg"|"$checkArg"=*) + return 0 + ;; + esac + done + return 1 +} +# _mongod_hack_get_arg_val '--some-arg' "$@" +_mongod_hack_get_arg_val() { + local checkArg="$1"; shift + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + case "$arg" in + "$checkArg") + echo "$1" + return 0 + ;; + "$checkArg"=*) + echo "${arg#$checkArg=}" + return 0 + ;; + esac + done + return 1 +} +declare -a mongodHackedArgs +# _mongod_hack_ensure_arg '--some-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_arg() { + local ensureArg="$1"; shift + mongodHackedArgs=( "$@" ) + if ! _mongod_hack_have_arg "$ensureArg" "$@"; then + mongodHackedArgs+=( "$ensureArg" ) + fi +} +# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_no_arg() { + local ensureNoArg="$1"; shift + mongodHackedArgs=() + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + if [ "$arg" = "$ensureNoArg" ]; then + continue + fi + mongodHackedArgs+=( "$arg" ) + done +} +# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_no_arg_val() { + local ensureNoArg="$1"; shift + mongodHackedArgs=() + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + case "$arg" in + "$ensureNoArg") + shift # also skip the value + continue + ;; + "$ensureNoArg"=*) + # value is already included + continue + ;; + esac + mongodHackedArgs+=( "$arg" ) + done +} +# _mongod_hack_ensure_arg_val '--some-arg' 'some-val' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_arg_val() { + local ensureArg="$1"; shift + local ensureVal="$1"; shift + _mongod_hack_ensure_no_arg_val "$ensureArg" "$@" + mongodHackedArgs+=( "$ensureArg" "$ensureVal" ) +} + +# _js_escape 'some "string" value' +_js_escape() { + jq --null-input --arg 'str' "$1" '$str' +} + +: "${TMPDIR:=/tmp}" +jsonConfigFile="$TMPDIR/docker-entrypoint-config.json" +tempConfigFile="$TMPDIR/docker-entrypoint-temp-config.json" +_parse_config() { + if [ -s "$tempConfigFile" ]; then + return 0 + fi + + local configPath + if configPath="$(_mongod_hack_get_arg_val --config "$@")" && [ -s "$configPath" ]; then + # if --config is specified, parse it into a JSON file so we can remove a few problematic keys (especially SSL-related keys) + # see https://docs.mongodb.com/manual/reference/configuration-options/ + if grep -vEm1 '^[[:space:]]*(#|$)' "$configPath" | grep -qE '^[[:space:]]*[^=:]+[[:space:]]*='; then + # if the first non-comment/non-blank line of the config file looks like "foo = ...", this is probably the 2.4 and older "ini-style config format" + # mongod tries to parse config as yaml and then falls back to ini-style parsing + # https://github.com/mongodb/mongo/blob/r6.0.3/src/mongo/util/options_parser/options_parser.cpp#L1883-L1894 + echo >&2 + echo >&2 "WARNING: it appears that '$configPath' is in the older INI-style format (replaced by YAML in MongoDB 2.6)" + echo >&2 ' This script does not parse the older INI-style format, and thus will ignore it.' + echo >&2 + return 1 + fi + if [ "$mongoShell" = 'mongo' ]; then + "$mongoShell" --norc --nodb --quiet --eval "load('/js-yaml.js'); printjson(jsyaml.load(cat($(_js_escape "$configPath"))))" > "$jsonConfigFile" + else + # https://www.mongodb.com/docs/manual/reference/method/js-native/#std-label-native-in-mongosh + "$mongoShell" --norc --nodb --quiet --eval "load('/js-yaml.js'); JSON.stringify(jsyaml.load(fs.readFileSync($(_js_escape "$configPath"), 'utf8')))" > "$jsonConfigFile" + fi + if [ "$(head -c1 "$jsonConfigFile")" != '{' ] || [ "$(tail -c2 "$jsonConfigFile")" != '}' ]; then + # if the file doesn't start with "{" and end with "}", it's *probably* an error ("uncaught exception: YAMLException: foo" for example), so we should print it out + echo >&2 'error: unexpected "js-yaml.js" output while parsing config:' + cat >&2 "$jsonConfigFile" + exit 1 + fi + jq 'del(.systemLog, .processManagement, .net, .security, .replication)' "$jsonConfigFile" > "$tempConfigFile" + return 0 + fi + + return 1 +} +dbPath= +_dbPath() { + if [ -n "$dbPath" ]; then + echo "$dbPath" + return + fi + + if ! dbPath="$(_mongod_hack_get_arg_val --dbpath "$@")"; then + if _parse_config "$@"; then + dbPath="$(jq -r '.storage.dbPath // empty' "$jsonConfigFile")" + fi + fi + + if [ -z "$dbPath" ]; then + if _mongod_hack_have_arg --configsvr "$@" || { + _parse_config "$@" \ + && clusterRole="$(jq -r '.sharding.clusterRole // empty' "$jsonConfigFile")" \ + && [ "$clusterRole" = 'configsvr' ] + }; then + # if running as config server, then the default dbpath is /data/configdb + # https://docs.mongodb.com/manual/reference/program/mongod/#cmdoption-mongod-configsvr + dbPath=/data/configdb + fi + fi + + : "${dbPath:=/data/db}" + + echo "$dbPath" +} + +if [ "$originalArgOne" = 'mongod' ]; then + file_env 'MONGO_INITDB_ROOT_USERNAME' + file_env 'MONGO_INITDB_ROOT_PASSWORD' + + mongoShell='mongo' + if ! command -v "$mongoShell" > /dev/null; then + mongoShell='mongosh' + fi + + # pre-check a few factors to see if it's even worth bothering with initdb + shouldPerformInitdb= + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + # if we have a username/password, let's set "--auth" + _mongod_hack_ensure_arg '--auth' "$@" + set -- "${mongodHackedArgs[@]}" + shouldPerformInitdb='true' + elif [ "$MONGO_INITDB_ROOT_USERNAME" ] || [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + cat >&2 <<-'EOF' + + error: missing 'MONGO_INITDB_ROOT_USERNAME' or 'MONGO_INITDB_ROOT_PASSWORD' + both must be specified for a user to be created + + EOF + exit 1 + fi + + if [ -z "$shouldPerformInitdb" ]; then + # if we've got any /docker-entrypoint-initdb.d/* files to parse later, we should initdb + for f in /docker-entrypoint-initdb.d/*; do + case "$f" in + *.sh|*.js) # this should match the set of files we check for below + shouldPerformInitdb="$f" + break + ;; + esac + done + fi + + # check for a few known paths (to determine whether we've already initialized and should thus skip our initdb scripts) + if [ -n "$shouldPerformInitdb" ]; then + dbPath="$(_dbPath "$@")" + for path in \ + "$dbPath/WiredTiger" \ + "$dbPath/journal" \ + "$dbPath/local.0" \ + "$dbPath/storage.bson" \ + ; do + if [ -e "$path" ]; then + shouldPerformInitdb= + break + fi + done + fi + + if [ -n "$shouldPerformInitdb" ]; then + mongodHackedArgs=( "$@" ) + if _parse_config "$@"; then + _mongod_hack_ensure_arg_val --config "$tempConfigFile" "${mongodHackedArgs[@]}" + fi + _mongod_hack_ensure_arg_val --bind_ip 127.0.0.1 "${mongodHackedArgs[@]}" + _mongod_hack_ensure_arg_val --port 27017 "${mongodHackedArgs[@]}" + _mongod_hack_ensure_no_arg --bind_ip_all "${mongodHackedArgs[@]}" + + # remove "--auth" and "--replSet" for our initial startup (see https://docs.mongodb.com/manual/tutorial/enable-authentication/#start-mongodb-without-access-control) + # https://github.com/docker-library/mongo/issues/211 + _mongod_hack_ensure_no_arg --auth "${mongodHackedArgs[@]}" + # "keyFile implies security.authorization" + # https://docs.mongodb.com/manual/reference/configuration-options/#mongodb-setting-security.keyFile + _mongod_hack_ensure_no_arg_val --keyFile "${mongodHackedArgs[@]}" + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + _mongod_hack_ensure_no_arg_val --replSet "${mongodHackedArgs[@]}" + fi + + # "BadValue: need sslPEMKeyFile when SSL is enabled" vs "BadValue: need to enable SSL via the sslMode flag when using SSL configuration parameters" + tlsMode='disabled' + if _mongod_hack_have_arg '--tlsCertificateKeyFile' "$@"; then + tlsMode='allowTLS' + fi + _mongod_hack_ensure_arg_val --tlsMode "$tlsMode" "${mongodHackedArgs[@]}" + + if stat "/proc/$$/fd/1" > /dev/null && [ -w "/proc/$$/fd/1" ]; then + # https://github.com/mongodb/mongo/blob/38c0eb538d0fd390c6cb9ce9ae9894153f6e8ef5/src/mongo/db/initialize_server_global_state.cpp#L237-L251 + # https://github.com/docker-library/mongo/issues/164#issuecomment-293965668 + _mongod_hack_ensure_arg_val --logpath "/proc/$$/fd/1" "${mongodHackedArgs[@]}" + else + initdbLogPath="$(_dbPath "$@")/docker-initdb.log" + echo >&2 "warning: initdb logs cannot write to '/proc/$$/fd/1', so they are in '$initdbLogPath' instead" + _mongod_hack_ensure_arg_val --logpath "$initdbLogPath" "${mongodHackedArgs[@]}" + fi + _mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}" + + pidfile="$TMPDIR/docker-entrypoint-temp-mongod.pid" + rm -f "$pidfile" + _mongod_hack_ensure_arg_val --pidfilepath "$pidfile" "${mongodHackedArgs[@]}" + + "${mongodHackedArgs[@]}" --fork + + mongo=( "$mongoShell" --host 127.0.0.1 --port 27017 --quiet ) + + # check to see that our "mongod" actually did start up (catches "--help", "--version", slow prealloc, etc) + # https://jira.mongodb.org/browse/SERVER-16292 + tries=30 + while true; do + if ! { [ -s "$pidfile" ] && ps "$(< "$pidfile")" &> /dev/null; }; then + # bail ASAP if "mongod" isn't even running + echo >&2 + echo >&2 "error: $originalArgOne does not appear to have stayed running -- perhaps it had an error?" + echo >&2 + exit 1 + fi + if "${mongo[@]}" 'admin' --eval 'quit(0)' &> /dev/null; then + # success! + break + fi + (( tries-- )) + if [ "$tries" -le 0 ]; then + echo >&2 + echo >&2 "error: $originalArgOne does not appear to have accepted connections quickly enough -- perhaps it had an error?" + echo >&2 + exit 1 + fi + sleep 1 + done + + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + rootAuthDatabase='admin' + + "${mongo[@]}" "$rootAuthDatabase" <<-EOJS + db.createUser({ + user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"), + pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"), + roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ] + }) + EOJS + fi + + export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}" + + echo + for f in /docker-entrypoint-initdb.d/*; do + case "$f" in + *.sh) echo "$0: running $f"; . "$f" ;; + *.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done + + "${mongodHackedArgs[@]}" --shutdown + rm -f "$pidfile" + + echo + echo 'MongoDB init process complete; ready for start up.' + echo + fi + + # MongoDB defaults to localhost-only binding + haveBindIp= + if _mongod_hack_have_arg --bind_ip "$@" || _mongod_hack_have_arg --bind_ip_all "$@"; then + haveBindIp=1 + elif _parse_config "$@" && jq --exit-status '.net.bindIp // .net.bindIpAll' "$jsonConfigFile" > /dev/null; then + haveBindIp=1 + fi + if [ -z "$haveBindIp" ]; then + # so if no "--bind_ip" is specified, let's add "--bind_ip_all" + set -- "$@" --bind_ip_all + fi + + unset "${!MONGO_INITDB_@}" +fi + +rm -f "$jsonConfigFile" "$tempConfigFile" + +exec "$@" diff --git a/4.4/windows/nanoserver-ltsc2022/Dockerfile b/4.4/windows/nanoserver-ltsc2022/Dockerfile new file mode 100644 index 000000000..c129efec3 --- /dev/null +++ b/4.4/windows/nanoserver-ltsc2022/Dockerfile @@ -0,0 +1,34 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 + +SHELL ["cmd", "/S", "/C"] + +# PATH isn't actually set in the Docker image, so we have to set it from within the container +USER ContainerAdministrator +RUN setx /m PATH "C:\mongodb\bin;%PATH%" +USER ContainerUser +# doing this first to share cache across versions more aggressively + +COPY --from=mongo:4.4.30-windowsservercore-ltsc2022 \ + C:\\Windows\\System32\\msvcp140.dll \ + C:\\Windows\\System32\\msvcp140_1.dll \ + C:\\Windows\\System32\\vcruntime140.dll \ + C:\\Windows\\System32\\vcruntime140_1.dll \ + C:\\Windows\\System32\\ + +# https://docs.mongodb.org/master/release-notes/4.4/ +ENV MONGO_VERSION 4.4.30 +# 12/18/2025, https://github.com/mongodb/mongo/tree/4d7fa6a6260d25c5caa971dce10561690cb79dea + +COPY --from=mongo:4.4.30-windowsservercore-ltsc2022 C:\\mongodb C:\\mongodb +RUN mongod --version + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/4.4/windows/windowsservercore-ltsc2022/Dockerfile b/4.4/windows/windowsservercore-ltsc2022/Dockerfile new file mode 100644 index 000000000..56432f2da --- /dev/null +++ b/4.4/windows/windowsservercore-ltsc2022/Dockerfile @@ -0,0 +1,67 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/servercore:ltsc2022 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"] + +# https://docs.mongodb.org/master/release-notes/4.4/ +ENV MONGO_VERSION 4.4.30 +# 12/18/2025, https://github.com/mongodb/mongo/tree/4d7fa6a6260d25c5caa971dce10561690cb79dea + +ENV MONGO_DOWNLOAD_URL https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-4.4.30-signed.msi +ENV MONGO_DOWNLOAD_SHA256=c635b5ab758e4d37a248295009f6f12948125dcaec7303be276f2cce31170e46 + +RUN Write-Host ('Downloading {0} ...' -f $env:MONGO_DOWNLOAD_URL); \ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + (New-Object System.Net.WebClient).DownloadFile($env:MONGO_DOWNLOAD_URL, 'mongo.msi'); \ + \ + if ($env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:MONGO_DOWNLOAD_SHA256); \ + if ((Get-FileHash mongo.msi -Algorithm sha256).Hash -ne $env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + }; \ + \ + Write-Host 'Installing ...'; \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#install-mongodb-community-edition + Start-Process msiexec -Wait \ + -ArgumentList @( \ + '/i', \ + 'mongo.msi', \ + '/quiet', \ + '/qn', \ + '/l*v', 'install.log', \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows-unattended/#run-the-windows-installer-from-the-windows-command-interpreter + 'INSTALLLOCATION=C:\mongodb', \ + 'ADDLOCAL=MiscellaneousTools,Router,ServerNoService' \ + ); \ + if (-Not (Test-Path C:\mongodb\bin\mongod.exe -PathType Leaf)) { \ + Write-Host 'Installer failed!'; \ + Get-Content install.log; \ + exit 1; \ + }; \ + Remove-Item install.log; \ + \ + $env:PATH = 'C:\mongodb\bin;' + $env:PATH; \ + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Verifying install ...'; \ + Write-Host ' mongod --version'; mongod --version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item C:\windows\installer\*.msi -Force; \ + Remove-Item mongo.msi -Force; \ + \ + Write-Host 'Complete.'; + +# TODO docker-entrypoint.ps1 ? (for "docker run --flag --flag --flag") + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/4.4/windows/windowsservercore-ltsc2025/Dockerfile b/4.4/windows/windowsservercore-ltsc2025/Dockerfile new file mode 100644 index 000000000..a2f3b2771 --- /dev/null +++ b/4.4/windows/windowsservercore-ltsc2025/Dockerfile @@ -0,0 +1,67 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/servercore:ltsc2025 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"] + +# https://docs.mongodb.org/master/release-notes/4.4/ +ENV MONGO_VERSION 4.4.30 +# 12/18/2025, https://github.com/mongodb/mongo/tree/4d7fa6a6260d25c5caa971dce10561690cb79dea + +ENV MONGO_DOWNLOAD_URL https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-4.4.30-signed.msi +ENV MONGO_DOWNLOAD_SHA256=c635b5ab758e4d37a248295009f6f12948125dcaec7303be276f2cce31170e46 + +RUN Write-Host ('Downloading {0} ...' -f $env:MONGO_DOWNLOAD_URL); \ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + (New-Object System.Net.WebClient).DownloadFile($env:MONGO_DOWNLOAD_URL, 'mongo.msi'); \ + \ + if ($env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:MONGO_DOWNLOAD_SHA256); \ + if ((Get-FileHash mongo.msi -Algorithm sha256).Hash -ne $env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + }; \ + \ + Write-Host 'Installing ...'; \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#install-mongodb-community-edition + Start-Process msiexec -Wait \ + -ArgumentList @( \ + '/i', \ + 'mongo.msi', \ + '/quiet', \ + '/qn', \ + '/l*v', 'install.log', \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows-unattended/#run-the-windows-installer-from-the-windows-command-interpreter + 'INSTALLLOCATION=C:\mongodb', \ + 'ADDLOCAL=MiscellaneousTools,Router,ServerNoService' \ + ); \ + if (-Not (Test-Path C:\mongodb\bin\mongod.exe -PathType Leaf)) { \ + Write-Host 'Installer failed!'; \ + Get-Content install.log; \ + exit 1; \ + }; \ + Remove-Item install.log; \ + \ + $env:PATH = 'C:\mongodb\bin;' + $env:PATH; \ + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Verifying install ...'; \ + Write-Host ' mongod --version'; mongod --version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item C:\windows\installer\*.msi -Force; \ + Remove-Item mongo.msi -Force; \ + \ + Write-Host 'Complete.'; + +# TODO docker-entrypoint.ps1 ? (for "docker run --flag --flag --flag") + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/5.0/Dockerfile b/5.0/Dockerfile new file mode 100644 index 000000000..f90fd6e12 --- /dev/null +++ b/5.0/Dockerfile @@ -0,0 +1,119 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM ubuntu:focal + +# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added +RUN set -eux; \ + groupadd --gid 999 --system mongodb; \ + useradd --uid 999 --system --gid mongodb --home-dir /data/db mongodb; \ + mkdir -p /data/db /data/configdb; \ + chown -R mongodb:mongodb /data/db /data/configdb + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + jq \ + numactl \ + procps \ + ; \ + rm -rf /var/lib/apt/lists/* + +# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases) +ENV GOSU_VERSION 1.19 +# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases) +ENV JSYAML_VERSION 3.13.1 +ENV JSYAML_CHECKSUM 662e32319bdd378e91f67578e56a34954b0a2e33aca11d70ab9f4826af24b941 + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + gnupg \ + wget \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ +# download/install gosu + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ + wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ + wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ + \ +# download/install js-yaml + mkdir -p /opt/js-yaml/; \ + wget -O /opt/js-yaml/js-yaml.tgz https://registry.npmjs.org/js-yaml/-/js-yaml-${JSYAML_VERSION}.tgz; \ + echo "$JSYAML_CHECKSUM */opt/js-yaml/js-yaml.tgz" | sha256sum -c -; \ + tar -xz --strip-components=1 -f /opt/js-yaml/js-yaml.tgz -C /opt/js-yaml package/dist/js-yaml.js package/package.json; \ + rm /opt/js-yaml/js-yaml.tgz; \ + ln -s /opt/js-yaml/dist/js-yaml.js /js-yaml.js; \ + \ +# download/install MongoDB PGP keys + export GNUPGHOME="$(mktemp -d)"; \ + wget -O KEYS 'https://pgp.mongodb.com/server-5.0.asc'; \ + gpg --batch --import KEYS; \ + mkdir -p /etc/apt/keyrings; \ + gpg --batch --export --armor 'F5679A222C647C87527C2F8CB00A0BD1E2C63C11' > /etc/apt/keyrings/mongodb.asc; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME" KEYS; \ + \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ +# smoke test + chmod +x /usr/local/bin/gosu; \ + gosu --version; \ + gosu nobody true + +RUN mkdir /docker-entrypoint-initdb.d + +# Allow build-time overrides (eg. to build image with MongoDB Enterprise version) +# Options for MONGO_PACKAGE: mongodb-org OR mongodb-enterprise +# Options for MONGO_REPO: repo.mongodb.org OR repo.mongodb.com +# Example: docker build --build-arg MONGO_PACKAGE=mongodb-enterprise --build-arg MONGO_REPO=repo.mongodb.com . +ARG MONGO_PACKAGE=mongodb-org +ARG MONGO_REPO=repo.mongodb.org +ENV MONGO_PACKAGE=${MONGO_PACKAGE} MONGO_REPO=${MONGO_REPO} + +ENV MONGO_MAJOR 5.0 +RUN echo "deb [ signed-by=/etc/apt/keyrings/mongodb.asc ] http://$MONGO_REPO/apt/ubuntu focal/${MONGO_PACKAGE%-unstable}/$MONGO_MAJOR multiverse" | tee "/etc/apt/sources.list.d/${MONGO_PACKAGE%-unstable}.list" + +# https://docs.mongodb.org/master/release-notes/5.0/ +ENV MONGO_VERSION 5.0.32 +# 12/17/2025, https://github.com/mongodb/mongo/tree/ba92303e18e7ed4701572aa15acd161c97796f2f + +RUN set -x \ +# installing "mongodb-enterprise" pulls in "tzdata" which prompts for input + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install -y \ + ${MONGO_PACKAGE}=$MONGO_VERSION \ + ${MONGO_PACKAGE}-server=$MONGO_VERSION \ + ${MONGO_PACKAGE}-shell=$MONGO_VERSION \ + ${MONGO_PACKAGE}-mongos=$MONGO_VERSION \ + ${MONGO_PACKAGE}-tools=$MONGO_VERSION \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/lib/mongodb \ + && mv /etc/mongod.conf /etc/mongod.conf.orig + +VOLUME /data/db /data/configdb + +# ensure that if running as custom user that "mongosh" has a valid "HOME" +# https://github.com/docker-library/mongo/issues/524 +ENV HOME /data/db + +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 27017 +CMD ["mongod"] diff --git a/5.0/docker-entrypoint.sh b/5.0/docker-entrypoint.sh new file mode 100755 index 000000000..d37d1b92b --- /dev/null +++ b/5.0/docker-entrypoint.sh @@ -0,0 +1,420 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +if [ "${1:0:1}" = '-' ]; then + set -- mongod "$@" +fi + +originalArgOne="$1" + +# allow the container to be started with `--user` +# all mongo* commands should be dropped to the correct user +if [[ "$originalArgOne" == mongo* ]] && [ "$(id -u)" = '0' ]; then + if [ "$originalArgOne" = 'mongod' ]; then + find -L /data/configdb /data/db \! -user mongodb -exec chown mongodb '{}' + + fi + + # make sure we can write to stdout and stderr as "mongodb" + # (for our "initdb" code later; see "--logpath" below) + chown --dereference mongodb "/proc/$$/fd/1" "/proc/$$/fd/2" || : + # ignore errors thanks to https://github.com/docker-library/mongo/issues/149 + + exec gosu mongodb "$BASH_SOURCE" "$@" +fi + +dpkgArch="$(dpkg --print-architecture)" +case "$dpkgArch" in + amd64) # https://github.com/docker-library/mongo/issues/485#issuecomment-891991814 + if ! grep -qE '^flags.* avx( .*|$)' /proc/cpuinfo; then + { + echo + echo 'WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!' + echo ' see https://jira.mongodb.org/browse/SERVER-54407' + echo ' see also https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2' + echo ' see also https://github.com/docker-library/mongo/issues/485#issuecomment-891991814' + echo + } >&2 + fi + ;; + + arm64) # https://github.com/docker-library/mongo/issues/485#issuecomment-970864306 + # https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features + # http://javathunderx.blogspot.com/2018/11/cheat-sheet-for-cpuinfo-features-on.html + if ! grep -qE '^Features.* (fphp|dcpop|sha3|sm3|sm4|asimddp|sha512|sve)( .*|$)' /proc/cpuinfo; then + { + echo + echo 'WARNING: MongoDB requires ARMv8.2-A or higher, and your current system does not appear to implement any of the common features for that!' + echo ' applies to all versions ≥5.0, any of 4.4 ≥4.4.19' + echo ' see https://jira.mongodb.org/browse/SERVER-71772' + echo ' see https://jira.mongodb.org/browse/SERVER-55178' + echo ' see also https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features' + echo ' see also https://github.com/docker-library/mongo/issues/485#issuecomment-970864306' + echo + } >&2 + fi + ;; +esac + +# you should use numactl to start your mongod instances, including the config servers, mongos instances, and any clients. +# https://docs.mongodb.com/manual/administration/production-notes/#configuring-numa-on-linux +if [[ "$originalArgOne" == mongo* ]]; then + numa='numactl --interleave=all' + if $numa true &> /dev/null; then + set -- $numa "$@" + fi +fi + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# see https://github.com/docker-library/mongo/issues/147 (mongod is picky about duplicated arguments) +_mongod_hack_have_arg() { + local checkArg="$1"; shift + local arg + for arg; do + case "$arg" in + "$checkArg"|"$checkArg"=*) + return 0 + ;; + esac + done + return 1 +} +# _mongod_hack_get_arg_val '--some-arg' "$@" +_mongod_hack_get_arg_val() { + local checkArg="$1"; shift + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + case "$arg" in + "$checkArg") + echo "$1" + return 0 + ;; + "$checkArg"=*) + echo "${arg#$checkArg=}" + return 0 + ;; + esac + done + return 1 +} +declare -a mongodHackedArgs +# _mongod_hack_ensure_arg '--some-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_arg() { + local ensureArg="$1"; shift + mongodHackedArgs=( "$@" ) + if ! _mongod_hack_have_arg "$ensureArg" "$@"; then + mongodHackedArgs+=( "$ensureArg" ) + fi +} +# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_no_arg() { + local ensureNoArg="$1"; shift + mongodHackedArgs=() + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + if [ "$arg" = "$ensureNoArg" ]; then + continue + fi + mongodHackedArgs+=( "$arg" ) + done +} +# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_no_arg_val() { + local ensureNoArg="$1"; shift + mongodHackedArgs=() + while [ "$#" -gt 0 ]; do + local arg="$1"; shift + case "$arg" in + "$ensureNoArg") + shift # also skip the value + continue + ;; + "$ensureNoArg"=*) + # value is already included + continue + ;; + esac + mongodHackedArgs+=( "$arg" ) + done +} +# _mongod_hack_ensure_arg_val '--some-arg' 'some-val' "$@" +# set -- "${mongodHackedArgs[@]}" +_mongod_hack_ensure_arg_val() { + local ensureArg="$1"; shift + local ensureVal="$1"; shift + _mongod_hack_ensure_no_arg_val "$ensureArg" "$@" + mongodHackedArgs+=( "$ensureArg" "$ensureVal" ) +} + +# _js_escape 'some "string" value' +_js_escape() { + jq --null-input --arg 'str' "$1" '$str' +} + +: "${TMPDIR:=/tmp}" +jsonConfigFile="$TMPDIR/docker-entrypoint-config.json" +tempConfigFile="$TMPDIR/docker-entrypoint-temp-config.json" +_parse_config() { + if [ -s "$tempConfigFile" ]; then + return 0 + fi + + local configPath + if configPath="$(_mongod_hack_get_arg_val --config "$@")" && [ -s "$configPath" ]; then + # if --config is specified, parse it into a JSON file so we can remove a few problematic keys (especially SSL-related keys) + # see https://docs.mongodb.com/manual/reference/configuration-options/ + if grep -vEm1 '^[[:space:]]*(#|$)' "$configPath" | grep -qE '^[[:space:]]*[^=:]+[[:space:]]*='; then + # if the first non-comment/non-blank line of the config file looks like "foo = ...", this is probably the 2.4 and older "ini-style config format" + # mongod tries to parse config as yaml and then falls back to ini-style parsing + # https://github.com/mongodb/mongo/blob/r6.0.3/src/mongo/util/options_parser/options_parser.cpp#L1883-L1894 + echo >&2 + echo >&2 "WARNING: it appears that '$configPath' is in the older INI-style format (replaced by YAML in MongoDB 2.6)" + echo >&2 ' This script does not parse the older INI-style format, and thus will ignore it.' + echo >&2 + return 1 + fi + if [ "$mongoShell" = 'mongo' ]; then + "$mongoShell" --norc --nodb --quiet --eval "load('/js-yaml.js'); printjson(jsyaml.load(cat($(_js_escape "$configPath"))))" > "$jsonConfigFile" + else + # https://www.mongodb.com/docs/manual/reference/method/js-native/#std-label-native-in-mongosh + "$mongoShell" --norc --nodb --quiet --eval "load('/js-yaml.js'); JSON.stringify(jsyaml.load(fs.readFileSync($(_js_escape "$configPath"), 'utf8')))" > "$jsonConfigFile" + fi + if [ "$(head -c1 "$jsonConfigFile")" != '{' ] || [ "$(tail -c2 "$jsonConfigFile")" != '}' ]; then + # if the file doesn't start with "{" and end with "}", it's *probably* an error ("uncaught exception: YAMLException: foo" for example), so we should print it out + echo >&2 'error: unexpected "js-yaml.js" output while parsing config:' + cat >&2 "$jsonConfigFile" + exit 1 + fi + jq 'del(.systemLog, .processManagement, .net, .security, .replication)' "$jsonConfigFile" > "$tempConfigFile" + return 0 + fi + + return 1 +} +dbPath= +_dbPath() { + if [ -n "$dbPath" ]; then + echo "$dbPath" + return + fi + + if ! dbPath="$(_mongod_hack_get_arg_val --dbpath "$@")"; then + if _parse_config "$@"; then + dbPath="$(jq -r '.storage.dbPath // empty' "$jsonConfigFile")" + fi + fi + + if [ -z "$dbPath" ]; then + if _mongod_hack_have_arg --configsvr "$@" || { + _parse_config "$@" \ + && clusterRole="$(jq -r '.sharding.clusterRole // empty' "$jsonConfigFile")" \ + && [ "$clusterRole" = 'configsvr' ] + }; then + # if running as config server, then the default dbpath is /data/configdb + # https://docs.mongodb.com/manual/reference/program/mongod/#cmdoption-mongod-configsvr + dbPath=/data/configdb + fi + fi + + : "${dbPath:=/data/db}" + + echo "$dbPath" +} + +if [ "$originalArgOne" = 'mongod' ]; then + file_env 'MONGO_INITDB_ROOT_USERNAME' + file_env 'MONGO_INITDB_ROOT_PASSWORD' + + mongoShell='mongo' + if ! command -v "$mongoShell" > /dev/null; then + mongoShell='mongosh' + fi + + # pre-check a few factors to see if it's even worth bothering with initdb + shouldPerformInitdb= + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + # if we have a username/password, let's set "--auth" + _mongod_hack_ensure_arg '--auth' "$@" + set -- "${mongodHackedArgs[@]}" + shouldPerformInitdb='true' + elif [ "$MONGO_INITDB_ROOT_USERNAME" ] || [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + cat >&2 <<-'EOF' + + error: missing 'MONGO_INITDB_ROOT_USERNAME' or 'MONGO_INITDB_ROOT_PASSWORD' + both must be specified for a user to be created + + EOF + exit 1 + fi + + if [ -z "$shouldPerformInitdb" ]; then + # if we've got any /docker-entrypoint-initdb.d/* files to parse later, we should initdb + for f in /docker-entrypoint-initdb.d/*; do + case "$f" in + *.sh|*.js) # this should match the set of files we check for below + shouldPerformInitdb="$f" + break + ;; + esac + done + fi + + # check for a few known paths (to determine whether we've already initialized and should thus skip our initdb scripts) + if [ -n "$shouldPerformInitdb" ]; then + dbPath="$(_dbPath "$@")" + for path in \ + "$dbPath/WiredTiger" \ + "$dbPath/journal" \ + "$dbPath/local.0" \ + "$dbPath/storage.bson" \ + ; do + if [ -e "$path" ]; then + shouldPerformInitdb= + break + fi + done + fi + + if [ -n "$shouldPerformInitdb" ]; then + mongodHackedArgs=( "$@" ) + if _parse_config "$@"; then + _mongod_hack_ensure_arg_val --config "$tempConfigFile" "${mongodHackedArgs[@]}" + fi + _mongod_hack_ensure_arg_val --bind_ip 127.0.0.1 "${mongodHackedArgs[@]}" + _mongod_hack_ensure_arg_val --port 27017 "${mongodHackedArgs[@]}" + _mongod_hack_ensure_no_arg --bind_ip_all "${mongodHackedArgs[@]}" + + # remove "--auth" and "--replSet" for our initial startup (see https://docs.mongodb.com/manual/tutorial/enable-authentication/#start-mongodb-without-access-control) + # https://github.com/docker-library/mongo/issues/211 + _mongod_hack_ensure_no_arg --auth "${mongodHackedArgs[@]}" + # "keyFile implies security.authorization" + # https://docs.mongodb.com/manual/reference/configuration-options/#mongodb-setting-security.keyFile + _mongod_hack_ensure_no_arg_val --keyFile "${mongodHackedArgs[@]}" + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + _mongod_hack_ensure_no_arg_val --replSet "${mongodHackedArgs[@]}" + fi + + # "BadValue: need sslPEMKeyFile when SSL is enabled" vs "BadValue: need to enable SSL via the sslMode flag when using SSL configuration parameters" + tlsMode='disabled' + if _mongod_hack_have_arg '--tlsCertificateKeyFile' "$@"; then + tlsMode='allowTLS' + fi + _mongod_hack_ensure_arg_val --tlsMode "$tlsMode" "${mongodHackedArgs[@]}" + + if stat "/proc/$$/fd/1" > /dev/null && [ -w "/proc/$$/fd/1" ]; then + # https://github.com/mongodb/mongo/blob/38c0eb538d0fd390c6cb9ce9ae9894153f6e8ef5/src/mongo/db/initialize_server_global_state.cpp#L237-L251 + # https://github.com/docker-library/mongo/issues/164#issuecomment-293965668 + _mongod_hack_ensure_arg_val --logpath "/proc/$$/fd/1" "${mongodHackedArgs[@]}" + else + initdbLogPath="$(_dbPath "$@")/docker-initdb.log" + echo >&2 "warning: initdb logs cannot write to '/proc/$$/fd/1', so they are in '$initdbLogPath' instead" + _mongod_hack_ensure_arg_val --logpath "$initdbLogPath" "${mongodHackedArgs[@]}" + fi + _mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}" + + pidfile="$TMPDIR/docker-entrypoint-temp-mongod.pid" + rm -f "$pidfile" + _mongod_hack_ensure_arg_val --pidfilepath "$pidfile" "${mongodHackedArgs[@]}" + + "${mongodHackedArgs[@]}" --fork + + mongo=( "$mongoShell" --host 127.0.0.1 --port 27017 --quiet ) + + # check to see that our "mongod" actually did start up (catches "--help", "--version", slow prealloc, etc) + # https://jira.mongodb.org/browse/SERVER-16292 + tries=30 + while true; do + if ! { [ -s "$pidfile" ] && ps "$(< "$pidfile")" &> /dev/null; }; then + # bail ASAP if "mongod" isn't even running + echo >&2 + echo >&2 "error: $originalArgOne does not appear to have stayed running -- perhaps it had an error?" + echo >&2 + exit 1 + fi + if "${mongo[@]}" 'admin' --eval 'quit(0)' &> /dev/null; then + # success! + break + fi + (( tries-- )) + if [ "$tries" -le 0 ]; then + echo >&2 + echo >&2 "error: $originalArgOne does not appear to have accepted connections quickly enough -- perhaps it had an error?" + echo >&2 + exit 1 + fi + sleep 1 + done + + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + rootAuthDatabase='admin' + + "${mongo[@]}" "$rootAuthDatabase" <<-EOJS + db.createUser({ + user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"), + pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"), + roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ] + }) + EOJS + fi + + export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}" + + echo + for f in /docker-entrypoint-initdb.d/*; do + case "$f" in + *.sh) echo "$0: running $f"; . "$f" ;; + *.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done + + "${mongodHackedArgs[@]}" --shutdown + rm -f "$pidfile" + + echo + echo 'MongoDB init process complete; ready for start up.' + echo + fi + + # MongoDB defaults to localhost-only binding + haveBindIp= + if _mongod_hack_have_arg --bind_ip "$@" || _mongod_hack_have_arg --bind_ip_all "$@"; then + haveBindIp=1 + elif _parse_config "$@" && jq --exit-status '.net.bindIp // .net.bindIpAll' "$jsonConfigFile" > /dev/null; then + haveBindIp=1 + fi + if [ -z "$haveBindIp" ]; then + # so if no "--bind_ip" is specified, let's add "--bind_ip_all" + set -- "$@" --bind_ip_all + fi + + unset "${!MONGO_INITDB_@}" +fi + +rm -f "$jsonConfigFile" "$tempConfigFile" + +exec "$@" diff --git a/5.0/windows/nanoserver-ltsc2022/Dockerfile b/5.0/windows/nanoserver-ltsc2022/Dockerfile new file mode 100644 index 000000000..4111bb695 --- /dev/null +++ b/5.0/windows/nanoserver-ltsc2022/Dockerfile @@ -0,0 +1,34 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 + +SHELL ["cmd", "/S", "/C"] + +# PATH isn't actually set in the Docker image, so we have to set it from within the container +USER ContainerAdministrator +RUN setx /m PATH "C:\mongodb\bin;%PATH%" +USER ContainerUser +# doing this first to share cache across versions more aggressively + +COPY --from=mongo:5.0.32-windowsservercore-ltsc2022 \ + C:\\Windows\\System32\\msvcp140.dll \ + C:\\Windows\\System32\\msvcp140_1.dll \ + C:\\Windows\\System32\\vcruntime140.dll \ + C:\\Windows\\System32\\vcruntime140_1.dll \ + C:\\Windows\\System32\\ + +# https://docs.mongodb.org/master/release-notes/5.0/ +ENV MONGO_VERSION 5.0.32 +# 12/17/2025, https://github.com/mongodb/mongo/tree/ba92303e18e7ed4701572aa15acd161c97796f2f + +COPY --from=mongo:5.0.32-windowsservercore-ltsc2022 C:\\mongodb C:\\mongodb +RUN mongo --version && mongod --version + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/5.0/windows/windowsservercore-ltsc2022/Dockerfile b/5.0/windows/windowsservercore-ltsc2022/Dockerfile new file mode 100644 index 000000000..ab4c893a0 --- /dev/null +++ b/5.0/windows/windowsservercore-ltsc2022/Dockerfile @@ -0,0 +1,68 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/servercore:ltsc2022 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"] + +# https://docs.mongodb.org/master/release-notes/5.0/ +ENV MONGO_VERSION 5.0.32 +# 12/17/2025, https://github.com/mongodb/mongo/tree/ba92303e18e7ed4701572aa15acd161c97796f2f + +ENV MONGO_DOWNLOAD_URL https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.32-signed.msi +ENV MONGO_DOWNLOAD_SHA256=688b8e27d8614a44a8d5235fe3f63e1519c92ee0ce19fd8ad4af9ce39337e227 + +RUN Write-Host ('Downloading {0} ...' -f $env:MONGO_DOWNLOAD_URL); \ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + (New-Object System.Net.WebClient).DownloadFile($env:MONGO_DOWNLOAD_URL, 'mongo.msi'); \ + \ + if ($env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:MONGO_DOWNLOAD_SHA256); \ + if ((Get-FileHash mongo.msi -Algorithm sha256).Hash -ne $env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + }; \ + \ + Write-Host 'Installing ...'; \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#install-mongodb-community-edition + Start-Process msiexec -Wait \ + -ArgumentList @( \ + '/i', \ + 'mongo.msi', \ + '/quiet', \ + '/qn', \ + '/l*v', 'install.log', \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows-unattended/#run-the-windows-installer-from-the-windows-command-interpreter + 'INSTALLLOCATION=C:\mongodb', \ + 'ADDLOCAL=Client,MiscellaneousTools,Router,ServerNoService' \ + ); \ + if (-Not (Test-Path C:\mongodb\bin\mongod.exe -PathType Leaf)) { \ + Write-Host 'Installer failed!'; \ + Get-Content install.log; \ + exit 1; \ + }; \ + Remove-Item install.log; \ + \ + $env:PATH = 'C:\mongodb\bin;' + $env:PATH; \ + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Verifying install ...'; \ + Write-Host ' mongo --version'; mongo --version; \ + Write-Host ' mongod --version'; mongod --version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item C:\windows\installer\*.msi -Force; \ + Remove-Item mongo.msi -Force; \ + \ + Write-Host 'Complete.'; + +# TODO docker-entrypoint.ps1 ? (for "docker run --flag --flag --flag") + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/5.0/windows/windowsservercore-ltsc2025/Dockerfile b/5.0/windows/windowsservercore-ltsc2025/Dockerfile new file mode 100644 index 000000000..394f581b6 --- /dev/null +++ b/5.0/windows/windowsservercore-ltsc2025/Dockerfile @@ -0,0 +1,68 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM mcr.microsoft.com/windows/servercore:ltsc2025 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"] + +# https://docs.mongodb.org/master/release-notes/5.0/ +ENV MONGO_VERSION 5.0.32 +# 12/17/2025, https://github.com/mongodb/mongo/tree/ba92303e18e7ed4701572aa15acd161c97796f2f + +ENV MONGO_DOWNLOAD_URL https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.32-signed.msi +ENV MONGO_DOWNLOAD_SHA256=688b8e27d8614a44a8d5235fe3f63e1519c92ee0ce19fd8ad4af9ce39337e227 + +RUN Write-Host ('Downloading {0} ...' -f $env:MONGO_DOWNLOAD_URL); \ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + (New-Object System.Net.WebClient).DownloadFile($env:MONGO_DOWNLOAD_URL, 'mongo.msi'); \ + \ + if ($env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:MONGO_DOWNLOAD_SHA256); \ + if ((Get-FileHash mongo.msi -Algorithm sha256).Hash -ne $env:MONGO_DOWNLOAD_SHA256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + }; \ + \ + Write-Host 'Installing ...'; \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#install-mongodb-community-edition + Start-Process msiexec -Wait \ + -ArgumentList @( \ + '/i', \ + 'mongo.msi', \ + '/quiet', \ + '/qn', \ + '/l*v', 'install.log', \ +# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows-unattended/#run-the-windows-installer-from-the-windows-command-interpreter + 'INSTALLLOCATION=C:\mongodb', \ + 'ADDLOCAL=Client,MiscellaneousTools,Router,ServerNoService' \ + ); \ + if (-Not (Test-Path C:\mongodb\bin\mongod.exe -PathType Leaf)) { \ + Write-Host 'Installer failed!'; \ + Get-Content install.log; \ + exit 1; \ + }; \ + Remove-Item install.log; \ + \ + $env:PATH = 'C:\mongodb\bin;' + $env:PATH; \ + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Verifying install ...'; \ + Write-Host ' mongo --version'; mongo --version; \ + Write-Host ' mongod --version'; mongod --version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item C:\windows\installer\*.msi -Force; \ + Remove-Item mongo.msi -Force; \ + \ + Write-Host 'Complete.'; + +# TODO docker-entrypoint.ps1 ? (for "docker run --flag --flag --flag") + +VOLUME C:\\data\\db C:\\data\\configdb + +EXPOSE 27017 +CMD ["mongod", "--bind_ip_all"] diff --git a/generate-stackbrew-library.sh b/generate-stackbrew-library.sh index ee6f476ad..a84377eeb 100755 --- a/generate-stackbrew-library.sh +++ b/generate-stackbrew-library.sh @@ -48,6 +48,12 @@ getArches() { parentRepoToArchesStr="$( find -name 'Dockerfile' -exec awk -v officialImagesBase="$officialImagesBase" ' toupper($1) == "FROM" && $2 !~ /^('"$repo"'|scratch|.*\/.*)(:|$)/ { + if ($2 == "ubuntu:focal") { + # temporary hack for EOL releases (TODO remove me) + # 2d96d3b45936c5e7784c4f56ae58d87d96267a35 is the last commit that contained ubuntu:focal in DOI + printf "https://github.com/docker-library/official-images/raw/2d96d3b45936c5e7784c4f56ae58d87d96267a35/library/%s\n", $2 + next + } printf "%s%s\n", officialImagesBase, $2 } ' '{}' + \ diff --git a/versions.json b/versions.json index eba2c6c01..9db124cb1 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,116 @@ { + "4.4": { + "changes": "https://jira.mongodb.org/issues/?jql=project%20%3D%20SERVER%20AND%20fixVersion%20%3D%20%224.4.30%22%20ORDER%20BY%20status%20DESC%2C%20priority%20DESC", + "date": "12/18/2025", + "eol": null, + "githash": "4d7fa6a6260d25c5caa971dce10561690cb79dea", + "linux": "ubuntu2004", + "notes": "https://docs.mongodb.org/master/release-notes/4.4/", + "pgp": [ + { + "fingerprints": [ + "20691EEC35216C63CAF66CE1656408E390CFB1F5" + ], + "url": "https://pgp.mongodb.com/server-4.4.asc" + } + ], + "targets": { + "debian10": { + "arches": [ + "amd64" + ], + "image": "debian:buster-slim", + "suite": "buster" + }, + "ubuntu2004": { + "arches": [ + "amd64", + "arm64v8" + ], + "image": "ubuntu:focal", + "suite": "focal" + }, + "windows": { + "arches": [ + "amd64" + ], + "features": [ + "MiscellaneousTools", + "Router", + "ServerNoService" + ], + "msi": "https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-4.4.30-signed.msi", + "sha256": "c635b5ab758e4d37a248295009f6f12948125dcaec7303be276f2cce31170e46", + "variants": [ + "windowsservercore-ltsc2025", + "windowsservercore-ltsc2022", + "nanoserver-ltsc2022" + ] + } + }, + "version": "4.4.30" + }, + "4.4-rc": null, + "5.0": { + "changes": "https://jira.mongodb.org/issues/?jql=project%20%3D%20SERVER%20AND%20fixVersion%20%3D%20%225.0.32%22%20ORDER%20BY%20status%20DESC%2C%20priority%20DESC", + "date": "12/17/2025", + "eol": null, + "githash": "ba92303e18e7ed4701572aa15acd161c97796f2f", + "linux": "ubuntu2004", + "notes": "https://docs.mongodb.org/master/release-notes/5.0/", + "pgp": [ + { + "fingerprints": [ + "F5679A222C647C87527C2F8CB00A0BD1E2C63C11" + ], + "url": "https://pgp.mongodb.com/server-5.0.asc" + } + ], + "targets": { + "debian10": { + "arches": [ + "amd64" + ], + "image": "debian:buster-slim", + "suite": "buster" + }, + "debian11": { + "arches": [ + "amd64" + ], + "image": "debian:bullseye-slim", + "suite": "bullseye" + }, + "ubuntu2004": { + "arches": [ + "amd64", + "arm64v8" + ], + "image": "ubuntu:focal", + "suite": "focal" + }, + "windows": { + "arches": [ + "amd64" + ], + "features": [ + "Client", + "MiscellaneousTools", + "Router", + "ServerNoService" + ], + "msi": "https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.32-signed.msi", + "sha256": "688b8e27d8614a44a8d5235fe3f63e1519c92ee0ce19fd8ad4af9ce39337e227", + "variants": [ + "windowsservercore-ltsc2025", + "windowsservercore-ltsc2022", + "nanoserver-ltsc2022" + ] + } + }, + "version": "5.0.32" + }, + "5.0-rc": null, "6.0": { "changes": "https://jira.mongodb.org/issues/?jql=project%20%3D%20SERVER%20AND%20fixVersion%20%3D%20%226.0.27%22%20ORDER%20BY%20status%20DESC%2C%20priority%20DESC", "date": "12/18/2025", diff --git a/versions.sh b/versions.sh index 18f353502..beb257965 100755 --- a/versions.sh +++ b/versions.sh @@ -52,9 +52,10 @@ shell="$( "8.0": "2029-10-31", "7.0": "2027-08-31", + # TODO comment these back out after one build for CVE-2025-14847 ("MongoBleed"; https://jira.mongodb.org/browse/SERVER-115508) #"6.0": "2025-07-31", - "5.0": "2024-10-31", - "4.4": "2024-02-29", + #"5.0": "2024-10-31", + #"4.4": "2024-02-29", # "Rapid Releases" and "Minor Releases" "8.2": "2026-03-30", @@ -144,7 +145,10 @@ for version in "${versions[@]}"; do $pgp.dev else empty end, - $pgp[$rcVersion | sub("[.][0-9]+$"; ".0")], # normalizing 8.x to 8.0 because "Rapid Releases" use the key of the most recent major + ( + $pgp[$rcVersion] # prefer an exact match (4.4 resurrection for CVE-2025-14847 "MongoBleed") + // $pgp[$rcVersion | sub("[.][0-9]+$"; ".0")] # normalizing 8.x to 8.0 because "Rapid Releases" use the key of the most recent major + ), empty ],