Como usar o comando docker run para gerenciar contêineres

DockerBeginner
Pratique Agora

Introdução

Neste laboratório, você obterá experiência prática usando o comando docker container run para gerenciar contêineres de forma eficaz. Você aprenderá como executar contêineres em modo detached (desanexado) para execução em segundo plano e atribuir nomes personalizados para facilitar a identificação.

Além disso, você explorará como se conectar a contêineres em execução, mantendo o STDIN aberto, publicar portas de contêiner para o host para acesso externo, montar volumes para garantir a persistência de dados e configurar contêineres definindo variáveis de ambiente e adicionando entradas de host. Essas habilidades fundamentais são essenciais para construir e gerenciar aplicações Dockerizadas.

Executar um contêiner em modo detached e atribuir um nome

Nesta etapa, você aprenderá como executar um contêiner Docker em modo detached (desanexado) e atribuir um nome personalizado a ele. Executar um contêiner em modo detached significa que o contêiner será executado em segundo plano, e você não verá sua saída diretamente em seu terminal. Atribuir um nome facilita a identificação e o gerenciamento do contêiner posteriormente.

Primeiro, vamos baixar a imagem hello-world. Esta é uma imagem muito pequena que é útil para testar se o Docker está funcionando corretamente.

docker pull hello-world

Você deve ver a saída indicando que a imagem está sendo baixada e, em seguida, uma mensagem confirmando que ela foi baixada com sucesso.

Agora, vamos executar o contêiner hello-world em modo detached. Usaremos a flag -d para o modo detached e a flag --name para atribuir um nome. Vamos nomear este contêiner my-hello-world.

docker run -d --name my-hello-world hello-world

Após executar este comando, o Docker imprimirá uma longa sequência de caracteres, que é o ID do contêiner. Isso indica que o contêiner foi iniciado em segundo plano.

Para verificar se o contêiner está em execução, você pode usar o comando docker ps. Este comando lista todos os contêineres atualmente em execução.

docker ps

Você deve ver uma lista de contêineres em execução, e um deles deve ser chamado my-hello-world. A coluna STATUS deve mostrar que o contêiner saiu há alguns segundos. O contêiner hello-world foi projetado para ser executado brevemente, imprimir uma mensagem e, em seguida, sair. Mesmo que tenha saído, ele ainda é listado por docker ps porque foi executado em modo detached.

Para ver todos os contêineres, incluindo aqueles que foram finalizados, você pode usar o comando docker ps -a.

docker ps -a

Isso mostrará my-hello-world na lista, juntamente com seu status (Exited - Finalizado).

Conectar-se a um contêiner em execução e manter STDIN aberto

Nesta etapa, você aprenderá como se conectar a um contêiner em execução e manter a entrada padrão (STDIN) aberta. Isso é útil para interagir com um contêiner que está executando um processo que espera entrada, como um shell.

Na etapa anterior, executamos o contêiner hello-world, que foi finalizado imediatamente. Para demonstrar a conexão, precisamos de um contêiner que permaneça em execução. Uma maneira simples de fazer isso é executar um shell interativo em um contêiner.

Vamos baixar a imagem ubuntu, que é uma imagem base comum para muitas aplicações.

docker pull ubuntu

Agora, executaremos um contêiner ubuntu em modo detached (-d), alocaremos um pseudo-TTY (-t) e manteremos o STDIN aberto (-i). Também atribuiremos um nome a ele, my-ubuntu. O comando que executaremos dentro do contêiner é /bin/bash, que é o caminho para o shell Bash.

docker run -itd --name my-ubuntu ubuntu /bin/bash

A flag -i mantém o STDIN aberto, permitindo que você envie entrada para o contêiner. A flag -t aloca um pseudo-TTY, que é necessário para sessões de shell interativas. A flag -d executa o contêiner em modo detached.

Você deve ver o ID do contêiner impresso em seu terminal, indicando que o contêiner está em execução em segundo plano.

Agora, vamos nos conectar ao contêiner my-ubuntu em execução usando o comando docker attach.

docker attach my-ubuntu

Após executar este comando, você deve ver o prompt do shell Bash dentro do contêiner ubuntu. Você agora está conectado aos fluxos de entrada, saída e erro padrão do contêiner.

Você pode agora interagir com o shell do contêiner. Por exemplo, você pode executar o comando ls para listar os arquivos no diretório atual dentro do contêiner.

ls

Você deve ver o conteúdo do diretório raiz (/) do contêiner Ubuntu.

Para se desconectar do contêiner sem pará-lo, você precisa usar uma sequência de teclas específica: CTRL+p seguido por CTRL+q. Tente pressionar CTRL+p e depois CTRL+q agora.

Você deve ser retornado ao prompt do terminal da sua máquina host. O contêiner ainda está em execução em segundo plano. Você pode verificar isso usando docker ps.

docker ps

Você deve ver my-ubuntu listado como um contêiner em execução.

