Introdução ao Docker: Simplificando a Gestão de Aplicações
Published: 2023-08-19 15:24:01

## Tópicos
&nbsp;1. [Introdução](#introdu%C3%A7%C3%A3o)
&nbsp;2. [Revisão de Sistemas Operacionais e Virtualização](#revis%C3%A3o-de-sistemas-operacionais-e-virtualiza%C3%A7%C3%A3o)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1. [Kernel do SO](#kernel-do-so)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. [Processos e Isolamento de Processos](#processos-e-isolamento-de-processos)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. [Gestão de Memória](#gest%C3%A3o-de-mem%C3%B3ria)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. [Sistema de Arquivos](#sistema-de-arquivos)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2. [Virtualização](#virtualiza%C3%A7%C3%A3o)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. [Virtualização de Hardware](#virtualiza%C3%A7%C3%A3o-de-hardware)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. [Virtualização de Sistema Operacional](#virtualiza%C3%A7%C3%A3o-de-sistema-operacional)
&nbsp;3. [O que é Docker?](#o-que-%C3%A9-docker)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. [Imagens](#imagens)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. [Container](#container)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3. [Volumes](#volumes)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.4. [Redes](#redes)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.5. [Compartilhamento de portas com o SO Host](#compartilhamento-de-portas-com-o-so-host)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6. [Docker Registry](#docker-registry)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.7. [Dockerfile](#-raw-dockerfile-endraw-)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.8. [Docker compose](#docker-compose)
&nbsp;4. [Conclusão](#conclus%C3%A3o)


## Introdução

Nos últimos anos, o desenvolvimento e a implantação de aplicativos têm sido transformados por tecnologias inovadoras que visam simplificar e agilizar todo o processo. Uma dessas tecnologias que ganhou enorme popularidade é o Docker. Com a capacidade de empacotar, distribuir e executar aplicativos em ambientes isolados, o Docker trouxe uma abordagem revolucionária para a criação de ambientes de desenvolvimento e produção consistentes e escaláveis. Neste artigo, vamos explorar os fundamentos do Docker e como ele está mudando a forma como os aplicativos são desenvolvidos e implantados.

---

## Revisão de Sistemas Operacionais e Virtualização

Antes de explorarmos mais a fundo o Docker e seus conceitos, é importante revisarmos alguns aspectos fundamentais dos sistemas operacionais e entender como eles estão relacionados com a virtualização, uma vez que o Docker utiliza uma tecnologia específica de virtualização de containers.

### Kernel do SO

O Kernel é o núcleo do sistema operacional, responsável por gerenciar recursos e fornecer serviços aos processos e aplicativos. Ele controla o acesso ao hardware, a execução de processos, a alocação de memória, entre outras tarefas essenciais. O kernel atua como uma camada de abstração entre o hardware e os programas em execução. A seguir vamos falar sobre algumas atribuições do Kernel de um Sistema Operacional.

#### Processos e Isolamento de Processos

Um processo é uma instância em execução de um programa. O isolamento de processos é um conceito-chave em sistemas operacionais, que garante que os processos não interfiram uns nos outros. Cada processo possui seu próprio espaço de endereçamento de memória, registradores, pilha e outras estruturas de dados. Isso evita conflitos e garante que um processo não acesse a memória de outro sem permissão.

#### Gestão de Memória

A gestão de memória é crucial para otimizar o uso dos recursos do sistema. Os sistemas operacionais são responsáveis por alocar e desalocar memória para os processos, bem como garantir a proteção da memória entre os processos. Mecanismos como paginação e segmentação são utilizados para permitir o compartilhamento seguro da memória entre processos.

#### Sistema de Arquivos

O sistema de arquivos é a estrutura que organiza e armazena os dados em dispositivos de armazenamento, como discos rígidos e SSDs. Ele permite a criação, leitura, gravação e exclusão de arquivos e diretórios. Os sistemas operacionais fornecem interfaces para acessar e manipular arquivos, gerenciando o armazenamento físico e a hierarquia de diretórios.

### Virtualização

De forma simplória, a virtualização é uma tecnologia que permite a criação de ambientes isolados e independentes, chamados de máquinas virtuais (VMs), dentro de um sistema hospedeiro. Ela oferece uma forma de executar múltiplos sistemas operacionais ou ambientes de software em uma única máquina física. Dois principais tipos de virtualização são relevantes para entender o Docker:

#### Virtualização de Hardware

Nesse modelo, uma camada de software chamada hipervisor é executada no hardware físico. O hipervisor gerencia a alocação de recursos entre as várias VMs. Cada VM contém um sistema operacional completo, incluindo kernel, processos e bibliotecas. Isso oferece um alto grau de isolamento, mas também pode ser mais pesado em termos de recursos, uma vez que cada VM inclui um sistema operacional completo.

#### Virtualização de Sistema Operacional

Também conhecida como virtualização de containers, essa abordagem compartilha o mesmo kernel entre o sistema hospedeiro e os containers. Os containers isolam processos e ambientes de execução, permitindo a execução de aplicativos em ambientes encapsulados. Isso resulta em menor sobrecarga, pois não há necessidade de múltiplos kernels. A virtualização de containers é mais eficiente em termos de recursos e oferece uma forma ágil de empacotar, distribuir e executar aplicativos.

---

## O que é Docker?

O Docker é uma plataforma de código aberto que permite criar, implantar e executar aplicações em containers. Um *container* é uma unidade de software que contém todas as dependências necessárias para executar uma aplicação, incluindo o código, bibliotecas, ambientes de tempo de execução e configurações. Essa abordagem de containers possibilita que as aplicações sejam isoladas em ambientes consistentes e portáveis, garantindo que elas funcionem de maneira confiável em diferentes ambientes.

O Docker opera em um sistema operacional host, que é o sistema operacional do usuário. No caso de sistemas baseados em Unix como Linux ou MacOS, o Docker é executado diretamente sobre o SO nativo. Já no Windows, o Docker pode ser executado através do Hyper-V ou da plataforma de virtualização WSL (Windows Subsystem for Linux) da Microsoft. No caso do uso do WSL, o Docker ainda compartilha o kernel do sistema operacional Linux emulado. Isso proporciona eficiência em termos de recursos, já que os containers não precisam virtualizar todo o hardware.

### Imagens

As imagens Docker são a espinha dorsal de como o Docker trabalha. Uma imagem é um modelo somente leitura que contém todos os componentes necessários para executar um aplicativo, incluindo o código-fonte, as bibliotecas, as dependências e os arquivos de configuração. Elas servem como base para criar containers.

Uma imagem é construída a partir de um arquivo chamado `Dockerfile`, que contém instruções para definir o ambiente do aplicativo. Ele especifica a partir de qual imagem base começar, quais comandos executar para configurar o ambiente e como o aplicativo será inicializado.

### *Container*

Os containers são instâncias em tempo de execução de imagens. Eles encapsulam um ambiente isolado para a execução de um aplicativo, incluindo seu sistema de arquivos, variáveis de ambiente, bibliotecas e processos em execução. Os containers são leves e compartilham o mesmo kernel do sistema operacional host, o que resulta em uma utilização eficiente de recursos.

Cada container é isolado dos outros, o que significa que os processos em execução em um container não interferem nos processos de outros containers. Isso proporciona uma excelente maneira de garantir a consistência e a separação entre os aplicativos, mesmo quando estão todos sendo executados no mesmo host.


![virtualization vs containers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47oub6xamaaj8qbh66pa.png)



### Volumes

Os volumes no Docker são mecanismos que permitem persistir dados além do ciclo de vida de um container. Eles são usados para compartilhar dados entre o host e os containers ou entre containers diferentes. Um volume é um diretório ou arquivo no sistema de arquivos do host que é montado em um determinado ponto dentro do container.

Os volumes são particularmente úteis para armazenar dados que precisam ser mantidos entre a inicialização e o encerramento do container, como bancos de dados ou arquivos de configuração. Eles também são uma forma de compartilhar dados entre containers que precisam colaborar. Além disso, eles podem ser utilizados como forma de manter o código fonte de um software no SO Host, acessível ao desenvolvedor, enquanto sua execução é feita dentro de um container.

### Redes

As redes Docker permitem a comunicação entre containers em diferentes hosts ou no mesmo host. Elas são usadas para conectar containers que precisam se comunicar uns com os outros, seja para trocar dados ou para formar componentes de um aplicativo distribuído.

As redes Docker podem ser configuradas para diferentes modos de comunicação, como modo bridge (ponte) para comunicação interna entre containers ou modo host para comunicação direta com a rede do host. Isso permite criar ambientes complexos em que os containers podem se comunicar de maneira eficiente e segura.

### Compartilhamento de portas com o SO Host

Os containers podem expor portas para o host e para a rede externa. Isso permite que os aplicativos sejam acessados através de interfaces de rede, tornando-os disponíveis para os usuários e para outros sistemas.

### Docker Registry

O Docker Registry é um repositório para armazenar e compartilhar imagens Docker. Ele é essencial para compartilhar imagens entre desenvolvedores e implantações. O [Docker Hub](https://hub.docker.com) é um exemplo de um Docker Registry público (repositório padrão), onde você pode encontrar imagens prontas para uso em diferentes cenários.

Você também pode configurar seu próprio Docker Registry privado para armazenar imagens internamente. Isso é especialmente útil quando você deseja manter o controle sobre as imagens usadas em sua organização ou quando precisa lidar com requisitos de segurança mais rigorosos.

### `Dockerfile`

Um Dockerfile é um arquivo de texto que contém um conjunto de instruções para criar uma imagem Docker. Ele é a base para construir imagens personalizadas que atendam às necessidades específicas do aplicativo.

No Dockerfile, você pode especificar uma imagem base, instalar pacotes e bibliotecas adicionais, configurar variáveis de ambiente, copiar arquivos para dentro da imagem e definir como o aplicativo será iniciado. Esse arquivo é usado pelo Docker para automatizar a criação de imagens de maneira consistente e reprodutível.

A seguir, um exemplo de um `Dockerfile`:

```dockerfile
# Usar uma imagem base
FROM node:14

# Definir o diretório de trabalho
WORKDIR /app

# Copiar os arquivos de configuração
COPY package.json package-lock.json /app/

# Instalar as dependências
RUN npm install

# Copiar o restante dos arquivos da aplicação
COPY . /app/

# Expor a porta que a aplicação irá escutar
EXPOSE 3000

# Comando para iniciar a aplicação
CMD ["npm", "start"]
```

### Docker compose

O Docker Compose é uma ferramenta que permite definir e executar aplicativos compostos por vários containers. Com um único arquivo de configuração, é possível definir a estrutura do aplicativo, suas dependências e como eles devem se comunicar.

O arquivo de configuração do Docker Compose é escrito em YAML (**`docker-compose.yml`**) e pode definir vários serviços, redes e volumes. Ele fornece uma maneira fácil de iniciar e gerenciar aplicativos complexos, permitindo que você descreva a arquitetura do aplicativo e suas interações de forma clara e concisa.

> #### Linguagem YAML (YAML Ain't Markup Language)
> YAML é uma linguagem de marcação leve que é frequentemente utilizada para configuração de dados estruturados. Ela é bastante legível para humanos e utiliza espaços e indentação para definir a estrutura dos dados. O YAML é comumente usado em arquivos de configuração, como o docker-compose.yml, para definir serviços, configurações e relacionamentos entre diferentes componentes.

A seguir, dois exemplos de arquivos `docker-compose.yml`:

```yaml
version: '3'
services:
  webapp:
    build:
      context: .  # Diretório onde está localizado o Dockerfile
    ports:
      - '3000:3000'
```

Neste exemplo, estamos definindo um serviço chamado 'webapp'. Estamos indicando que ele deve ser construído usando o Dockerfile no mesmo diretório (`context: .`) e mapeando a porta 3000 do host para a porta 3000 do container.


```yaml
version: '3'
services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: mysecretpassword
      MYSQL_DATABASE: mydatabase
    volumes:
      - mysql-data:/var/lib/mysql

  webapp:
    image: php:7.4-apache
    ports:
      - '80:80'
    volumes:
      - ./webapp:/var/www/html
    depends_on:
      - mysql

volumes:
  mysql-data:
```

Já neste exemplo, temos dois serviços: mysql e webapp.

- O serviço mysql utiliza a imagem oficial do MySQL 5.7 e configura algumas variáveis de ambiente, como a senha do root e o nome do banco de dados. O uso de volumes permite persistir os dados do banco de dados fora do container.

- O serviço webapp utiliza a imagem oficial do PHP 7.4 com o servidor Apache. Ele mapeia a porta 80 do host para a porta 80 do container e monta o diretório local `./webapp` no diretório `/var/www/html` do container. Isso permite que você desenvolva a aplicação localmente e veja as alterações refletidas imediatamente no container.

Além disso, o serviço webapp depende do serviço mysql, o que garante que o container do banco de dados esteja em execução antes do container da aplicação web.

Por fim, um volume chamado mysql-data é definido para persistir os dados do banco de dados em um volume Docker, tornando os dados persistentes mesmo quando os containers são reiniciados ou atualizados.

O Docker Compose simplifica a criação e gerenciamento de ambientes de desenvolvimento complexos, permitindo que você defina e execute vários serviços interconectados com facilidade.

---

## Conclusão

A revolução trazida pelo Docker na forma como desenvolvemos, implantamos e gerenciamos aplicativos é inegável. Com uma abordagem baseada em containers, o Docker fornece uma maneira eficiente de criar, distribuir e executar aplicativos em ambientes isolados e consistentes. O uso de imagens, containers, volumes, redes e outras funcionalidades do Docker permite uma maior portabilidade, escalabilidade e facilidade de implantação.

Além disso, a compreensão dos conceitos fundamentais de sistemas operacionais, como o papel do kernel, isolamento de processos, gestão de memória e sistema de arquivos, é crucial para aproveitar ao máximo os benefícios oferecidos pelo Docker. A virtualização, tanto a de hardware quanto a de sistema operacional, também desempenha um papel fundamental na compreensão das tecnologias subjacentes ao Docker e de como ele consegue fornecer ambientes isolados de maneira eficiente.

O Dockerfile e o Docker Compose são ferramentas poderosas que simplificam a criação e o gerenciamento de ambientes de desenvolvimento complexos. O uso do Docker Registry, seja público ou privado, amplia ainda mais a flexibilidade e a eficiência do desenvolvimento e implantação de aplicativos.

Em resumo, o Docker representa um divisor de águas na maneira como desenvolvemos e entregamos software. Sua abordagem baseada em containers oferece uma solução altamente eficiente e flexível para a criação e execução de aplicativos, independentemente do ambiente em que serão implantados. Portanto, investir tempo para entender os conceitos por trás do Docker e aprender a trabalhar com suas ferramentas pode ser extremamente benéfico para profissionais de desenvolvimento, operações e outras áreas relacionadas.