Docker é software container engine. Há orquestradores de Container, de arquitetura distribuída, como o Kubernetes. Containers são pequenos pacotes de software, isolados, leves e fáceis de movimentar, diferenciando-se de VM. São baseados em Imagens que possuem camadas, que podem ser compartilhadas. Descartam pré configuração de ambiente físico. Além disso, ocasionam deploy mais ágil, facilitam escalabilidade, previnem erros e causam economia, sendo ideais para cloud e microservices. Os namespaces isolam os containers, cgroups limitam acesso a recursos de hardware da máquina host e union mounting criam camadas no sistema de arquivos, que podem ser compartilhadas nos demais containers, reduzindo uso de recursos. O repositório oficial do Docker é o docker hub, composto de inúmeras imagens. O Docker fica salvo no diretório /etc/. A rede do Docker fica do 172.17.0.2 até 172.17.0.254 (172.17.0.1 é o host docker). Passo a passo oficial para instalação do Docker pode ser encontrado no site oficial.
Pacote com dados para construção do container (configurações, libraries, variáveis, arquivos, etc). Possui conceito de camadas, onde, por exemplo, imagem PHP é baseada em imagem Apache, que é baseada em imagem Debian. O passo a passo de criação de uma imagem é um arquivo chamado Dockerfile. Entrypoint são scripts que o container executa prévio à sua instalação, como receber variáveis de ambiente, geralmente pré solicitadas na construção de containers.
Dockerfile (constrói)-> Imagem (constrói)-> container
Arquivo de nome Dockerfile, com configurações da Imagem, para sua construção. Facilmente compartilhado e pode ser registrado no Docker Hub. Registry é um repositório de imagens (ex: docker hub). Para subir imagens (push), é necessário login no docker hub, com comando docker login.
MODELO/SINTAXE:
FROM nomeImagens:versaoImagens
ENV variaveisAmbiente=valor
EXPOSE portasUtilizadas (Somente documentação, precisa ser informada na execução do container)
RUN comandos (executa comandos durante a criação da imagem)
COPY diretorioOrigem diretorioDestino (copiar código do diretório do dockerfile para diretório destino do container)
WORKDIR diretorioPadrao (Diretório padrão ao entrar no container, onde todos os comandos serão originados, como Bash)
CMD comandos (comando padrão ao executar imagem)
EXEMPLO:
FROM alpine
ENV DB_HOST=172.17.0.4
EXPOSE 5000
RUN apk add py3-pip
COPY * /opt/app
RUN pip3 install -r /opt/app/arquivoRequirements.txt
WORKDIR /opt/app
CMD flask run --host 0.0.0.0
IMAGEM
Sintaxe nomeImagem: usuario/nomeImagem:versaoImagem (versão padrão é latest)
Baixar imagem: docker pull nomeImagem (push sobe imagem)
Ver imagens: docker image ls
Construir Imagem: docker build -t nomeImagem:opcionalInfo -f caminho/nomeDockerFile .
Ex: docker build -t mysql-image -f api/db/Dockerfile .
Remover imagem: docker image rm nomeImagem (-f para imagens com containers existentes)
Criar apelido para imagem: docker image tag nomeAtual novoAlternativo
CONTAINER
Ver Containers em execução: docker ps (-a mostra todos containers)
Criar Container: docker run -dt nomeImagem (se não houver container, baixará e criará)
Ex: docker run -dt ubuntu
Ver informações do container: docker inspect idContainer (inserir para filtro: '| grep termoPesquisa')
Criar container com variáveis: docker run -dt --name banco -e MYSQL_PASSWORD=abc -e MYSQL_USER=fulano mariadb
Entrar comandos em container em execução: docker exec -ti idContainer bash
Sair do container: exit ou 'ctrl+d' ('ctrl+p+q' sai do shell sem encerrar container)
Iniciar container: docker start idContainer (stop para)
Pausar container: docker pause idContainer (unpause retoma)
Ver status do container: docker stats idContainer
Ver processos do container: docker top idContainer
Ver logs do container: docker logs idContainer
Remover container parado: docker rm idContainer (-f para em execução, excluir manterá imagens)
Remover todos containers: docker rm -f $(docker ps -qa) (-q é quit, mostra somente id's dos containers)
Criar rede em container: docker network create nomeRede
Listar redes: docker network ls
Conectar container a rede: doker network connect nomeRede idContainer (disconnect para desconectar)
Remover todos containers, imagens e redes parados: docker system prune
Remover todos containers parados: docker container prume ('images' para imagens, 'volume' para volumes)
PARÂMETROS:
-f: especifica dockerfile
-d: Executar Container em background
-t: tag
-i: Execução de comando em modo interativo, como um shell
-ti: TTY, utilizar emulador de Terminal
--rm: Sobrescreve Container com novo, caso já exista antigo similar
-e: Environment/Entrypoint, especificar variáveis prévias de configurações
-v: Volume
-p: Especifica porta no Container estará exposta para porta do host (pHostDocker:pContainer)
Ponto no final: Especifica diretório atual
$(pwd): Especifica caminho do diretório atual
Exemplo prático:
1. docker run -dt --name banco -e MYSQL_USER=fulano -v dados:/var/lib/mysql -p 3306:3306 mariadb
2. docker exec -ti banco bash
Local/pasta onde ficam os dados do container, que podem ser transferidos, além do ciclo de seu vida (Ex: Dados de BD, códigos e arquivos, etc), e compartilhados com demais containers (Ao adicionar container, muda-se a porta do host docker. Cada container funciona em uma porta). Pode ser diretório local ou externo. Um Volume pode ser usado por 1 ou mais Containers. Por padrão, Volumes no Docker ficam em '/var/lib/docker/volumes/'. Para alterar o diretório padrão, basta, ao criar Container, trocar o nome do Volume pelo seu novo diretório (docker container run --name db -v /outro/diretorio/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql).
Criar Volume: docker volume create nomeVolume
Listar Volumes: docker volume ls
Ver dados do Volume: docker volume inspect nomeVolume
Remover Volume: docker volume rm nomeVolume
Volume em container: docker run -dt --name nomeContainer -v nomeVolume:/localDeDados/dentroDoContainer/ nomeImagem
Volume personalizado ao host docker: docker run -dt --name nomeContainer -v /localDeDados/dentroDoHostDocker:/localDeDados/dentroDoContainer/ nomeImagem (Salvará dados dentro de pasta personalizada)
EXEMPLO 1 (Volume padrão):
1. Criar Volume: docker volume create meuVolume
2. Criar Container com Volume: docker run -dti --name meuContainerComVolume -v meuVolume:/home/ alpine
3. Entrar no Container: docker exec -ti meuContainerComVolume sh
4. Dentro do Container, criar coisas em /home/: touch /home/arquivo1 /home/arquivo2 /home/arquivo3
5. Sair do Container: (Ctrl+d ou exit)
6. Verificar diretório de Volumes Docker: ls /var/lib/docker/volumes/
7. Acessar Volume: cd /var/lib/docker/volumes/meuVolume/_data
8. Ver conteúdo do Volume: ls (Mostrará os arquivos criados anteiormente dentro do Container)
EXEMPLO 2 (Volume personalizado):
1. Criar Container com Volume personalizado: docker run -dti --name meuContainerComVolume2 -v /home/:/tmp/ alpine
3. Entrar no Container: docker exec -ti meuContainerComVolume2 sh
4. Dentro do Container, criar coisas em /tmp/: touch /tmp/arquivo1 /tmp/arquivo2 /tmp/arquivo3
5. Sair do Container: (Ctrl+d ou exit)
6. Verificar diretório de Volume personalizado: ls /tmp/ (Mostrará os arquivos criados anteiormente dentro do Container)
Ambiente para Windows 10, com MySQL, Nodejs e Php. E usuários com MacOS e Linux.
O uso de CPU será proporcional à quantidade de containers presentes, com relação ao percentual da soma de CPU entre os mesmos. Ex: 3 containers, abc com 1024 (50%), def com 512 (25%) e ghi com 512 (50%). Cada unitário desses valores será 1 cpu-shares. Ex: container abc possui 1024 cpu-shares.
Alterar limite de memória do container (parado): docker run -ti -m 512m --name nomeContainer debian (512 MegaBytes)
Alterar limite de memória do container (execução): docker update -m 256m idContainer
Alterar limite de CPU do container (parado): docker run -ti --cpu-shares 1024 --name nomeContainer debian
Alterar limite de CPU do container (execução): docker update --cpu-shares 512 idContainer
Arquivo do tipo yaml chamado 'docker-compose.yml', contendo composto (infraestrutura IAC) de configurações para automatização docker e comunicação entre containers (via nome estabelecido) e volumes, podendo haver versionamento e, com isso, melhor organização.
Estrutura:
Exemplo 1 docker-compose.yml:
version: "3.7"
services:
app:
image: node:12-alpine
container_name: containerNode
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: senhaMySQL
MYSQL_DB: nomeBD
restart: always
mysql:
image: mysql:5.7
container_name: containerBD
volumes:
- volumeDockerCompose:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: senhaMySQL
MYSQL_DATABASE: nomeBD
expose:
- "5000"
restart: always
depends_on:
- app
volumes:
volumeDockerCompose: {}
COMANDOS DOCKER-COMPOSE:
Versão docker-compose: docker-compose version
Executar containers do docker-compose: docker-compose up (-d executa em background, build ao invés de up somente fará build das Imagens, -f seguido do diretório especificará o local e nome de arquivo do docker-compose.yml)
Listar containers via docker-compose: docker-compose ps
Listar logs de container no docker-compose: docker-compose logs -f nomeContainer
Parar docker-compose/containers: docker-compose stop (Ou down, para parar e remover container e componentes, start inicia e restart reinicia)
Entrar em container via docker-compose: docker-compose exec nomeContainer bash
Aumentar réplicas de container: docker-compose scale
(Pode-se, dentro, citar outros containers pelos nomes personalizados)
Exemplo 2 docker-compose.yml:
# Criar 2 containers, um servidor com nginx e um cliente debian, que acessará o servidor nginx
version: '3'
services:
nginx:
image: nginx:latest
container_name: servidor_nginx
ports:
- "8080:80"
networks:
- rede
command: ["bash", "-c", "echo '<h1>Aplicação web</h1>' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'; sleep infinity"]
debian:
image: debian:latest
container_name: cliente_debian
networks:
- rede
command: ["bash", "-c", "apt update; apt install -y curl; sleep infinity;"]
networks:
rede:
driver: bridge
# 1. Executar ambiente: docker-compose up -d
# 2. Acessar container cliente: docker exec -it cliente_debian bash
# 3. Via container cliente, acessar container servidor: curl http://servidor_nginx
Elaborado por Mateus Schwede
ubsocial.github.io