O Docker é uma ferramenta Open Source que utiliza a tecnologia de containers, mantida pela empresa Docker Inc. Ela é projetada para auxiliar desenvolvedores e administradores de sistemas, permitindo a criação, implantação e testes de aplicações de forma rápida, simples e utilizando poucos recursos.
Simplificando, ele é uma alternativa a virtualização, sendo mais ágil e menos pesada, pois ao invés de criar um sistema virtual completo, com todos os recursos de uma máquina física (Xen, VMWare, VirtualBox, etc), o Docker utiliza os mesmos recursos da máquina hospedeira, como: kernel, bibliotecas, etc…
O Docker foi baseado no LXC (Linux Containers), que são pacotes que permitem rodar diferentes sistemas isolados em um único sistema operacional real, utilizando o mínimo necessário para seu funcionamento. Sendo possível implantar e escalonar em qualquer ambiente, aumentando o desempenho e reduzindo o tamanho da aplicação.
Grandes empresas de tecnologia como Google, Amazon, Netflix, Spotify e até mesmo a Microsoft, vem utilizando essa tecnologia, substituindo a virtualização.
Comparando a utilização de máquinas virtuais e containers nos ambientes de produção, podemos definir que as máquinas virtuais simulam o hardware, enquanto os containers simulam o software, mas precisamente uma aplicação (wordpress, python, apache, postgresql, etc).
Benefícios:
O Docker está disponível em 2 edições: CE (Community Edition) e EE (Enterprise Edition).
Docker CE: Plataforma grátis, ideal para iniciantes no Docker e para pequenos desenvolvedores;
Docker EE: Plataforma empresarial com assinatura e suporte, ideal para grandes empresas que desenvolvem aplicações críticas;
O Docker pode ser instalado em diversos sistemas Linux como CentOS, Debian, Fedora e Ubuntu, também está disponível versões para Windows e MacOS. Para nossos exemplos utilizaremos o Debian 9. Podemos adicionar o repositório para a distribuição e usar os passos abaixo para fazer a instalação:
# apt -y install apt-transport-https curl gnupg2 software-properties-common
# curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian stretch stable"
# apt update && apt -y install docker-ce
Também podemos baixar a versão mais atual, diretamente da empresa que desenvolve o Docker (precisa do curl instalado). Desta forma funcionará em qualquer distribuição. Para isso, digitamos o seguinte comando:
# curl -fsSl https://get.docker.com | bash
Após a finalização do script, o Docker já está pronto para ser utilizado, podemos verificar a versão com o comando:
# docker ––version
Vamos utilizar o usuário root para gerenciar o Docker, caso esteja utilizando um usuário comum e não queira usar sudo para cada comando, pode adicionar o seu usuário ao grupo docker:
# sudo usermod -aG docker $(whoami)
O Docker adiciona uma interface Bridge (docker0) no host hospedeiro. É através desta interface, que os containers se comunicam e também é feita o redirecionamento de portas para acesso aos aplicativos.
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 64:32:a8:81:59:f2 brd ff:ff:ff:ff:ff:ff
altname wlp0s20f3
inet 192.168.68.108/24 brd 192.168.68.255 scope global dynamic noprefixroute wlo1
valid_lft 69604sec preferred_lft 69604sec
inet6 fe80::3da3:abe2:ab45:c3ef/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:07:9b:a3:aa brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7ff:fe9b:a3aa/64 scope link
valid_lft forever preferred_lft forever
O Docker possui um repositório com diversas imagens de aplicações, tanto as oficiais como criadas por usuários, permitindo o seu compartilhamento. Esse repositório é o Docker Hub, vamos precisar baixar localmente essas imagens para criarmos nossos containers. Abaixo temos alguns comando úteis na criação e manipulação de imagens:
O comando docker searc
h irá pesquisar na base de dados do Docker Hub:
# docker search debian
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… 11681 [OK]
debian Debian is a Linux distribution that's compos… 3699 [OK]
arm32v7/debian Debian is a Linux distribution that's compos… 70
itscaro/debian-ssh debian:jessie 28 [OK]
O comando “docker pull” irá preparar o download da imagem escolhida do Docker Hub, deixando disponível localmente:
# docker pull debian
Using default tag: latest
latest: Pulling from library/debian
6c33745f49b4: Pull complete
Digest: sha256:22d4552b9f96fd0ea943cb846d58b069d4df297673636055a3d984b3ccac6a28
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest
Na criação de imagens podemos definir um versionamento, quando formos baixá-la basta especificar qual versão deseja através do parâmetro :<versão>. Abaixo um exemplo baixando a versão 5 do CentOS:
# docker pull centos:5
5: Pulling from library/centos
38892065247a: Pull complete
Digest: sha256:70fffd687ff9545662c30f9043108489c698662861cd5f76070f7e2cd350564f
Status: Downloaded newer image for centos:5
docker.io/library/centos:5
O comando docker images ls
ou somente docker images
lista as imagens disponíveis localmente, exibindo algumas informações importantes, são elas:
REPOSITORY: Nome definido para imagem.
TAG: Utilizado para versionamento da imagem.
IMAGE ID: Identificação da imagem no Docker.
CREATED: Tempo de criação da imagem.
SIZE: Tamanho que a imagem ocupa no disco.
# docker images ls
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 6d6b00c22231 3 weeks ago 114MB
java 11 51ab01914c65 7 weeks ago 255MB
centos 5 1ae98b2c895d 4 years ago 285MB
O comando docker image inspect
ou somente docker inspect
trás mais informações detalhadas relacionadas a imagem, como autor, variáveis de sistema, comando executado, entre outras:
# docker image inspect centos:5
# docker inspect centos:5
O comando docker image tag
ou somente docker tag
permite alterar o nome de uma imagem e a versão. Precisamos passar os parâmetros <image id>
e <repository>:<versão>
. O comando irá criar uma nova imagem baseada na original:
# docker image tag 1ae98b2c895d centos:5.4
# docker tag 1ae98b2c895d centos:5.4
ou
# docker image tag centos:5.4 novonome:1.0
# docker tag centos:5.4 novonome:1.0
O comando docker image rm
ou somente docker rmi
remove uma imagem baixada anteriormente. Precisamos passar como parâmetro repository
ou image id
:
# docker image rm 6d83de432e98
# docker rmi 6d83de432e98
Caso a imagem esteja associada a outra, ou exista um container que é baseado nela, será preciso utilizar o parâmetro -f
para forçar a remoção:
# docker image rm -f 1ae98b2c895d
# docker rmi -f 1ae98b2c895d
Untagged: centos:5
Untagged: centos@sha256:70fffd687ff9545662c30f9043108489c698662861cd5f76070f7e2cd350564f
Deleted: sha256:1ae98b2c895d1ceeba8913ff79f422f005b7f967a311da520a88ac89180b4c39
Deleted: sha256:5513565ec546b4249cb76fec6551253c611d6ee80184807324c5c4335e4a2964
O comando docker image save
ou somente docker save
salva a imagem no disco com o formato tar. Precisamos passar como parâmetro repository
ou image id
, e também o caminho -o </caminho/arquivo.tar>
:
# docker image save debian -o ~/debian.tar
# docker save debian -o ~/debian.tar
# ls -lh ~
total 134M
-rw------- 1 cesar cesar 114M jan 2 18:32 debian.tar
O comando docker image load
ou somente docker load
carrega o arquivo para as imagens do Docker. Precisamos passar o parâmetro -i </caminho/arquivo.tar>
:
# docker image load -i ~/debian.tar
# docker load -i ~/debian.tar
Para começarmos a trabalhar com containers vamos utilizar o comando “docker run”. Para iniciar, vamos utilizar a imagem hello-world do repositório do Docker Hub, que trará uma mensagem de Hello e algumas informações. Caso a imagem não exista localmente, ele irá baixá-la:
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
# docker run debian /bin/echo "Bem-vindo ao Docker"
Bem-vindo ao Docker
Para podermos criar um container acessando o console, temos que passar os parâmetros -t
(terminal) e -i
(interatividade) junto com o comando docker run
.
# docker run -it centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
[root@76edfe69d86a /]#
Após criar o container já iremos cair direto no console, podemos ver que o usuário padrão é root e o nome do host é o container id.
Ao sair do console com exit, o container será finalizado. Para que ele continue executando, saia do console com CTRL + P, CTRL + Q, assim ele continuará em segundo plano.
O comando docker container ls
ou somente docker ps
lista os containers que estão em execução, exibindo algumas informações, são elas:
CONTAINER ID: Identificação do container no docker.
IMAGE: Imagem utilizada na criação do container.
COMMAND: Comando executado dentro do container.
CREATED: Tempo de criação do container.
STATUS: Status atual do container (Execução, pausado, etc).
PORTS: Portas utilizadas no container e se tem direcionamento de porta com o host hospedeiro.
NAMES: Nome do container (quando não é definido um nome o docker seleciona um aleatório).
# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76edfe69d86a centos "/bin/bash" About a minute ago Up 56 seconds sad_bose
ou
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76edfe69d86a centos "/bin/bash" About a minute ago Up 56 seconds sad_bose
O parâmetro --name
é utilizado para definir um nome para o container:
# docker container run -ti --name teste debian
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4458c3a9806 debian "bash" 8 seconds ago Up 8 seconds teste
O comando docker container create
ou somente docker create
cria um container sem iniciá-lo:
# docker create --name ubu ubuntu
b70a310eb6dbf840864df3afca26b0e09720ecdac7debda695657bd4218a0fcd
ou
# docker container create --name ubu ubuntu
b70a310eb6dbf840864df3afca26b0e09720ecdac7debda695657bd4218a0fcd
Durante a manipulação dos containers, vários são criados e finalizamos, mas não excluídos. Para visualizá-los execute o comando docker container ls
com o parâmetro -a
:
# docker container ls -a
ou
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b70a310eb6db ubuntu "/bin/bash" About a minute ago Created ubu
b4458c3a9806 debian "bash" 4 minutes ago Exited (130) 3 minutes ago teste
45db32663556 debian "bash" 4 minutes ago Exited (130) 4 minutes ago blissful_feistel
76edfe69d86a centos "/bin/bash" 7 minutes ago Exited (0) 4 minutes ago sad_bose
d5e46c091716 debian "/bin/echo 'Bem-vind…" 8 minutes ago Exited (0) 8 minutes ago distracted_galileo
8154bcf02123 hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago condescending_ellis
7cfe02e2ab06 java:11 "sh" 7 weeks ago Exited (137) 7 weeks ago frosty_torvalds
67a99cc3d75b java:11 "sh" 7 weeks ago Exited (0) 7 weeks ago strange_dirac
ca44ee5edcab 994d899f58bf "sh" 7 weeks ago Exited (0) 7 weeks ago tender_matsumoto
O comando docker container prune
irá remover todos os containers que estão parados. Cuidado!!! Será solicitado confirmação e ao confirmar, não conseguirá desfazer o processo:
# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
b70a310eb6dbf840864df3afca26b0e09720ecdac7debda695657bd4218a0fcd
b4458c3a9806de465faf08a0175b46f467a753783593e3ec53d28e6f65e683cf
45db32663556587d107d490cd7a0c67d1447947458af003c810e64a682560cf3
76edfe69d86ad3078b5cfc914034d0d3eecec5d50e34f5299426c54d34edf6a3
d5e46c0917164931f433e0009afd1611ac5280d0ff5fa7b33662aecea2a3e891
8154bcf02123e4c21444accdf81a1c19d95e37976cecf0ca9753f937f07045eb
7cfe02e2ab060a50c1a2906add4790d731a2f44454607498c67763baf53cfce6
67a99cc3d75b1560cf445395e34e05525adbc8858736ca31d4977a86fb316054
ca44ee5edcab9144a845501ec504ce04d158cab927a8d5863fa6b002d2fb4ccf
Total reclaimed space: 32B
Podemos utilizar o parâmetro --rm
, para criar containers que serão destruídos ao sairmos da sessão:
# docker run --rm -it ––name testando debian
O comando docker container start
ou somente docker start
inicia um container parado. Precisamos passar como parâmetro o <nome>
ou o <container id>
:
# docker container start teste
# docker start f162d3a30804
O comando docker container stop
ou somente docker stop
interrompe um container ativo. Precisamos passar como parâmetro o <nome>
ou <container id>
:
# docker container stop 8a6c279623fb
# docker stop suspicious_jepsen
O comando docker container pause
ou somente docker pause
interromper temporariamente um container. Precisamos passar como parâmetro o ou o :
# docker container pause teste
ou
# docker pause c07c68aa29f7
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c07c68aa29f7 debian "bash" About a minute ago Up 29 seconds (Paused) teste
O comando docker container unpause
ou somente docker unpause
retira a pausa do container. Precisamos passar como parâmetro o <nome>
ou o <container id>
:
# docker container unpause teste
ou
# docker unpause c07c68aa29f7
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c07c68aa29f7 debian "bash" 4 minutes ago Up 3 minutes teste
O comando docker container exec
ou somente docker exec
executa comandos dentro de um container em execução. Precisamos passar como parâmetro o <nome>
ou o <container id>
, seguido do comando desejado:
# docker container exec teste apt update && apt -y install apache2
ou
# docker exec teste apt update && apt -y install apache2
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Hit:1 http://security.debian.org/debian-security buster/updates InRelease
Hit:2 http://deb.debian.org/debian buster InRelease
Hit:3 http://deb.debian.org/debian buster-updates InRelease
Reading package lists...
Building dependency tree...
Reading state information...
...
Após criar um container e instalar programas, mudar configurações, você pode querer replicar estas alterações em outros containers, assim, precisamos salvar estas alterações como uma imagem. Para isso, utilizamos o comando docker commit
e passamos como parâmetros o <container>
e depois o <novo repository>
:
# docker commit webapp nginx-webapp
O comando docker container attach
ou somente docker attach
é utilizado para acessar o console de um container que está em execução em segundo plano. Precisamos passar como parâmetro o <nome>
ou <container id>
:
# docker container attach teste
ou
# docker attach c07c68aa29f7
root@c07c68aa29f7:/#
O comando docker container rm ou docker rm é utilizado para remover um container. Precisamos passar como parâmetro o <nome>
ou <container id>
:
# docker container rm c07c68aa29f7
ou
# docker rm c07c68aa29f7
Error response from daemon: You cannot remove a running container c07c68aa29f7ca919a0bb9e69be762fc99169fad58682563ba87c5dd389569eb. Stop the container before attempting removal or force remove
Caso o container esteja em execução, será preciso utilizar a opção -f para forçar:
# docker container rm -f c07c68aa29f7
ou
# docker rm -f c07c68aa29f7
c07c68aa29f7
Para deixar um container em background, precisamos passar o parâmetro -d na criação do container. Entretanto, para que funcione corretamente, o container precisa de um aplicativo rodando, por exemplo um servidor web:
# docker container run -d --name web httpd
2f42ceb3af7b0aa3f77d2996975f99c940e8001a4db87b077c660186314bea52
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5019c5b80b5d httpd "httpd-foreground" 2 seconds ago Up 2 seconds 80/tcp web
Para que um container fique sempre em execução, mesmo quando o host hospedeiro for reiniciado, utilizamos o parâmetro --restart=always
:
# docker run -d --restart=always --name webserver httpd
82b8673bc16cc2ef6ab726c66f4a376335e02e82aee6676e8bf01e764998e322
Quando trabalhamos com containers de aplicativos, precisamos que os usuários acrescentem arquivos aos projetos que estão trabalhando (ex. webserver), mas o ideal é não dar acesso direto via ssh nesse container, então, podemos adicionar volumes que são acessados pelo host hospedeiro. Abaixo temos alguns exemplos de utilização:
Para definir um volume utilizamos o parâmetro -v seguido do <nome do volume>
. O container acrescentará a partição mapeada /volume ao sistema de arquivos do container. Os volumes geralmente ficam na pasta /var/lib/docker/volumes.
# docker run -ti -v /volume ––name files ubuntu
Podemos especificar um diretório que servirá de volume para o container, usando a opção -v <dir no host>:<volume no container>
:
# mkdir -p ~/volumes/www
# echo 'echo $(hostname)' > ~/volume/data/host.sh
# docker run -d -v ~/volume/www:/usr/local/apache2/htdocs/ --name www httpd
Podemos criar um container que tem como objetivo servir como um volume que poderá ser compartilhado entre os outros containers. Ele é um container que não fica em execução, abaixo temos um exemplo:
# mkdir -p ~/volume/data
# docker create -v ~/volume/data:/data --name dados centos:6
Criaremos dois containers que irão mapear o nosso container de volume criado anteriormente (dados), para testar se ambos acessam o mesmo volume, iremos criar um script para exibir o hostname (container id) de cada um deles. Execute os comandos abaixo:
# echo 'echo $(hostname)' > ~/volume/data/host.sh
# docker run -d --name ubuntu --volumes-from dados ubuntu bash -c "while true; do sleep 1; done"
d779c53d78011306e1d2e6bc7767a13306791c9b06570912325f8d221b6ca03a
# docker run -d --name centos --volumes-from dados centos bash -c "while true; do sleep 1; done"
82868f52eb05295a1bdaaea70134792abd939d146faf4558831b360781a87465
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82868f52eb05 centos "bash -c 'while true…" 9 seconds ago Up 8 seconds centos
d779c53d7801 ubuntu "bash -c 'while true…" 17 seconds ago Up 16 seconds ubuntu
e545b3cb8cea centos:6 "/bin/bash" 54 seconds ago Created dados
# docker exec ubuntu sh /data/host.sh
d779c53d7801
# docker exec centos sh /data/host.sh
82868f52eb05
Para mais informações sobre Docker e Containers, veja as referências utilizadas abaixo:
https://docs.docker.com
https://linuxcontainers.org
https://www.howtoforge.com/tutorial/how-to-use-docker-introduction
https://www.server-world.info/en/note?os=Debian_9&p=docker&f=1
https://youtube.com/user/linuxtipscanal
Se una com os assinantes de nossa Newsletter, sempre que tiver postagem nova você será notificado.