Se você simplesmente pressionasse CTRL+c enquanto estivesse conectado, isso enviaria um sinal para o processo em execução dentro do contêiner (o shell Bash), o que provavelmente faria com que o contêiner parasse. Usar CTRL+p seguido por CTRL+q é a maneira padrão de se desconectar sem parar o contêiner.

Publicar as portas do contêiner no host

Nesta etapa, você aprenderá como publicar portas de um contêiner Docker para a máquina host. Isso permite que você acesse serviços em execução dentro do contêiner a partir da rede do seu host.

Primeiro, vamos parar e remover o contêiner my-ubuntu da etapa anterior para evitar conflitos.

docker stop my-ubuntu
docker rm my-ubuntu

Você deve ver o nome do contêiner impresso após cada comando, confirmando que ele foi parado e removido.

Agora, executaremos um servidor web simples dentro de um contêiner e publicaremos sua porta para o host. Usaremos a imagem nginx, que é um servidor web popular.

Vamos baixar a imagem nginx.

docker pull nginx

Agora, executaremos um contêiner nginx em modo detached (-d) e publicaremos a porta 80 dentro do contêiner para a porta 8080 na máquina host. Usaremos a flag -p para publicação de porta, no formato host_port:container_port. Também atribuiremos um nome a ele, my-nginx.

docker run -d --name my-nginx -p 8080:80 nginx

A parte -p 8080:80 mapeia a porta 80 dentro do contêiner (onde o Nginx escuta por padrão) para a porta 8080 na sua máquina host.

Você deve ver o ID do contêiner impresso, indicando que o contêiner está em execução em segundo plano.

Para verificar se a porta foi publicada corretamente e o servidor web está acessível, você pode usar o comando curl em sua máquina host para acessar localhost na porta 8080.

curl http://localhost:8080

Você deve ver a página HTML de boas-vindas padrão do Nginx na saída do seu terminal. Isso confirma que você pode acessar o servidor web Nginx em execução dentro do contêiner através da porta 8080 no seu host.

Você também pode usar docker ps para ver o contêiner em execução e suas portas publicadas.

docker ps

Na saída, você deve ver my-nginx listado, e sob a coluna PORTS, você deve ver 0.0.0.0:8080->80/tcp, indicando que a porta 80 dentro do contêiner está mapeada para a porta 8080 em todas as interfaces do host.

Montar um volume para persistir dados

Nesta etapa, você aprenderá como usar volumes Docker para persistir dados gerados e usados por contêineres Docker. Por padrão, os dados dentro de um contêiner são efêmeros; eles são perdidos quando o contêiner é removido. Volumes fornecem uma maneira de armazenar dados fora do sistema de arquivos do contêiner, permitindo que eles persistam mesmo após o contêiner ser parado ou removido.

Primeiro, vamos parar e remover o contêiner my-nginx da etapa anterior.

docker stop my-nginx
docker rm my-nginx

Agora, criaremos um volume Docker. Volumes são gerenciados pelo Docker e são armazenados em uma área dedicada na máquina host.

docker volume create my-volume

Você deve ver o nome do volume (my-volume) impresso, confirmando que ele foi criado.

Você pode listar volumes existentes usando o comando docker volume ls.

docker volume ls

Você deve ver my-volume na lista de volumes.

Agora, executaremos um novo contêiner nginx e montaremos o my-volume no diretório webroot padrão do Nginx dentro do contêiner, que é /usr/share/nginx/html. Isso significa que quaisquer arquivos colocados em /usr/share/nginx/html dentro do contêiner serão, na verdade, armazenados no my-volume no host.

Executaremos o contêiner em modo detached (-d), publicaremos a porta 80 dentro do contêiner para a porta 8081 no host (-p 8081:80), atribuiremos um nome a ele (my-nginx-volume) e usaremos a flag -v para montar o volume. O formato para montar um volume nomeado é volume_name:container_path.

docker run -d --name my-nginx-volume -p 8081:80 -v my-volume:/usr/share/nginx/html nginx

Você deve ver o ID do contêiner impresso, indicando que o contêiner está em execução.

Agora, vamos colocar um arquivo HTML simples no volume montado. Podemos fazer isso executando um comando dentro do contêiner em execução usando docker exec. Criaremos um arquivo chamado index.html em /usr/share/nginx/html com algum conteúdo simples.

docker exec my-nginx-volume sh -c 'echo "<h1>Hello from the volume!</h1>" > /usr/share/nginx/html/index.html'

Este comando executa um shell (sh -c) dentro do contêiner my-nginx-volume e executa o comando echo para criar o arquivo index.html.

Agora, vamos acessar o servidor web na porta 8081 no host para ver o conteúdo do arquivo index.html que acabamos de criar.

curl http://localhost:8081

Você deve ver <h1>Hello from the volume!</h1> na saída. Isso confirma que o arquivo que criamos dentro do contêiner está sendo servido pelo Nginx e, como foi escrito no volume montado, os dados são persistentes.

