From 850523626339a3de37847f0e3278a4c966c2e8b4 Mon Sep 17 00:00:00 2001 From: Shadow Date: Tue, 17 Dec 2024 12:59:01 -0600 Subject: [PATCH] feat: mongo replica sets --- packages/server/src/utils/databases/mongo.ts | 54 ++++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/packages/server/src/utils/databases/mongo.ts b/packages/server/src/utils/databases/mongo.ts index c1b0542df..3c9556f9c 100644 --- a/packages/server/src/utils/databases/mongo.ts +++ b/packages/server/src/utils/databases/mongo.ts @@ -30,15 +30,54 @@ export const buildMongo = async (mongo: MongoNested) => { mounts, } = mongo; - const defaultMongoEnv = `MONGO_INITDB_ROOT_USERNAME=${databaseUser}\nMONGO_INITDB_ROOT_PASSWORD=${databasePassword}${ - env ? `\n${env}` : "" - }`; + const initReplicaSet = ` +#!/bin/bash +mongod --port 27017 --replSet rs0 --bind_ip_all & +MONGOD_PID=$! + +# Wait for MongoDB to be ready +while ! mongosh --eval "db.adminCommand('ping')" > /dev/null 2>&1; do + sleep 2 +done + +# Check if replica set is already initialized +REPLICA_STATUS=$(mongosh --quiet --eval "rs.status().ok || 0") + +if [ "$REPLICA_STATUS" != "1" ]; then + echo "Initializing replica set..." + mongosh --eval ' + rs.initiate({ + _id: "rs0", + members: [{ _id: 0, host: "localhost:27017", priority: 1 }] + }); + + // Wait for the replica set to initialize + while (!rs.isMaster().ismaster) { + sleep(1000); + } + + // Create root user after replica set is initialized and we are primary + db.getSiblingDB("admin").createUser({ + user: "${databaseUser}", + pwd: "${databasePassword}", + roles: ["root"] + }); + ' +else + echo "Replica set already initialized." +fi + +wait $MONGOD_PID`; + + const defaultMongoEnv = `MONGO_INITDB_DATABASE=admin\n${env ? `${env}` : ""}`; + const resources = calculateResources({ memoryLimit, memoryReservation, cpuLimit, cpuReservation, }); + const envVariables = prepareEnvironmentVariables( defaultMongoEnv, mongo.project.env, @@ -56,12 +95,8 @@ export const buildMongo = async (mongo: MongoNested) => { Image: dockerImage, Env: envVariables, Mounts: [...volumesMount, ...bindsMount, ...filesMount], - ...(command - ? { - Command: ["/bin/sh"], - Args: ["-c", command], - } - : {}), + Command: ["/bin/bash"], + Args: ["-c", command ?? initReplicaSet], }, Networks: [{ Target: "dokploy-network" }], Resources: { @@ -90,6 +125,7 @@ export const buildMongo = async (mongo: MongoNested) => { : [], }, }; + try { const service = docker.getService(appName); const inspect = await service.inspect();