Trying to setup a Mongo ReplicaSet
I know that MongoDB Replica Sets are not officially supported. However, with the Railway current capabilities in theory could be approached.
I am following the official steps and I feel to be stuck on first steps and I would like to understand if there is anything I can do alternatively.
With the start command support for docker, you can pass "--replSet rs0" to the mongod command. However, you need to enforce security with a key for the replicas communication and shared between three minimum required mongo replicas.
I was trying to store the key into an env variable, and then tweak the start command of the service with something like this:
docker-entrypoint.sh mongod --replSet rs0 --keyFile <(echo "${AUTH_SECRET}" | base64) --ipv6 --bind_ip ::,0.0.0.0
However, I think this is not working and I think the reason is that start command can't execute " <(echo ${VAR})" "$(echo ${VAR})" dynamic evaluations.
Am I correct on this limitation? Is there any chance to ask for support dynamic evals on start commands?
Alternatively, could you think in an alternative way to achieve this?
Of course, I was thinking in possibly create a forked mongo db image and include a way to fetch securely the secret, generate the file and be ready to link it on the start command just by the route. But I was wondering if there is an even easier way to achive this without going out Railsway context.
Thank you40 Replies
Project ID:
N/A
wrap start command in
That worked! Thank you.
Having other issues on the way to set up the secret file, but it is really good to see Railsway flexibility on configure your projects. 😁
railway has a lot of flexibility, it's just not exposed as well as it could be
I achieved to have my mongodb reclica set setup!
1. Prepare three mongo nodes on the same environment in Railway.
2. Tweak the start command like this on each of the nodes:
3. Add
AUTH_SECRET
as a shared env in Railway and make it available for the three mongo nodes.
To generate the key beforehand on your own env with:
This copied the key ready to be added on your Railway shared env section.
3. Configure on the primary node the replica set config using internal network address.
And finally once three nodes are ready! Enjoy 😁make this a template!!!
(also use triple backticks for multi line code blocks)
I never tried to make one. I will check out the docs to see how. Thank you 😁
this would be a great addition if you could make it work in template form!
https://docs.railway.app/reference/templates
the only thing I am not sure how to do it is to automatically run the rs.initiate command only once
and after all nodes are created. Maybe templates are not ready for this use case
have a service in the template that does that initialisation
I'm confident you could make it work after familiarising yourself with the template creation process
Let us know if there’s something you’re missing! Init scripts are something I’ve thought about lightly but haven’t found a great solution to
i second init scripts, ive had a few uses for them, ended up sticking it in a start command
I have a question, do you know if shared variables are included on the template? They don't seem to appear once I try to convert a project that has shared envs to a template
they arent
but you can set a variable on one service and then reference it from other services
https://docs.railway.app/develop/variables#reference-variables
a real example of this would be my typebot template https://railway.app/template/typebot
where the builder and viewer both need a whole lot of the same variables, i set most of the variables on the builder service and reference them on the viewer service
Interesting. Will try few things
sounds good!
i set most of the variables on the builder serviceWhen you say this, how the communication between the service and railway happens to be able to set the envs on the service run? Do I have to import an API for that? Or should I just include fake static env vars?
nope, please have a read of the docs page i linked and look through the variables on the builder and viewer service of the typebot template
I implemented a project where I created the three mongo nodes and a service that initializes those nodes using a github repository. I created the template from the project. Several questions:
- The service is a Github repository with a main.sh command to wait the nodes and do the initialization once they ready. I am asked to clone the project whenever I deploy from the template. I guess I should use a docker image instead to avoid the clone and be more staightforward config?
- I can't seem to generate properly the secrets with
${{ secret(128, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/') }}
as the docs suggest to be possible. When the project is deployed the value the raw value is utilized without password evaluation. What am I doing wrong?
- Is it possible to parametrize or allow to edit the db source (mongo docker image version) when deploy a project from the template? It would be good for the user to be able to select the proper DB version they expect to use.1. if you could make it work with all docker images that would be highly preferable
2. maybe it doesn't support 128 length?
3. not yet unfortunately
I am trying to achieve the same thing. The service keeps failing with the following error "MongoDB - ReplicaSet - Failed to refresh key cache"
Yes, I got that as well on my new project to generate the template. The only difference has been that now I use the latest mongo 7 version. Not sure if this is related or what. I didn't have more time to reattempt on this. I am also thinking that it may be related with some kind of race condition on setting up the nodes and the rs initialization process. Not sure, still testing.
Regarding the template, it is good to be able to launch automatically all nodes and the initialization process, but I am still getting wrong the secret on using this on the secret env the way is mentioned on the docs
${{ secret(32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/') }}
.Hello, I'm new to this. I don't really understand the third step, the configuration of the primary node. Where should this be put? Should this be on the Redis? I am missing something. Context: Trying to use Prisma on this db, and it is requiring me a replica set.
heres the docs on shared variables https://docs.railway.app/guides/variables#shared-variables
Ah sorry, i miscounted :)) Fourth step the " rs.initiate" one. ( I didn't notice the duplicate 3. )
welp i have no idea about that one then, sorry
youd have to wait for an answer from nacho
It is alright, thank you very much anyway 😄
That needs to be run using mongosh connecting to your primary instance. This is the step that ensures proper configuration of replica set hosts.
https://www.mongodb.com/docs/manual/reference/method/rs.initiate/
Can this method be applied to a running database that has data in it?
I didn't test that scenario. I don't know.
In the docs they explain how to do it, https://www.mongodb.com/docs/manual/tutorial/convert-standalone-to-replica-set/
I'll try this, My project has gone big and I need changeStreams to monitor the collections for invalid activity and error correction.
How did you connect to the primary node with mongosh? When I use the startup command you posted, I can't connect to the database through a public network. I can't find how to connect to the primary node through the private network to execute the rs.initiate() command.
Also, all three of the nodes spam this in the console, does your setup do that as well?
To connect using mongosh you normally need to do:
mongosh "mongodb://user:pwd@host:port/database" --authenticationDatabase admin
In the case of Railway, yes, you can't connect using the private IP. But some months back a way to expose a public IP pointing to TCP service (eg Mongo) was implemented. In fact, as part of adding a new mongo node that IP is exposed automatically with a port, if don't you have it you can do it yourself. In the picture I attach, you can check where you can find the public address to use it for the mongosh command.Aggregate command executor errorThis error will go away once the replica setup is configured properly.
Won't we need a vpn to connect to the private network?
This isn't working. MongoServerSelectionError: connection <monitor> to 35.213.165.89:47424 closed
I am getting the "Aggregate command executor error" and not able to connect
plus in the rs.initialize my hostname doesn't change to mongo-two or three
Should I change the service variable HOST to this?
Alright I was able to follow through this somehow
This is the last log that I get in my deploy logs
Received first command on ingress connection since session start or auth handshake
Is this a good thing?
I just see connection accepted/ended and auth succeeding logs on my end. Have you already reached that?
I have to say that I attempted to replicate my initial set up to make a template, but I run into many issues, the fact that for making the template all nodes are initialized, configured and served at the same time likely being the reason of all the issues. And I didn't have time to see them and clarify why it fails.
Maybe I was lucky on my initial attempt, but it worked straight with the steps described above.
I want to provide also more context about my set up: I use Mongo 6.0.11 version in my app via the docker official image tag.
In the template thing I tried with latest 7.x version where I got the problems. Not sure if related but just mentioning.
Lucky you, I lost some of my data on my first attempt.
Happy to see that Railway just delivered the official support of MongoDB Replica Set, https://railway.app/template/ha-mongo
I have been using MongoDB replicas for long already, and this template should overcome many of the problems when I tried to automate. 🥳
awesome, we would love to hear your feedback!