diff --git a/build-all-multiplatform.sh b/build-all-multiplatform.sh index 6cf46b9e..f8768a72 100755 --- a/build-all-multiplatform.sh +++ b/build-all-multiplatform.sh @@ -9,7 +9,7 @@ fi COMPONENTS=$* if [ -z "$COMPONENTS" ]; then - COMPONENTS="postgres debezium" + COMPONENTS="postgres debezium mongodb" fi; if [ -z "$MULTIPLATFORM_PLATFORMS" ]; then @@ -31,6 +31,8 @@ DEBEZIUM_SINGLEPLATFORM_VERSIONS="1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8" POSTGRES_VERSIONS="14" POSTGRES_MULTIPLATFORM_VERSIONS="15 16 17 18 14-alpine 15-alpine 16-alpine 17-alpine 18-alpine" +MONGODB_VERSIONS="6.0-6.0" +MONGODB_MULTIPLATFORM_VERSIONS="6.0-6.0 7.0-7.0 8.0-8.0" docker buildx prune -f || true if shouldBuild "postgres"; then @@ -52,3 +54,17 @@ if shouldBuild "debezium"; then fi; done fi; + +if shouldBuild "mongodb"; then + for MONGODB_VERSION in $MONGODB_MULTIPLATFORM_VERSIONS; do + RELEASE_VERSION="${MONGODB_VERSION%-*}" + BASE_VERSION="${MONGODB_VERSION#*-}" + ./build-mongodb-multiplatform.sh "$RELEASE_VERSION" "$BASE_VERSION" "${MULTIPLATFORM_PLATFORMS}" + done + + for MONGODB_VERSION in $MONGODB_VERSIONS; do + RELEASE_VERSION="${MONGODB_VERSION%-*}" + BASE_VERSION="${MONGODB_VERSION#*-}" + ./build-mongodb-multiplatform.sh "$RELEASE_VERSION" "$BASE_VERSION" "linux/amd64" + done +fi; diff --git a/build-mongodb-multiplatform.sh b/build-mongodb-multiplatform.sh new file mode 100755 index 00000000..f73ffd7f --- /dev/null +++ b/build-mongodb-multiplatform.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -eo pipefail + +function usage() { + MSG=$1 + + echo "" + echo "$MSG" + echo "" + echo "Usage: build-mongodb-multiplatform "; + echo "" + echo " Where platform can be for example:" + echo " linux/amd64" + echo " linux/amd64,linux/arm64" + echo " linux/arm64" + echo "" + exit 1; +} + +if [[ -z "$1" ]]; then + usage "A release version must be specified." +fi + +if [[ -z "$2" ]]; then + usage "A base version must be specified." +fi + +if [[ -z "$3" ]]; then + usage "Platform must be specified." +fi + +PLATFORM=$3 + +if [ -z "${DEBEZIUM_DOCKER_REGISTRY_PRIMARY_NAME}" ]; then + DEBEZIUM_DOCKER_REGISTRY_PRIMARY_NAME=quay.io/debezium +fi; + +echo "" +echo "****************************************************************" +echo "** Building ${DEBEZIUM_DOCKER_REGISTRY_PRIMARY_NAME}/mongodb:$1 based on mongodb version $2 for $PLATFORM" +echo "****************************************************************" +TAGS+=("-t ${DEBEZIUM_DOCKER_REGISTRY_PRIMARY_NAME}/mongodb:$1") +if [ -n "${DEBEZIUM_DOCKER_REGISTRY_SECONDARY_NAME}" ]; then + TAGS+=("-t ${DEBEZIUM_DOCKER_REGISTRY_SECONDARY_NAME}/mongodb:$1") +fi; + +PUSH_FLAG="--push" + if [[ "$DRY_RUN" == "true" ]]; then + PUSH_FLAG="" + fi + +echo "****************************************************************" +echo "Running docker buildx build $PUSH_FLAG --platform \"${PLATFORM}\" \ + --progress=plain \ + --build-arg IMAGE_TAG=\"$2\" \ + ${TAGS[*]} \ + \"mongodb/$1\"" +echo "****************************************************************" + +# shellcheck disable=SC2068 +docker buildx build $PUSH_FLAG --platform "${PLATFORM}" \ + --build-arg IMAGE_TAG="$2" \ + ${TAGS[@]} \ + "mongodb/$1" \ No newline at end of file diff --git a/mongodb/6.0/Dockerfile b/mongodb/6.0/Dockerfile new file mode 100644 index 00000000..1155192d --- /dev/null +++ b/mongodb/6.0/Dockerfile @@ -0,0 +1,17 @@ +ARG IMAGE_TAG=6.0 +FROM mirror.gcr.io/library/mongo:$IMAGE_TAG + +LABEL maintainer="Debezium Community" + +RUN openssl rand -base64 756 > /etc/mongodb.keyfile &&\ + chown mongodb /etc/mongodb.keyfile &&\ + chmod 400 /etc/mongodb.keyfile + +# Copy custom entrypoint script +COPY --chmod=+x mongodb-debezium-entrypoint.sh /usr/local/bin/mongodb-debezium-entrypoint.sh + +# Switch to non-root user +USER mongodb + +# Override the default entrypoint +ENTRYPOINT ["/usr/local/bin/mongodb-debezium-entrypoint.sh"] \ No newline at end of file diff --git a/mongodb/6.0/README.md b/mongodb/6.0/README.md new file mode 100644 index 00000000..4fb5c64d --- /dev/null +++ b/mongodb/6.0/README.md @@ -0,0 +1,81 @@ +# Debezium MongoDB 6.0 + +MongoDB image pre-configured with replica set support for Debezium change data capture. + +## Why This Image? + +Standard MongoDB images require manual replica set initialization. This image automatically configures a single-node replica set with authentication, which is required for Debezium CDC to work. The mongodb instance is reachable to host machine or in a shared network. + +## Key Features + +- **Auto-initialized replica set**: Single-node replica set configured on first start +- **Authentication enabled**: Root user created automatically +- **Keyfile authentication**: Pre-generated keyfile for replica set internal auth +- **Shard server mode**: Configured with `--shardsvr` flag +- **Init script support**: Executes `.sh` and `.js` files from `/docker-entrypoint-initdb.d/` +- **Persistent initialization**: Uses marker file to skip re-initialization on restart + +## Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MONGO_INITDB_ROOT_USERNAME` | `admin` | Root user username | +| `MONGO_INITDB_ROOT_PASSWORD` | `admin` | Root user password | +| `MONGO_INITDB_DATABASE` | `admin` | Initial database | +| `RS_NAME` | `rs0` | Replica set name | +| `HOSTNAME` | Container hostname | Replica set member hostname (use `host:port` for external access) | +| `RETRIES` | `30` | Startup connection retries | + +## Quick Start + +### Basic Usage (Docker Network) + +```bash +docker run -d \ + --name mongodb \ + -p 27017:27017 \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:6.0 +``` + +### Port-Forwarding + +```yaml +version: '3' +services: + mongodb: + image: quay.io/debezium/mongodb:6.0 + hostname: mongodb + ports: + - "27017:27017" + environment: + - MONGO_INITDB_ROOT_USERNAME=admin + - MONGO_INITDB_ROOT_PASSWORD=admin + - HOSTNAME=127.0.0.1 +``` +### Data Persistence + +Mount a volume to persist data: + +```bash +docker run -d \ + -v mongodb-data:/data/db \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:6.0 +``` + +### Custom Initialization Scripts + +Place scripts in `/docker-entrypoint-initdb.d/`: + +```bash +docker run -d \ + -v ./init-scripts:/docker-entrypoint-initdb.d \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:6.0 +``` + +Scripts are executed only on first initialization, after replica set is configured. \ No newline at end of file diff --git a/mongodb/6.0/mongodb-debezium-entrypoint.sh b/mongodb/6.0/mongodb-debezium-entrypoint.sh new file mode 100644 index 00000000..d014ff5f --- /dev/null +++ b/mongodb/6.0/mongodb-debezium-entrypoint.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env sh + +set -ex + +PIDFILE="/tmp/mongod.pid" +INIT_DIR="/docker-entrypoint-initdb.d" +METADATA_DIR="/data/db/.metadata" +REPLICA_FILE="$METADATA_DIR/.replicaset" +LOG_PATH="/tmp/mongod.log" +DB_PATH="/data/db" +PORT=27017 + +# Default values +: "${MONGO_INITDB_DATABASE:=admin}" +: "${RS_NAME:=rs0}" +: "${HOSTNAME:=$(hostname)}" +: "${MONGODB_KEYFILE:=/etc/mongodb.keyfile}" +: "${MONGO_INITDB_ROOT_USERNAME:=admin}" +: "${MONGO_INITDB_ROOT_PASSWORD:=admin}" +: "${RETRIES:=30}" + + +if command -v mongosh >/dev/null 2>&1; then + MONGO_SHELL="mongosh" +elif command -v mongo >/dev/null 2>&1; then + MONGO_SHELL="mongo" +else + echo "No MongoDB shell found (mongosh or mongo). Exiting." + exit 127 +fi + + +if [ ! -f "$REPLICA_FILE" ]; then + echo "=> Starting MongoDB without auth for initialization..." + mongod --fork --dbpath "$DB_PATH" --port "$PORT" --logpath "$LOG_PATH" --pidfilepath "$PIDFILE" + + echo "=> Waiting for MongoDB to start..." + + while true; do + if ! { [ -s "$PIDFILE" ] && ps "$(cat "$PIDFILE")" > /dev/null 2>&1; }; then + echo "ERROR: mongod process did not stay running. Check logs for errors." + exit 1 + fi + + if $MONGO_SHELL --host 127.0.0.1 --port "$PORT" --quiet "$MONGO_INITDB_DATABASE" --eval 'quit(0)' > /dev/null 2>&1; then + break + fi + + RETRIES=$((RETRIES - 1)) + if [ "$RETRIES" -le 0 ]; then + echo "ERROR: mongod did not accept connections quickly enough. Check logs for errors." + exit 1 + fi + + sleep 1 + done + + echo "=> Creating root user..." + $MONGO_SHELL admin --eval "db.createUser({user:'$MONGO_INITDB_ROOT_USERNAME',pwd:'$MONGO_INITDB_ROOT_PASSWORD',roles:[{role:'root',db:'admin'}]})" + + echo "=> Shutting down temporary MongoDB..." + mongod --shutdown + + echo "=> Starting MongoDB with replica set and auth..." + mongod --fork --logpath "$LOG_PATH" --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --shardsvr --dbpath "$DB_PATH" --port "$PORT" + + echo "=> Initiating replica set..." + CONFIG="{_id:\"$RS_NAME\",version:1,members:[{_id:0,host:\"$HOSTNAME:$PORT\"}]}" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin --eval "printjson(rs.initiate($CONFIG))" + + echo "=> Running initialization scripts from $INIT_DIR..." + if [ -d "$INIT_DIR" ]; then + for f in "$INIT_DIR"/*; do + case "$f" in + *.sh) + echo "=> Executing shell script: $f" + . "$f" + ;; + *.js) + echo "=> Executing MongoDB script: $f" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin "$MONGO_INITDB_DATABASE" "$f" + ;; + *) + echo "=> Ignoring file: $f" + ;; + esac + done + fi + + echo "=> Finalizing setup..." + mkdir -p "$METADATA_DIR" + touch "$REPLICA_FILE" + mongod --shutdown + + echo "=> Starting MongoDB normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +else + echo "=> MongoDB already initialized, starting normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +fi \ No newline at end of file diff --git a/mongodb/7.0/Dockerfile b/mongodb/7.0/Dockerfile new file mode 100644 index 00000000..5e50a83d --- /dev/null +++ b/mongodb/7.0/Dockerfile @@ -0,0 +1,17 @@ +ARG IMAGE_TAG=7.0 +FROM mirror.gcr.io/library/mongo:$IMAGE_TAG + +LABEL maintainer="Debezium Community" + +RUN openssl rand -base64 756 > /etc/mongodb.keyfile &&\ + chown mongodb /etc/mongodb.keyfile &&\ + chmod 400 /etc/mongodb.keyfile + +# Copy custom entrypoint script +COPY --chmod=+x mongodb-debezium-entrypoint.sh /usr/local/bin/mongodb-debezium-entrypoint.sh + +# Switch to non-root user +USER mongodb + +# Override the default entrypoint +ENTRYPOINT ["/usr/local/bin/mongodb-debezium-entrypoint.sh"] \ No newline at end of file diff --git a/mongodb/7.0/README.md b/mongodb/7.0/README.md new file mode 100644 index 00000000..bcf9e0a3 --- /dev/null +++ b/mongodb/7.0/README.md @@ -0,0 +1,81 @@ +# Debezium MongoDB 7.0 + +MongoDB image pre-configured with replica set support for Debezium change data capture. + +## Why This Image? + +Standard MongoDB images require manual replica set initialization. This image automatically configures a single-node replica set with authentication, which is required for Debezium CDC to work. The mongodb instance is reachable to host machine or in a shared network. + +## Key Features + +- **Auto-initialized replica set**: Single-node replica set configured on first start +- **Authentication enabled**: Root user created automatically +- **Keyfile authentication**: Pre-generated keyfile for replica set internal auth +- **Shard server mode**: Configured with `--shardsvr` flag +- **Init script support**: Executes `.sh` and `.js` files from `/docker-entrypoint-initdb.d/` +- **Persistent initialization**: Uses marker file to skip re-initialization on restart + +## Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MONGO_INITDB_ROOT_USERNAME` | `admin` | Root user username | +| `MONGO_INITDB_ROOT_PASSWORD` | `admin` | Root user password | +| `MONGO_INITDB_DATABASE` | `admin` | Initial database | +| `RS_NAME` | `rs0` | Replica set name | +| `HOSTNAME` | Container hostname | Replica set member hostname (use `host:port` for external access) | +| `RETRIES` | `30` | Startup connection retries | + +## Quick Start + +### Basic Usage (Docker Network) + +```bash +docker run -d \ + --name mongodb \ + -p 27017:27017 \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:7.0 +``` + +### Port-Forwarding + +```yaml +version: '3' +services: + mongodb: + image: quay.io/debezium/mongodb:7.0 + hostname: mongodb + ports: + - "27017:27017" + environment: + - MONGO_INITDB_ROOT_USERNAME=admin + - MONGO_INITDB_ROOT_PASSWORD=admin + - HOSTNAME=127.0.0.1 +``` +### Data Persistence + +Mount a volume to persist data: + +```bash +docker run -d \ + -v mongodb-data:/data/db \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:7.0 +``` + +### Custom Initialization Scripts + +Place scripts in `/docker-entrypoint-initdb.d/`: + +```bash +docker run -d \ + -v ./init-scripts:/docker-entrypoint-initdb.d \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:7.0 +``` + +Scripts are executed only on first initialization, after replica set is configured. \ No newline at end of file diff --git a/mongodb/7.0/mongodb-debezium-entrypoint.sh b/mongodb/7.0/mongodb-debezium-entrypoint.sh new file mode 100644 index 00000000..d014ff5f --- /dev/null +++ b/mongodb/7.0/mongodb-debezium-entrypoint.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env sh + +set -ex + +PIDFILE="/tmp/mongod.pid" +INIT_DIR="/docker-entrypoint-initdb.d" +METADATA_DIR="/data/db/.metadata" +REPLICA_FILE="$METADATA_DIR/.replicaset" +LOG_PATH="/tmp/mongod.log" +DB_PATH="/data/db" +PORT=27017 + +# Default values +: "${MONGO_INITDB_DATABASE:=admin}" +: "${RS_NAME:=rs0}" +: "${HOSTNAME:=$(hostname)}" +: "${MONGODB_KEYFILE:=/etc/mongodb.keyfile}" +: "${MONGO_INITDB_ROOT_USERNAME:=admin}" +: "${MONGO_INITDB_ROOT_PASSWORD:=admin}" +: "${RETRIES:=30}" + + +if command -v mongosh >/dev/null 2>&1; then + MONGO_SHELL="mongosh" +elif command -v mongo >/dev/null 2>&1; then + MONGO_SHELL="mongo" +else + echo "No MongoDB shell found (mongosh or mongo). Exiting." + exit 127 +fi + + +if [ ! -f "$REPLICA_FILE" ]; then + echo "=> Starting MongoDB without auth for initialization..." + mongod --fork --dbpath "$DB_PATH" --port "$PORT" --logpath "$LOG_PATH" --pidfilepath "$PIDFILE" + + echo "=> Waiting for MongoDB to start..." + + while true; do + if ! { [ -s "$PIDFILE" ] && ps "$(cat "$PIDFILE")" > /dev/null 2>&1; }; then + echo "ERROR: mongod process did not stay running. Check logs for errors." + exit 1 + fi + + if $MONGO_SHELL --host 127.0.0.1 --port "$PORT" --quiet "$MONGO_INITDB_DATABASE" --eval 'quit(0)' > /dev/null 2>&1; then + break + fi + + RETRIES=$((RETRIES - 1)) + if [ "$RETRIES" -le 0 ]; then + echo "ERROR: mongod did not accept connections quickly enough. Check logs for errors." + exit 1 + fi + + sleep 1 + done + + echo "=> Creating root user..." + $MONGO_SHELL admin --eval "db.createUser({user:'$MONGO_INITDB_ROOT_USERNAME',pwd:'$MONGO_INITDB_ROOT_PASSWORD',roles:[{role:'root',db:'admin'}]})" + + echo "=> Shutting down temporary MongoDB..." + mongod --shutdown + + echo "=> Starting MongoDB with replica set and auth..." + mongod --fork --logpath "$LOG_PATH" --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --shardsvr --dbpath "$DB_PATH" --port "$PORT" + + echo "=> Initiating replica set..." + CONFIG="{_id:\"$RS_NAME\",version:1,members:[{_id:0,host:\"$HOSTNAME:$PORT\"}]}" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin --eval "printjson(rs.initiate($CONFIG))" + + echo "=> Running initialization scripts from $INIT_DIR..." + if [ -d "$INIT_DIR" ]; then + for f in "$INIT_DIR"/*; do + case "$f" in + *.sh) + echo "=> Executing shell script: $f" + . "$f" + ;; + *.js) + echo "=> Executing MongoDB script: $f" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin "$MONGO_INITDB_DATABASE" "$f" + ;; + *) + echo "=> Ignoring file: $f" + ;; + esac + done + fi + + echo "=> Finalizing setup..." + mkdir -p "$METADATA_DIR" + touch "$REPLICA_FILE" + mongod --shutdown + + echo "=> Starting MongoDB normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +else + echo "=> MongoDB already initialized, starting normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +fi \ No newline at end of file diff --git a/mongodb/8.0/Dockerfile b/mongodb/8.0/Dockerfile new file mode 100644 index 00000000..01e8e117 --- /dev/null +++ b/mongodb/8.0/Dockerfile @@ -0,0 +1,17 @@ +ARG IMAGE_TAG=8.0 +FROM mirror.gcr.io/library/mongo:$IMAGE_TAG + +LABEL maintainer="Debezium Community" + +RUN openssl rand -base64 756 > /etc/mongodb.keyfile &&\ + chown mongodb /etc/mongodb.keyfile &&\ + chmod 400 /etc/mongodb.keyfile + +# Copy custom entrypoint script +COPY --chmod=+x mongodb-debezium-entrypoint.sh /usr/local/bin/mongodb-debezium-entrypoint.sh + +# Switch to non-root user +USER mongodb + +# Override the default entrypoint +ENTRYPOINT ["/usr/local/bin/mongodb-debezium-entrypoint.sh"] \ No newline at end of file diff --git a/mongodb/8.0/README.md b/mongodb/8.0/README.md new file mode 100644 index 00000000..460ab9d2 --- /dev/null +++ b/mongodb/8.0/README.md @@ -0,0 +1,81 @@ +# Debezium MongoDB 8.0 + +MongoDB image pre-configured with replica set support for Debezium change data capture. + +## Why This Image? + +Standard MongoDB images require manual replica set initialization. This image automatically configures a single-node replica set with authentication, which is required for Debezium CDC to work. The mongodb instance is reachable to host machine or in a shared network. + +## Key Features + +- **Auto-initialized replica set**: Single-node replica set configured on first start +- **Authentication enabled**: Root user created automatically +- **Keyfile authentication**: Pre-generated keyfile for replica set internal auth +- **Shard server mode**: Configured with `--shardsvr` flag +- **Init script support**: Executes `.sh` and `.js` files from `/docker-entrypoint-initdb.d/` +- **Persistent initialization**: Uses marker file to skip re-initialization on restart + +## Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MONGO_INITDB_ROOT_USERNAME` | `admin` | Root user username | +| `MONGO_INITDB_ROOT_PASSWORD` | `admin` | Root user password | +| `MONGO_INITDB_DATABASE` | `admin` | Initial database | +| `RS_NAME` | `rs0` | Replica set name | +| `HOSTNAME` | Container hostname | Replica set member hostname (use `host:port` for external access) | +| `RETRIES` | `30` | Startup connection retries | + +## Quick Start + +### Basic Usage (Docker Network) + +```bash +docker run -d \ + --name mongodb \ + -p 27017:27017 \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:8.0 +``` + +### Port-Forwarding + +```yaml +version: '3' +services: + mongodb: + image: quay.io/debezium/mongodb:8.0 + hostname: mongodb + ports: + - "27017:27017" + environment: + - MONGO_INITDB_ROOT_USERNAME=admin + - MONGO_INITDB_ROOT_PASSWORD=admin + - HOSTNAME=127.0.0.1 +``` +### Data Persistence + +Mount a volume to persist data: + +```bash +docker run -d \ + -v mongodb-data:/data/db \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:8.0 +``` + +### Custom Initialization Scripts + +Place scripts in `/docker-entrypoint-initdb.d/`: + +```bash +docker run -d \ + -v ./init-scripts:/docker-entrypoint-initdb.d \ + -e MONGO_INITDB_ROOT_USERNAME=admin \ + -e MONGO_INITDB_ROOT_PASSWORD=admin \ + quay.io/debezium/mongodb:8.0 +``` + +Scripts are executed only on first initialization, after replica set is configured. \ No newline at end of file diff --git a/mongodb/8.0/mongodb-debezium-entrypoint.sh b/mongodb/8.0/mongodb-debezium-entrypoint.sh new file mode 100644 index 00000000..d014ff5f --- /dev/null +++ b/mongodb/8.0/mongodb-debezium-entrypoint.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env sh + +set -ex + +PIDFILE="/tmp/mongod.pid" +INIT_DIR="/docker-entrypoint-initdb.d" +METADATA_DIR="/data/db/.metadata" +REPLICA_FILE="$METADATA_DIR/.replicaset" +LOG_PATH="/tmp/mongod.log" +DB_PATH="/data/db" +PORT=27017 + +# Default values +: "${MONGO_INITDB_DATABASE:=admin}" +: "${RS_NAME:=rs0}" +: "${HOSTNAME:=$(hostname)}" +: "${MONGODB_KEYFILE:=/etc/mongodb.keyfile}" +: "${MONGO_INITDB_ROOT_USERNAME:=admin}" +: "${MONGO_INITDB_ROOT_PASSWORD:=admin}" +: "${RETRIES:=30}" + + +if command -v mongosh >/dev/null 2>&1; then + MONGO_SHELL="mongosh" +elif command -v mongo >/dev/null 2>&1; then + MONGO_SHELL="mongo" +else + echo "No MongoDB shell found (mongosh or mongo). Exiting." + exit 127 +fi + + +if [ ! -f "$REPLICA_FILE" ]; then + echo "=> Starting MongoDB without auth for initialization..." + mongod --fork --dbpath "$DB_PATH" --port "$PORT" --logpath "$LOG_PATH" --pidfilepath "$PIDFILE" + + echo "=> Waiting for MongoDB to start..." + + while true; do + if ! { [ -s "$PIDFILE" ] && ps "$(cat "$PIDFILE")" > /dev/null 2>&1; }; then + echo "ERROR: mongod process did not stay running. Check logs for errors." + exit 1 + fi + + if $MONGO_SHELL --host 127.0.0.1 --port "$PORT" --quiet "$MONGO_INITDB_DATABASE" --eval 'quit(0)' > /dev/null 2>&1; then + break + fi + + RETRIES=$((RETRIES - 1)) + if [ "$RETRIES" -le 0 ]; then + echo "ERROR: mongod did not accept connections quickly enough. Check logs for errors." + exit 1 + fi + + sleep 1 + done + + echo "=> Creating root user..." + $MONGO_SHELL admin --eval "db.createUser({user:'$MONGO_INITDB_ROOT_USERNAME',pwd:'$MONGO_INITDB_ROOT_PASSWORD',roles:[{role:'root',db:'admin'}]})" + + echo "=> Shutting down temporary MongoDB..." + mongod --shutdown + + echo "=> Starting MongoDB with replica set and auth..." + mongod --fork --logpath "$LOG_PATH" --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --shardsvr --dbpath "$DB_PATH" --port "$PORT" + + echo "=> Initiating replica set..." + CONFIG="{_id:\"$RS_NAME\",version:1,members:[{_id:0,host:\"$HOSTNAME:$PORT\"}]}" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin --eval "printjson(rs.initiate($CONFIG))" + + echo "=> Running initialization scripts from $INIT_DIR..." + if [ -d "$INIT_DIR" ]; then + for f in "$INIT_DIR"/*; do + case "$f" in + *.sh) + echo "=> Executing shell script: $f" + . "$f" + ;; + *.js) + echo "=> Executing MongoDB script: $f" + $MONGO_SHELL -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" --authenticationDatabase admin "$MONGO_INITDB_DATABASE" "$f" + ;; + *) + echo "=> Ignoring file: $f" + ;; + esac + done + fi + + echo "=> Finalizing setup..." + mkdir -p "$METADATA_DIR" + touch "$REPLICA_FILE" + mongod --shutdown + + echo "=> Starting MongoDB normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +else + echo "=> MongoDB already initialized, starting normally..." + exec mongod --auth --keyFile "$MONGODB_KEYFILE" --replSet "$RS_NAME" --dbpath "$DB_PATH" --port "$PORT" --bind_ip_all +fi \ No newline at end of file