diff --git a/build/build.sh b/build/build.sh new file mode 100755 index 0000000..30699e9 --- /dev/null +++ b/build/build.sh @@ -0,0 +1,7 @@ +sudo docker build -t mongodb -f src/Dockerfile . + +echo "" +echo "run" +echo "docker tag registry.vlabs.uniwa.gr:5043/:" +echo "" +echo "docker push registry.vlabs.uniwa.gr:5043/:" diff --git a/build/opensslkey.sh b/build/opensslkey.sh new file mode 100644 index 0000000..4b630a6 --- /dev/null +++ b/build/opensslkey.sh @@ -0,0 +1,2 @@ +openssl rand -base64 756 > mongo.key +chmod 400 mongo.key diff --git a/build/src/Dockerfile b/build/src/Dockerfile new file mode 100644 index 0000000..641d134 --- /dev/null +++ b/build/src/Dockerfile @@ -0,0 +1,107 @@ +FROM ubuntu:xenial + +# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added +RUN groupadd -r mongodb && useradd -r -g mongodb mongodb + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + jq \ + numactl \ + ; \ + if ! command -v ps > /dev/null; then \ + apt-get install -y --no-install-recommends procps; \ + fi; \ + rm -rf /var/lib/apt/lists/* + +# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases) +ENV GOSU_VERSION 1.11 +# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases) +ENV JSYAML_VERSION 3.13.0 + +RUN set -ex; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + wget \ + ; \ + if ! command -v gpg > /dev/null; then \ + apt-get install -y --no-install-recommends gnupg dirmngr; \ + savedAptMark="$savedAptMark gnupg dirmngr"; \ + elif gpg --version | grep -q '^gpg (GnuPG) 1\.'; then \ +# "This package provides support for HKPS keyservers." (GnuPG 1.x only) + apt-get install -y --no-install-recommends gnupg-curl; \ + fi; \ + rm -rf /var/lib/apt/lists/*; \ + \ + 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; \ + command -v gpgconf && gpgconf --kill all || :; \ + rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc; \ + chmod +x /usr/local/bin/gosu; \ + gosu --version; \ + gosu nobody true; \ + \ + wget -O /js-yaml.js "https://github.com/nodeca/js-yaml/raw/${JSYAML_VERSION}/dist/js-yaml.js"; \ +# TODO some sort of download verification here + \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false + +RUN mkdir /docker-entrypoint-initdb.d + +ENV GPG_KEYS 9DA31620334BD75D9DCB49F368818C72E52529D4 +RUN set -ex; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ + done; \ + gpg --batch --export $GPG_KEYS > /etc/apt/trusted.gpg.d/mongodb.gpg; \ + command -v gpgconf && gpgconf --kill all || :; \ + rm -r "$GNUPGHOME"; \ + apt-key list + +# 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.0 +ENV MONGO_VERSION 4.0.10 +# bashbrew-architectures:amd64 arm64v8 +RUN echo "deb http://$MONGO_REPO/apt/ubuntu xenial/${MONGO_PACKAGE%-unstable}/$MONGO_MAJOR multiverse" | tee "/etc/apt/sources.list.d/${MONGO_PACKAGE%-unstable}.list" + +RUN set -x \ + && 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 + +RUN mkdir -p /data/db /data/configdb \ + && chown -R mongodb:mongodb /data/db /data/configdb +VOLUME /data/db /data/configdb +RUN chown -R mongodb.mongodb /data/db + +ADD ./src/mongodb.conf /etc/mongodb.conf +ADD ./src/docker-entrypoint.sh /usr/local/bin/ + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +EXPOSE 27017 +CMD ["mongod"] diff --git a/build/src/Dockerfile.my b/build/src/Dockerfile.my new file mode 100644 index 0000000..647bf8b --- /dev/null +++ b/build/src/Dockerfile.my @@ -0,0 +1,22 @@ +FROM ubuntu:16.04 +# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added +RUN groupadd -r mongodb && useradd -r -g mongodb -u 999 mongodb +RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 +RUN echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list + +RUN apt-get update && apt-get install -y --no-install-recommends mongodb-org +RUN mkdir -p /data/db +RUN chown -R mongodb:mongodb /data/db +ADD ./src/mongodb.conf /etc/mongodb.conf + +RUN set -x \ + && apt-get autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/lib/mongodb + +VOLUME ["/data/db"] +COPY src/docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["docker-entrypoint.sh"] +EXPOSE 27017 +CMD ["/usr/bin/mongod", "--config", "/etc/mongodb.conf"] diff --git a/build/src/docker-entrypoint.sh b/build/src/docker-entrypoint.sh new file mode 100755 index 0000000..ce5f0e9 --- /dev/null +++ b/build/src/docker-entrypoint.sh @@ -0,0 +1,354 @@ +#!/bin/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 /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 + +# 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' +} + +jsonConfigFile="${TMPDIR:-/tmp}/docker-entrypoint-config.json" +tempConfigFile="${TMPDIR:-/tmp}/docker-entrypoint-temp-config.json" +_parse_config() { + if [ -s "$tempConfigFile" ]; then + return 0 + fi + + local configPath + if configPath="$(_mongod_hack_get_arg_val --config "$@")"; 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/ + mongo --norc --nodb --quiet --eval "load('/js-yaml.js'); printjson(jsyaml.load(cat($(_js_escape "$configPath"))))" > "$jsonConfigFile" + jq 'del(.systemLog, .processManagement, .net, .security)' "$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' + # 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[@]}" + if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then + _mongod_hack_ensure_no_arg_val --replSet "${mongodHackedArgs[@]}" + fi + + sslMode="$(_mongod_hack_have_arg '--sslPEMKeyFile' "$@" && echo 'allowSSL' || echo 'disabled')" # "BadValue: need sslPEMKeyFile when SSL is enabled" vs "BadValue: need to enable SSL via the sslMode flag when using SSL configuration parameters" + _mongod_hack_ensure_arg_val --sslMode "$sslMode" "${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:-/tmp}/docker-entrypoint-temp-mongod.pid" + rm -f "$pidfile" + _mongod_hack_ensure_arg_val --pidfilepath "$pidfile" "${mongodHackedArgs[@]}" + + "${mongodHackedArgs[@]}" --fork + + mongo=( mongo --host 127.0.0.1 --port 27017 --quiet ) + + # check to see that our "mongod" actually did start up (catches "--help", "--version", MongoDB 3.2 being silly, 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 3.6+ defaults to localhost-only binding + if mongod --help 2>&1 | grep -q -- --bind_ip_all; then # TODO remove this conditional when 3.4 is no longer supported + 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 + fi + + unset "${!MONGO_INITDB_@}" +fi + +rm -f "$jsonConfigFile" "$tempConfigFile" + +exec "$@" diff --git a/build/src/mongodb.conf b/build/src/mongodb.conf new file mode 100644 index 0000000..f1e22f0 --- /dev/null +++ b/build/src/mongodb.conf @@ -0,0 +1,18 @@ +systemLog: + destination: file + path: "/var/log/mongodb/mongod.log" + logAppend: true +storage: + dbPath: "/data/db" + journal: + enabled: true +net: + port: 27017 + #bindIp: mongo_node1 +replication: + replSetName: replica01 +setParameter: + enableLocalhostAuthBypass: false +security: + authorization: enabled + keyFile: "/data/mongo.key" diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..f087e6c --- /dev/null +++ b/deploy.sh @@ -0,0 +1,11 @@ +sudo mkdir -p /var/lab/mongo_replica +sudo mkdir -p /var/lab/swarmexec +sudo touch /var/lab/mongo_replica.log + +env MONGOnode1=mtoje636wza8b0pxvhj7ewto3 \ +env MONGOnode2=teab4qgrb17mb5sv2a8ex599g \ +env MONGOnode3=st6ebl5y2kjvgjthq88v6r2fs \ +docker stack deploy -c stack.yml mongo + + + diff --git a/mongod2.conf b/mongod2.conf new file mode 100644 index 0000000..f4d316c --- /dev/null +++ b/mongod2.conf @@ -0,0 +1,21 @@ +systemLog: + destination: file + path: "/var/log/mongodb/mongod.log" + logAppend: true +storage: + dbPath: "/data/db" + journal: + enabled: true +#processManagement: +# fork: true +net: + port: 27017 + #bindIp: 127.0.0.1 # Listen to local interface only, comment to listen on all interfaces. + bindIpAll: true +replication: + replSetName: "replica01" +setParameter: + enableLocalhostAuthBypass: false +security: + authorization: enabled + keyFile: "/data/mongo.key" diff --git a/stack.yml b/stack.yml new file mode 100644 index 0000000..02f3150 --- /dev/null +++ b/stack.yml @@ -0,0 +1,120 @@ +version: "3.7" + +networks: + mongo-net: + external: true + +services: + + node1: + image: mongo:4.0 + command: /usr/bin/mongod --config /etc/mongod.conf + labels: + node1.description: "node1" + networks: + mongo-net: + ipv4_address: 192.168.1.11 + expose: + - "27017" + environment: + TERM: xterm + volumes: + - /etc/localtime:/etc/localtime:ro + - /var/lab/mongo_replica:/data/db + - /var/lab/swarmexec/mongo.key:/data/mongo.key + - /var/lab/swarmexec/mongod2.conf:/etc/mongod.conf + - /var/lab/mongo_replica.log:/var/log/mongodb/mongod.log + deploy: + mode: replicated + replicas: 1 + endpoint_mode: vip + restart_policy: + condition: on-failure + resources: + limits: + cpus: '1' + memory: 512M + reservations: + cpus: '0.50' + memory: 512M + placement: + constraints: + - node.id == ${MONGOnode1} + labels: + node1.description: "node1" + + + node2: + image: mongo:4.0 + command: /usr/bin/mongod --config /etc/mongod.conf + labels: + node2.description: "node2" + networks: + mongo-net: + ipv4_address: 192.168.1.12 + expose: + - "27017" + environment: + TERM: xterm + volumes: + - /etc/localtime:/etc/localtime:ro + - /var/lab/mongo_replica:/data/db + - /var/lab/swarmexec/mongo.key:/data/mongo.key + - /var/lab/swarmexec/mongod2.conf:/etc/mongod.conf + - /var/lab/mongo_replica.log:/var/log/mongodb/mongod.log + deploy: + mode: replicated + replicas: 1 + endpoint_mode: vip + restart_policy: + condition: on-failure + resources: + limits: + cpus: '1' + memory: 512M + reservations: + cpus: '0.50' + memory: 512M + placement: + constraints: + - node.id == ${MONGOnode2} + labels: + node2.description: "node2" + + node3: + image: mongo:4.0 + command: /usr/bin/mongod --config /etc/mongod.conf + labels: + node3.description: "node3" + networks: + mongo-net: + ipv4_address: 192.168.1.13 + expose: + - "27017" + environment: + TERM: xterm + volumes: + - /etc/localtime:/etc/localtime:ro + - /var/lab/mongo_replica:/data/db + - /var/lab/swarmexec/mongo.key:/data/mongo.key + - /var/lab/swarmexec/mongod2.conf:/etc/mongod.conf + - /var/lab/mongo_replica.log:/var/log/mongodb/mongod.log + deploy: + mode: replicated + replicas: 1 + endpoint_mode: vip + restart_policy: + condition: on-failure + resources: + limits: + cpus: '1' + memory: 512M + reservations: + cpus: '0.50' + memory: 512M + placement: + constraints: + - node.id == ${MONGOnode3} + labels: + node3.description: "node3" +