Application modernization and containerization
Turns out that containers are pretty great, both for development environments and production!
This effort of mine took anywhere between months to years of efforts, depending on how you look at things. Initially, I started out with adding systemd services and Ansible for managing server configuration, but it turned out that this alone wasn't enough to ensure consistency across different environments. The answer to that issue was using containers instead and making the running application instances truly reproducible - you ship what you test!
What I did
In my case, I went for the tried and trusted setup of Docker and Docker Swarm (at least for development environments), which lead to more than a hundred containers successfully running per cluster. Every application that was needed as a part of the group of projects was containerized by the end, with CI/CD cycles for both building and deploying them, as well as for shipping new releases.
What I learnt
It wasn't an easy path, since some legacy code needed to be addressed and improved along the way, as opposed to just shoving it inside of a container and pretending that everything is okay. However, in the end I managed to come out on the top of these challenges and now it's even easy to introduce new services into the mix.