Docker-AND-DockerCompose

O arquivo exemplo-docker-compose-postgresql.yml carrega imagem do postgres como base de exemplo.

Importante - ARQUIVO DE EXEMPLO exemplo-docker-compose-postgrtesql.yml

Volumes

/mnt/volume-docker:/var/lib/postgresql/data === no exemplo a pasta da máquina local /mnt/volume-docker tem os mesmos dados da pasta /var/lib/postgresql/data do container.
pg-config:/etc/postgresql ===

DOCKER

inicializar o serviço no Ubuntu == service docker start.

docker images == lista as imagens disponiveis. docker start idContainer == inicia o container que está parado.
docker stop idContainer == para o container selecionado.
docker start idContainer == inicia o container que está parado.
docker ps == lista os containers em atividade.
docker inspect idImage == lista os detalhes da imagem.
docker history idImage == visualiza as camadas da imagem.
docker ps -a == lista todos os containers, incluindo os que estiverem parados.
docker run -d idContainer == flag -d o conainer é executado em segundo plano no terminal.
docker run -P idContainer == mapeia automaticamente as portas do container, com o -P maiúsculo não é possível especificar a porta.
docker run -p portaDaMinhaMaquina:portaContainer idContainer == a flag -p (minúsculo) mapeia de forma específica as portas do container.
docker port idContainer == lista as portas do container.
docker rm idContainer --force == para e exclui um container docker.
docker system prune -a == limpa containeres nao utilizados.
docker volumes prune == remove volumes nao utilizados.
docker rmi <image_id> == serve para excluir uma imagem do disco local.
docker rmi <image_id> == define um nome para o Container.

exemplo de comando para inicializar uma imagem docker Mysql, importante observar o uso do atributo -p indicando a que a porta 3306 do docker também será a porta 3306 do Linux que esta rodando no WSL do Windows.

docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_USER=diogo -e MYSQL_PASSWORD=123 mysql:5.7 == este comando cria um novo container e aporta 3306 do host foi redirecionada para a porta 3306 do container, então quando é acessado http://localhost:3306 é acessado o container na porta 3306. Essa é uma regra de iptables.

Exemplo de container docker com postgres === docker run -v postgres-dados:/var/lib/postgresql/data -p 5432:5432 -e POSTGRES_PASSWORD=123 postgres. Pode-se adicionar a opção -d para rodar em segundo background

iptables -t nat -L -n é possível ver o redirecionamento.

Fazendo build a partir de um Dockerfile

Importante lembrar que para fazer o push da imagem o nome da imagem deve iniciar com o usuario do Docker Hub.
docker build -t nomeDaImagem:1.0 . == gera uma imagem a partir de um arquivo DockerFile, a flag -t é para definir o nome da imagem, e importante notar o . (ponto) ao final do comando, este define onde deve ser executado no caso o . (ponto) é o diretório atual.

Enviar a imagem para o Docker Hub

Para enviar a imagem para o Docker Hub é necessário seguir um a padrão de nomenclatura. A imagem deve iniciar com o nome do usuário usado no Docker Hub. Geralmente as imagens não são criadas seguindo esse padrão, dessa forma existe o comando docker tag para renomear a imagem gerada à partir do Dockerfile. Exemplo abaixo:

docker login -u nomeUsuarioNoDockerHub == faz login no Docker Hub.
docker tag nomeDaImagem usuarioDockerHub/nomeDaImagem == .
docker push nomdeDaImage == envia a imagem para o repositorio do Docker Hub.

Persistindo dados em um container Docker

docker run -it -v caminhaMaquinaLocal:/caminhoDentroDoContainer --- exemplo executado em teste === docker run -it -v D:\volume-docker:/app ubuntu bash == usando bind mounts, onde uma pasta da maquina local é compartilhada com o container Docker. Ou o container pare de funcionar, ou algo do tipo os dados continuam persistidos na máquina local.
docker run -it --mount type=bind,source=D:\volume-docker2,target=/app2 ubuntu bash == exemplo para fazer um bind de uma pasta do host com o container Docker.

Volumes docker

O próprio Docker gerencia os volumes, deixando muito mais seguro o processo de persistência dos dados.

docker volume create NOMEVOLUME === cria um novo volume docker.
docker volume ls === lista os volumes docker disponíveis.
docker volume inspect nomeDoVolume === exibe os detalhes do volume selecionado.
docker run -it -v nomdeDoVolume:/pastaNoContainer nomeContainer bash === exemplo de uso de volume em um container docker.

docker exec -it meu_container bash
Esse comando irá executar um o bash que é nosso console no linux. A flag -i permite mapear a entrada do teclado para o bashs e -t reserva o terminal.

Redes no Docker

Com o comando docker inspect idContainer no final é possível ver a rede do docker, o nome da rede e o endereço ip do container.

O Docker possue a rede host, ao usar essa rede é retirado o isolamento entre o Container e a máquina local, dessa forma sendo acessado os recursos do Docker diretamente via localhost, e também possue a rede none na qual o container fica sem uma interface de rede.

docker network ls === lista as redes Docker.
docker network create --driver bridge nomeDaRede === comando para criar uma rede no Docker.

Comunicação através de redes Docker

Abaixo o primeiro comando tem um servidor de um banco de dados mongo, este ficará responsável por disponibilizar os dados para uma aplicação, representada pelo segundo comando. A falg --name é de fundamental importância pois define o nome do host do banco de dados.

docker run -d --network nomeDaRede --name meu-mongo mongo:4.4.6 === cria o container com o banco de dados mongo.
docker run -d --network nomeDaRede --name nomeDoContainer -p 3000:3000 === máquina com a aplicação backend que irá fazer uso do banco de dados mongo do container definido pelo nome de meu-mongo.

DOCKER-COMPOSE

Ferramenta de coordenação de containers. Nos auxilia a compor diversos containers através de um único arquivo

Configurado atraves de um arquivo YAML tem a capacidade de rodar varios containers, sem a necessidade de subir cada container manualmente.

YAML (uma sigla que significa YAML Ain’t Markup Language) não é propriamente uma linguagem de programação mas sim uma sintaxe para a criação de ficheiros de configuração. A estrutura do YAML é determinada pela sua indentação, sendo a indentação definida pelo numero de espaços no inicio da cada linha e podem ser zero, dois ou múltiplos de dois. A estrutura de cada bloco é constituída por níveis, sendo que o nível anterior é considerado parent e o inferior children. O caracter - indica o inicio de uma listagem de variaveis ou atributos que se encontram ao mesmo nível, e que deve ser considerado na contagem de espaços na indentação. Em YAML os comentários são indicados pelo caracter #. Se o comentário estiver entre dois blocos de código deve ser escrito sem espaços à esquerda, se for escrito após uma linha de código deve sempre ser precedido de um espaço ou de uma ou mais tabulações para que os comentários fiquem alinhados.

docker-compose up === subindo os containers que estiverem no arquivo .yml da pasta onde o comando foi executado.
docker-compose -f <nomdeDoArquivo.yml> up === subindo os containers com um único comando.

Erro ao inicializar Docker no WSL

failed to start daemon: Error initializing network controller: error obtaining controller instance: unable to add return rule in DOCKER-ISOLATION-STAGE-1 chain: (iptables failed: iptables --wait -A DOCKER-ISOLATION-STAGE-1 -j RETURN: iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or directory): rule in chain DOCKER-ISOLATION-STAGE-1 (exit status 4))

Solução

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy