Garantir que apenas uma classe seja instanciada na mão (de preferencia o server) e todo o resto seja obtido via injeção de dependencia, seja via container.get, seja informando no constructor
O banco deve ser inicializado no próprio initialize do server, obtendo a classe q controla isso via container.get
As configurações também devem ser obtidas via injeção de dependencia, de forma a deixar em um lugar centralizado o "configFactory", que é o lugar que monta o objeto de configuração. De preferencia, criar uma classe que representa a configuração, com os cmapos esperados e usar ela como símbolo de injeção.
Configuração obtida via lib config ou via process.env, preferencialmente deve ser toda maiúscula com palavras separadas por _. Pensa que o seu projeto pode rodar em uma máquina windows, que é case insensitive. Já o seu objet ode configuração, pode ficar om o nome dbUri bonitinho, por exemplo, já que vc vai ter uma função configFactory que transforma uma coisa em outra.
Evitar colocar lógica fora de função ou método, seja inicializações de variáveis, seja execução de código mais complexo. Encapsula tudo em funções ou método e cria um arquivo index.ts, que só vai chamar uma função: startServer. Todos os outros lugares não declaram nada fora de função, método ou classe
Usar inSingletonScope nas suas injeções, para fazer com que as classes sejam instanciadas apenas uma vez.