Um problema muito comum na área de tecnologia é garantir que um programa seja executado da exata mesma forma em diferentes ambientes, como, por exemplo, garantir que um software seja executado em produção da mesma forma que foi testado no ambiente de desenvolvimento. Esse problema tende a se tornar cada vez pior com o aumento da complexidade dos componentes do software.
Uma série de fatores pode influenciar nesse problema, como o hardware que está sendo usado para executar, o sistema operacional (SO), outros softwares instalados, a linguagem e o fuso horário do sistema operacional, entre outros.
A primeira solução para esse tipo de problema foram as chamadas máquinas virtuais (VM), que permitem executar dentro do nosso sistema operacional um ambiente isolado rodando outro sistema operacional à nossa escolha, por exemplo, rodar um Ubuntu dentro de um Windows ou um Windows em um Ubuntu. No entanto, ainda era necessário configurar manualmente as definições da máquina virtual, o sistema operacional que seria executado e todos os programas que deveriam ser instalados.
Surgiu então o Vagrant, uma ferramenta para administrar máquinas virtuais na qual era possível definir todas as configurações de uma máquina virtual através de um arquivo de texto. Isso facilitou a criação de ambientes por times de desenvolvimento, pois agora todos utilizavam o mesmo arquivo de configuração para criar o ambiente virtualizado.
No entanto, utilizar máquinas virtuais ainda era um problema, pois elas ocupam muita memória e processamento, já que é necessário executar um novo sistema operacional completo na nossa máquina. Isso se agrava ainda mais quando é necessário que cada serviço da aplicação seja executado em um ambiente isolado. Cada nova VM consumiria uma quantidade excessiva de recursos do computador.
Então, em 2013, Solomon Hykes lançou a primeira versão do Docker, uma abstração que utiliza dois recursos do kernel do Linux: o Namespaces, que permite isolar processos fazendo com que eles fiquem visíveis somente entre si, e o cgroups (Control Groups), que permite um controle granular sobre os recursos do sistema, como memória e processamento. Assim, ao invés de instalar um novo sistema operacional completo, o Docker permite a criação de ambientes isolados dentro de uma mesma máquina por meio do isolamento dos processos, e esses ambientes foram chamados de containers.
Dessa forma, o Docker surgiu como uma alternativa muito mais eficiente em comparação às máquinas virtuais, por utilizar os próprios recursos do sistema operacional e apenas isolar os diferentes processos em containers ao invés de executar um sistema operacional completo para cada ambiente, como mostra a imagem a seguir.
Em resumo: