Se você já viu um projeto funcionar na sua máquina e falhar no do colega ou no servidor, provavelmente esbarrou em diferenças de ambiente. O Docker resolve esse problema, empacotando o programa com o que ele precisa para rodar.

O Que é Docker
Docker é uma plataforma de gerenciamento de contêineres que ajuda a criar e gerenciar ambientes de execução isolados para aplicativos. Ele reúne a aplicação e o ambiente de execução em uma imagem, que é um modelo somente leitura que contém o programa, bibliotecas e configurações.
Imagens, Contêineres e Registry
Uma imagem é um modelo somente leitura que contém o programa, bibliotecas e configurações. Um contêiner é uma instância dessa imagem em execução. Uma analogia útil é que a imagem é como um disco de instalação; o contêiner é o programa instalado e rodando. Você pode iniciar vários contêineres a partir da mesma imagem. Cada um ganha sua própria camada gravável, processo e rede. Alterações feitas dentro de um contêiner não mudam a imagem original. Se apagar o contêiner, a imagem ainda pode ser usada para iniciar outro, mas os dados da camada gravável daquele contêiner desaparecem. Para dados que precisam sobreviver, como os de um banco de dados, use um Volume.
Registries
O terceiro conceito é o Registry: um servidor que armazena e compartilha imagens. O Docker Hub é o mais usado. Quando você executa docker run nginx sem especificar outro endereço, o Docker procura a imagem lá. Também existem Registries do GitHub e de provedores de nuvem; equipes podem publicar suas próprias imagens nesses serviços.
Camadas e Reutilização
Imagens são compostas de camadas. Uma imagem de um site Node.js, por exemplo, pode ter uma camada do sistema base, outra com o ambiente Node.js, uma com pacotes instalados e a camada do código da aplicação. Imagens diferentes conseguem compartilhar camadas inferiores. Se várias usam Debian como base, essa camada é armazenada e baixada uma vez, em vez de ser duplicada para cada imagem. Isso ajuda a entender por que a ordem das instruções em um Dockerfile faz diferença: mudanças em partes mais altas podem aproveitar as camadas que continuam iguais.
O Caminho do Comando até o Contêiner
Ao digitar docker no terminal, você usa a Docker CLI, o cliente de linha de comando. Ela não executa contêineres diretamente: envia solicitações ao Docker Engine, serviço em segundo plano que baixa imagens e cria e gerencia contêineres, redes e Volumes. Para obter ou enviar imagens, o Engine conversa com um Registry.
Contêineres e Máquinas Virtuais
Um contêiner compartilha o kernel do sistema operacional do host e isola o que o programa precisa, como sistema de arquivos, processos e rede. Na prática, contêineres costumam iniciar em menos de um segundo e ocupam de alguns MB a centenas de MB. VMs normalmente levam de dezenas de segundos a minutos para iniciar e podem ocupar vários GB. Como compartilham o kernel, contêineres Linux precisam de um kernel Linux; uma VM pode executar outro sistema operacional, como Windows em um host Linux. Isso não torna contêineres substitutos de VMs. Os dois aparecem juntos com frequência: serviços de nuvem podem executar contêineres dentro de máquinas virtuais. A escolha depende do isolamento e do ambiente que você precisa.
Conclusão
Docker simplifica a execução de aplicativos em diferentes ambientes, reduzindo as diferenças entre máquinas. Imagens são o modelo; contêineres são instâncias em execução; e Registries são onde as imagens são armazenadas e compartilhadas. A CLI envia solicitações ao Engine, que gerencia contêineres e troca imagens com o Registry. Isso permite que você controle o Engine de um servidor remoto usando o Docker no notebook. Os contêineres e máquinas virtuais aparecem juntos com frequência, mas a escolha depende do isolamento e do ambiente que você precisa.