My company got to ~20 services in separated repos prior to moving them all into one monorepo, so we've ended up with 20 root commits and an enormous commit graph around the time where it all converged together. We did do them all separately though - rather than as an octopus merge.
Has been particularly interesting to balance the different languages in the same repo. Few painful bits, but overall has worked out really well.
We also build the entire thing into a single Docker container containing every service. You just start the particular one you want via the command (the entrypoint is a little shell script to invoke the correct executable).
What's the advantage of having all that in one repository? And what's the advantage of provisioning every container with functionality it will never need?
I don't know about that container strategy, but the thing I like about monorepos in that situation is that you can enforce having every commit to master represent a state where all your services and tools work together.
Otherwise if you ever need to do a rollback or post mortem or similar you have to figure out what commit out of the 20 different projects was actually being used at the time.
Of course that comes at a cost and there are other ways to get the same benefit, but my experience is that this is an easy way to keep things consistent.
In my opinion (I work at said company) the best thing about the monorepo is that 1 feature that touches several parts of the infrastructure can be in a single PR, and therefore is much easier to review.
This. Where I work it's common for features to involve 3-4 repos and it makes testing and deploying a huge pain. This leads to people sticking code in the wrong place as a work around, defeating the purpose of splitting the code into services in the first place.
All of the items in your mono-container advantage list go away if you consider the alternative of having a bunch of separate images that share a common base image.
Image layers are immutable and get deduplicated/cached individually when stored or sent over the network. For example if you pull 10 images with a common base to the same host, the first image might be slow to download but after that docker only fetches the deltas between it and the rest.
Has been particularly interesting to balance the different languages in the same repo. Few painful bits, but overall has worked out really well.
We also build the entire thing into a single Docker container containing every service. You just start the particular one you want via the command (the entrypoint is a little shell script to invoke the correct executable).