Para demonstrar a persistência, vamos parar e remover o contêiner my-nginx-volume.

docker stop my-nginx-volume
docker rm my-nginx-volume

Agora, vamos executar um novo contêiner, montando o mesmo volume. Vamos nomear este novo contêiner my-nginx-volume-new e publicar sua porta 80 para a porta 8082 do host.

docker run -d --name my-nginx-volume-new -p 8082:80 -v my-volume:/usr/share/nginx/html nginx

O novo contêiner está em execução e está usando o mesmo my-volume. Vamos acessar o servidor web na porta 8082.

curl http://localhost:8082

Você ainda deve ver <h1>Hello from the volume!</h1> na saída. Isso ocorre porque o arquivo index.html foi armazenado no my-volume, que persistiu mesmo após a remoção do contêiner original. O novo contêiner, montando o mesmo volume, tem acesso aos dados que foram gravados anteriormente.

Isso demonstra o poder dos volumes para persistir dados independentemente do ciclo de vida do contêiner.

Definir variáveis de ambiente e adicionar entradas de host

Nesta etapa, você aprenderá como definir variáveis de ambiente para um contêiner Docker e como adicionar entradas personalizadas ao arquivo /etc/hosts de um contêiner. Variáveis de ambiente são uma maneira comum de configurar aplicativos em execução dentro de contêineres, e adicionar entradas de host pode ser útil para descoberta de serviços ou para substituir a resolução DNS dentro do contêiner.

Primeiro, vamos parar e remover o contêiner my-nginx-volume-new da etapa anterior.

docker stop my-nginx-volume-new
docker rm my-nginx-volume-new

Agora, executaremos um contêiner simples e definiremos uma variável de ambiente. Usaremos a imagem ubuntu novamente e executaremos um comando que imprime o valor de uma variável de ambiente. Definiremos uma variável de ambiente chamada MY_VARIABLE com o valor hello_docker. Usamos a flag -e para definir variáveis de ambiente, no formato VARIABLE_NAME=value.

docker run --rm -e MY_VARIABLE=hello_docker ubuntu env | grep MY_VARIABLE

Neste comando:

  • --rm remove automaticamente o contêiner quando ele sai.
  • -e MY_VARIABLE=hello_docker define a variável de ambiente MY_VARIABLE como hello_docker dentro do contêiner.
  • ubuntu é a imagem que estamos usando.
  • env é o comando executado dentro do contêiner para imprimir todas as variáveis de ambiente.
  • | grep MY_VARIABLE filtra a saída para mostrar apenas a linha contendo MY_VARIABLE.

Você deve ver MY_VARIABLE=hello_docker impresso na saída do seu terminal. Isso confirma que a variável de ambiente foi definida com sucesso dentro do contêiner.

Em seguida, vamos aprender como adicionar entradas de host personalizadas ao arquivo /etc/hosts de um contêiner. Isso pode ser útil se você precisar que um contêiner resolva um nome de host específico para um endereço IP específico sem depender de DNS externo. Usamos a flag --add-host para isso, no formato hostname:ip_address.

Executaremos outro contêiner ubuntu e adicionaremos uma entrada de host que mapeia o nome de host my-service para o endereço IP 192.168.1.100. Em seguida, usaremos o comando cat para exibir o conteúdo do arquivo /etc/hosts dentro do contêiner e usaremos grep para verificar nossa entrada adicionada.

docker run --rm --add-host my-service:192.168.1.100 ubuntu cat /etc/hosts | grep my-service

Neste comando:

  • --rm remove o contêiner após sua saída.
  • --add-host my-service:192.168.1.100 adiciona uma entrada ao arquivo /etc/hosts do contêiner, mapeando my-service para 192.168.1.100.
  • ubuntu é a imagem.
  • cat /etc/hosts é o comando executado dentro do contêiner para imprimir o arquivo hosts.
  • | grep my-service filtra a saída para encontrar a linha com my-service.

Você deve ver uma saída semelhante a 192.168.1.100 my-service no seu terminal. Isso confirma que a entrada de host personalizada foi adicionada ao arquivo /etc/hosts do contêiner.

Você pode combinar a definição de variáveis de ambiente e a adição de entradas de host em um único comando docker run, se necessário.

Resumo

Neste laboratório, você aprendeu como usar o comando docker run para gerenciar contêineres. Você começou executando um contêiner em modo detached usando a flag -d e atribuindo a ele um nome personalizado com a flag --name, verificando seu status com docker ps e docker ps -a.

Em seguida, você explorou como se conectar a um contêiner em execução, mantendo o STDIN aberto, publicar portas do contêiner para o host usando a flag -p para acessibilidade de rede, montar um volume com a flag -v para garantir a persistência de dados além do ciclo de vida do contêiner e configurar o ambiente do contêiner definindo variáveis de ambiente com a flag -e e adicionando entradas de host usando a flag --add-host.