src | theme | class | highlighter | mdc | drawings | image | selectable | colorSchema | title | author | download | export | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
./cover.md |
default |
text-center |
shiki |
true |
|
/side-logo.png |
true |
dark |
Docker |
Pablo Leon Rodrigues |
true |
|
Docker é uma plataforma open source que automatiza a implantação, escalabilidade e execução de aplicações dentro de contêineres.
Contêineres são ambientes isolados e portáteis que contêm tudo o que uma aplicação precisa para funcionar, incluindo bibliotecas, dependências e configurações.
::right::
Antes de falar do docker precisamos entender a diferença entre Virtualização
e Conteinarização
Em vez de usar um único sistema físico para cada tarefa, a tecnologia de virtualização permite dividir o hardware em várias máquinas virtuais (VMs) que operam como sistemas independentes, com seu próprio sistema operacional e aplicações. Cada VM compartilha os recursos do hardware físico, mas opera de forma isolada das demais.
::right::
Para gerênciar várias máquinas virtuais existe uma camada chamada hypervisor
, como por exemplo, VirtualBox, VMwere, KVM. O Hipervisor é responsável dimensionar a máquina virtual, fornecer acesso, iniciar e desligar vms... entre outras tarefas.
Existem dois tipos principais de Hypervisors:
-
Hosted: são softwares instalados na máquina, e dependem de um sistema operacional, como VMWare e VirtualBox.
-
BareMetal: esses softwares rodam diretamente no hardware do host, tendo um controle do host em mais baixo nível... VMware ESXi, Microsoft Hyper-V, and Citrix XenServer.
A conteinerização é uma tecnologia que permite empacotar um aplicativo e suas dependências em um "container", que é um ambiente isolado, mais leve e que roda em cima do sistema operacional.
A conteinerização compartilha o kernel do sistema operacional do host com múltiplos containers, usando recursos nativos. Cada container é uma instância isolada do ambiente necessário para o aplicativo, incluindo dependências e bibliotecas, mas sem precisar de um sistema operacional completo sendo mais leve que a virtualização.
::right::
Aspecto | Virtualização | Containerização |
---|---|---|
Isolamento | Completo com SO próprio | Compartilhamento do kernel do host |
Consumo de Recursos | Alto, devido ao SO completo | Baixo, devido ao compartilhamento do kernel |
Inicialização | Mais lento | Mais rápido |
Portabilidade | Boa, depende dos hypervisors | Muito alta, independente de infraestrutura |
Escalabilidade | Escalável, mas com overhead maior | Facilmente escalável, ideal para microsserviços |
Segurança | Maior isolamento | Isolamento limitado |
Uso ideal | Aplicações pesadas, múltiplos SOs | Microsserviços, aplicações leves e portáveis |
- Portabilidade: Aplicações podem ser executadas de forma consistente em diferentes ambientes.
- Isolamento: Contêineres são isolados, reduzindo conflitos entre dependências.
- Eficiência: Contêineres são leves em comparação com máquinas virtuais, economizando recursos.
- Escalabilidade: Fácil replicação e escalabilidade horizontal.
::right::
- Complexidade: Configurações complexas podem ser desafiadoras para iniciantes.
- Persistência de Dados: Contêineres são efêmeros por padrão; gerenciar dados persistentes requer configuração adicional.
- Segurança: Embora isolados, contêineres compartilham o mesmo kernel do sistema operacional host, o que pode representar um risco de segurança em algumas situações.
O Docker
para vários SO's, vamos trabalhar com Linux,
nas máquinas do laboratório temos o Ubuntu instalado e o Docker está nos principais repositórios.
Instalando pré-requisitos:
sudo apt-get update
sudp apt-get install qemu-system-x86 pass
sudo apt-get install curl apt-transport-https ca-certificates software-properties-common
Adiciona a chave GPG, inserindo o comando a seguir:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Agora, adicione o repositório executando este comando:
sudo add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
Depois disso, atualize a informação do repositório
sudo apt update
Garanta que você está instalando a partir do repositório do Docker, ao invés do repositório padrão do Ubuntu ao usar este comando:
apt-cache policy docker-ce
A saída correta vai ficar como o texto a seguir, com diferentes números de versões:
docker-ce:
Installed: (none)
Candidate: 16.04.1~ce~4-0~ubuntu
Version table:
16.04.1~ce~4-0~ubuntu 500
500 https://download.docker.com/linux/ubuntubionic/stableamd64packages
Após o processo anterior ter sido executado instale utilizando o repositório:
sudo apt install docker-ce
No Ubuntu server apenas o comando abaixo é suficiente:
sudo apt install docker.io
E para verificar a instalação
sudo systemctl status docker
::right::
Para instalar Docker Desktop, baixe o arquivo em Deb package
E em seguida entre na pasta onde o arquivo foi baixado:
cd ~/Downloads
chmod +x docker-desktop-amd64.deb
Atualize os repositórios e depois instale o package .deb
sudo dpkg -i ./docker-desktop-amd64.deb
Execute o seguinte comando:
docker run hello-world
O Dockerfile
é o ponto de entrada de um container docker, é onde a imagem e toda a lógica do container são definidos. Neste arquivo definimos as etapas para criação de um container.
- FROM: define a imagem base do container.
- WORKDIR: define o diretório de trabalho dentro do container.
- COPY: copia arquivos do sistema de arquivos host para o sistema de arquivos do container.
- RUN: executa comandos no container durante o processo de build.
- EXPOSE: informa qual porta o serviço do container vai escutar
::right::
- CMD: define o comando padrão que será executado quando o contêiner for iniciado. Diferente de RUN, que é executado durante o build, CMD é executado quando o contêiner já está rodando.
Etapas do container
- Build da imagem: Ao executar
docker build -t nome-da-imagem .
, o Docker lê o Dockerfile, segue as instruções e cria uma imagem. - Run da imagem: Quando você executa
docker run - 3000:3000 nome-da-imagem
, o Docker cria um contêiner a partir da imagem criada, mapeia a porta 3000 do host para a porta 3000 do contêiner, e executa o comando definido em CMD.
Crie um arquivo chamado speech.sh
#!/bin/bash
TEXTO=("Arise, arise, riders of Rohan!
Fell deeds awake, fire and slaughter!
Spear shall be shaken, shield be splintered!
A sword-day, a red day, ere the sun rises!
Ride now, ride now, ride to Gondor!")
figlet -w 500 -f doh "$TEXTO"
Após isso vamos criar um Dockerfile
:
FROM ubuntu:latest
RUN apt update && apt install -y figlet wget
RUN wget -P /usr/share/figlet http://www.jave.de/figlet/fonts/details/doh.flf
COPY speech.sh /speech.sh
RUN chmod +x /speech.sh
CMD ["/speech.sh"]
Vamos criar a imagem:
docker build -t "ascii" .
E usar a imagem:
docker run ascii:latest
Nesse exemplo vamos criar um container para a nossa primeira API com javascript em memória mesmo.
FROM node:16
# Define o diretório de trabalho
WORKDIR /app
# Copia o package.json
COPY package.json ./
RUN npm install
# Copia o código da aplicação
COPY . .
# Expomos uma porta
EXPOSE 3001
# Comando para iniciar o serviço
CMD ["npm", "start"]
::right::
docker build -t api .
docker run -d -p 3002:3001 api
docker ps
docker stop <container-id>
docker rm <container-id>
docker logs <container-id>
docker exec -it <container-id> /bin/bash
Mas assim como temos arquivos que queremos ignorar no gitignore também seria necessário ignorar na imagem do container, por exemplo:
- .env
- node_modules/
Para isso existe o .dockerignore
ele segue as mesmas regras do .gitignore
.
node_modules
.env
O Docker Compose é uma ferramenta que facilita a definição e o gerenciamento de aplicações multi-container no Docker.
Ele permite que você defina todos os serviços, redes e volumes de sua aplicação em um arquivo YAML (docker-compose.yml).
Vamos utilizar nossa api e criar um docker-compose.yaml
na pasta raiz da api junto ao Dockerfile.
docker-compose up --build // ou down
version: '3.8'
services:
api:
build: .
container_name: api
ports:
- "3000:3000"
environment:
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=postgres
- DB_PASSWORD=masterkey
- DB_NAME=api
depends_on:
- postgres
networks:
- api-network
::right::
postgres:
image: postgres:16
container_name: postgres-db
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: masterkey
POSTGRES_DB: api
ports:
- "5000:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- api-network
networks:
api-network:
driver: bridge
volumes:
postgres-data:
docker --help
docker images
::right::
sudo systemctl start docker
sudo systemctl restart docker
docker-compose restart
docker rm -f $(docker ps -a -q)
docker volume rm $(docker volume ls -q)