Questa domanda sarebbe anche pertinente per golang, dove puoi semplicemente estrarre binari collegati staticamente ed eseguirli da qualche parte, al contrario di Python o C ++, dove solitamente hai un gran numero di librerie collegate che porta le persone a costruire semplicemente un container fuori dall'ambiente di sviluppo.
Ci sono due punti per rispondere qui:
Uno: là deve essere un modo migliore , e c'è: puoi costruire container più piccoli (e più efficienti) usando semplicemente l'ambiente di installazione, il che porta a vantaggi simili come nel caso di contenitori Golang-con-ambiente contro Golang-solo-binari. Nel caso di Java, è possibile creare un jar fat o un'app installabile che contenga tutti i jar della libreria e uno script della shell; nel caso di Python, è possibile utilizzare auditwheel per creare ruote indipendenti indipendenti dall'ambiente di generazione (e si potrebbe usare C ++ con collegamento statico quasi allo stesso effetto).
Due: per cosa hai bisogno di docker? In Java land, puoi fare molta separazione tra diversi componenti usando i programmi di caricamento di classi, ma il punto principale è ciò che è intorno all'applicazione Java. Nessuna applicazione Java viene eseguita da sola: se non viene eseguita nella finestra mobile, di solito deve essere controllata da supervisord, systemd o simili. Inserisci il cloud Kubernetes, Marathon o Docker, che utilizza l'astrazione del contenitore per virtualizzare non l'host stesso, ma in realtà virtualizza l'intera rete in modo tale che puoi semplicemente distribuire i contenitori e questi vengono eseguiti su un host casuale.
I microservizi di solito funzionano su cloud basati su docker perché consentono di trattare gli host di docker come bestiame, non come animali domestici e in modo simile con le applicazioni ancorate. Naturalmente, questa astrazione perde quando si montano i volumi host sulla finestra mobile e occorre eseguire contenitori docker esattamente sull'host con questi volumi. Alcune persone si aggirano intorno a questo.