Docker
Porque Docker?
Imagine que você está desenvolvendo uma aplicação que roda alguns diferentes serviços:
- Web Server in Node
- Database in MySQL
Você quer enviar sua aplicação para alguém testar. Para isso, você precisa entregar o código fonte. Vamos criar uma pessoa chamada Mark :older_man:.
O primeiro problema é que Mark não sabe instalar e rodar aplicações. Então você vai precisar ir até a casa dele e instalar para ele.
Outro problema é que é difícil instalar algumas dependências no computador de Mark, porque ele está usando um sistema operacional diferente do seu. Ok, você teve dificuldades mas está tudo pronto: vamos rodar a aplicação.
Oh não! Você vê alguns erros aparecendo no console. Isso se deve à problemas de incompatibilidade entre as dependências que você está usando e os serviços que você instalou. Você instalou a última versão dos serviços no computador de Mark, mas no seu próprio computador foi utilizado mais antigas, porque você vem desenvolvendo essa aplicação tem um tempo.
:older_man: | You | |
---|---|---|
OS | Windows | Linux |
Node | 15 | 14 |
MySQL | 8 | 5.7 |
E não é só sobre as versões. Algumas dependências que você está usando no seu próprio computador não existem no sistema operacional de Mark.
Uau, que bagunça. O que você faz? Você não pode prever todos esses problemas enquanto está desenvolvendo. E isso não é um caso isolado, acontece muito. Mas como lidar com essas situações?
...
Traga a pessoa até a sua casa para mostrar! Nunca ouviu a frase "No meu computador funciona"?
Brincadeira. Docker é a resposta! (Mas você provavelmente sabia que eu diria isso em algum momento)
Para resumir, docker resolve os seguintes problemas:
- incompatibilidades
- tempo de configuração longa e difícil
- ambientes de desenvolvimento e teste diferentes
O que é Docker?
Simplificando, docker é um software que permite separar suas aplicações da infraestrutura, rodando cada serviço com suas próprias dependências em containers separados.
Images
Image é como uma receita que te dá instruções para criar um docker container.
Images podem ser baseadas em outra image, com algumas configurações adicionais. Usando o exemplo dado acima, vamos assumir que seu sistema operacional é um ubuntu
. Você pode criar uma imagem baseada no ```ubuntu`` e instalar Node e MySQL nele para rodar sua aplicação.
Dockerfile
Dockerfile é um arquivo com sintaxe simples que define os passos necessários para criar a image e rodar.
Example
FROM node:15-alpine
WORKDIR /var/www
COPY *.json .
COPY *.lock .
RUN yarn
COPY . . # add node_modules no .dockerignore
CMD ['yarn', 'start']
Cada instrução cria uma layer:
FROM
cria uma layer da image node:15-alpine.COPY
adiciona arquivos do seu diretório atual do Docker.RUN
builda sua aplicação com yarn.CMD
especifica que comando rodar dentro do container.
MySQL depois será adicionado no arquivo de docker_compose
Container
Container é uma instância de uma image executando.
Por padrão, um container é relativamente bem isolado de outros containers, mas isso pode ser alterado.
Um container é definido por sua image e qualquer opção de configuração adicional que você configure antes de criá-lo ou iniciá-lo.
Docker registry
Guarda Docker images. Frequentemente você puxa imagens do repositório, mas você também pode upar sua própria image e então a comunidade poderá ter acesso a ele.
Docker Hub
É um registry de images.
Comandos
docker run {image:tag}
Roda um container a partir de uma image
image
pode ser qualquer image que você quiser, comoubuntu
oumysql
tag
é onde você especifica a versão da image, comolatest
ou4.0.1
. Se você não especificar nenhuma tag, docker vai pegar a latest (mais atual)
Docker primeiro vai procurar a image localmente. Se a image não foir encontrada, ele vai procurar no Docker Hub.
docker run -i {image:tag}
Roda um container em modo interativo. Isso significa que você pode prover input para o container que está rodando.
docker run -t {image:tag}
Roda um container printando a saída da instancia.
docker run -it {image:tag}
É uma combinação de rodar um container em modo interativo e mostrar o input do terminal
docker run -p {host_port:doccker_port} {image:tag}
Se você quiser ter acesso à sua aplicação em um browser, por exemplo, que está rodando em um container, você tem que mapear a porte que você está usando dentro do container para a porta do docker host.
Então, você pode acessar usando o IP do Docker Host, e a host_port
que você selecionou.
docker run -v {outside_container: inside_container} {image:tag}
Vamos supor que você está rodando um banco de dados, e você precisa guardar os dados, mesmo se o container for deletado.
Se você quiser guardar os dados, você precisa mapear um diretório fora do container no docker host, para um diretório dentro do container.
docker volume create {volume_name}
Cria um volume
docker run -e {ENVIRONMENT_VARIABLE=value} {image:tag}
Configura um valor para uma variável de ambiente aceita pelo container.
Para ver as variáveis de ambiente disponíveis, você tem que rodar o comando inspect
, e na sessão de Config está uma lista das variáveis de ambiente.
docker ps
Lista todos os containers rodando.
docker ps -a
Lista todos os containers, rodando ou não.
docker inspect {container}
Lista todos os detalhes de um container em formato JSON.
docker logs {container}
Mostra o output advindo da aplicação rodando em um container
docker stop {container}
Para um container executando
container
pode ser o nome do container, ou seu IP
Você não precisa digitar aquele número enorme do IP do container. Os primeiros 4 números são suficientes
docker rm {container}
Remove o container permanentemente
docker images
Lista todas as images e seus tamanhos
docker rmi {image}
Remove uma imagem
Você precisa garantir que não tem nenhum container rodando usando aquela image. Você deve parar e deletar todos os containers usando aquela image antes de deletá-la
docker pull {image}
Apenas faz download da image, sem rodar um container.
docker build Dockerfile -t {tag_name}
Crea uma image baseada em um Dockerfile. A tag -t
é para prover uma tag_name para a image.
docker push {tag_name}
Sobe uma imagem criada para o Docker Hub
docker run --link {name_container:host_name} {image:tag}
Faz um link entre dois containers
docker run --cpu={number} {image:tag}
Limita o uso da CPU por um container
{number}
é um número decimal entre 0 e 1, por exemplo .5.
docker run --memory={number}m {image:tag}
Limita o uso da memória por um container
{number}
é qualquer número, dado em megabytes
Docker Compose
Para rodar vários serviços de uma vez, Docker te permite escrever um arquivo docker-compose.yml
onde você cria configurações para as images que você quer rodar.
docker-compose up
Roda as imagens descritas no docker compose.
Aqui está um exemplo do conteúdo de um docker-compose.yml
version: 3
services:
app:
container_name: app
command: sh -c "yarn && yarn start"
build:
context: .
dockerfile: dockerfile
volumes:
- .:var/www
ports:
- 3333:3333
depends_on:
- db
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
volumes:
db_data: