My Account List Orders Book Page

Scripts Úteis do Docker

Sumário

  • Introdução
  • Capítulo 1 Primeiros Passos com o Docker: Comandos Essenciais.
  • Capítulo 2 Criando Sua Primeira Imagem Docker com um Dockerfile.
  • Capítulo 3 Gerenciando Aplicações Multi-Container com Docker Compose.
  • Capítulo 4 Escrevendo um Script para Automatizar Atualizações de Containers.
  • Capítulo 5 Simplificando Tarefas Comuns com Scripts Auxiliares.
  • Capítulo 6 Técnicas Avançadas de Dockerfile para Builds Otimizados.
  • Capítulo 7 Automatizando Builds e Pushes com GitHub Actions.
  • Capítulo 8 Scripting para Ambientes de Desenvolvimento.
  • Capítulo 9 Scripts para Integração Contínua e Testes.
  • Capítulo 10 Criando Scripts de Entrypoint Personalizados para Containers Flexíveis.
  • Capítulo 11 Gerenciando Contextos do Docker em Scripts Bash.
  • Capítulo 12 Scripting para Criação e Gerenciamento de Redes.
  • Capítulo 13 Automatizando Gerenciamento de Volumes e Persistência de Dados.
  • Capítulo 14 Um Script para Limpar Recursos Docker Não Utilizados.
  • Capítulo 15 Scripting para Backup e Restauração de Volumes Docker.
  • Capítulo 16 Automatizando a Limpeza de Imagens Docker.
  • Capítulo 17 Scripting para Verificações de Saúde dos Seus Containers.
  • Capítulo 18 Criando um Script Python para Interagir com a API do Docker.
  • Capítulo 19 Criando um Script de Gerenciamento de Usuários para Ambientes Docker Compartilhados.
  • Capítulo 20 Scripting para Implantação de uma Aplicação Full Stack.
  • Capítulo 21 Um Script para Inspecionar e Formatar Informações de Containers.
  • Capítulo 22 Automatizando a Marcação e Envio de Imagens para um Registro.
  • Capítulo 23 Scripting para o Manuseio Seguro de Segredos no Docker.
  • Capítulo 24 Um Script para Parar e Remover Containers de Forma Graciosa.
  • Capítulo 25 Scripting Avançado: Combinando Comandos Docker para Fluxos de Trabalho Complexos.

Introdução

Existe um momento distinto na jornada de todo usuário do Docker que parece uma pequena revelação. Frequentemente, ele chega após digitar docker run com uma dúzia de sinalizadores pela vigésima vez em uma hora, ou após executar penosamente uma sequência de comandos docker ps, docker stop e docker rm para limpar um ambiente local. É o momento em que você se recosta na cadeira, olha para o prompt de comando e pensa: "Tem que haver uma maneira mais eficiente de fazer isso". Você está, obviamente, absolutamente correto. O caminho dos comandos manuais repetitivos para a eficiência simplificada é pavimentado com scripts.

O Docker mudou fundamentalmente como construímos, enviamos e executamos software. Ele oferece uma promessa incrível: um ambiente consistente, isolado e portátil para qualquer aplicação. Ao empacotar uma aplicação e suas dependências em uma única unidade padronizada chamada contêiner, o Docker resolve o clássico problema "funciona na minha máquina" que atormenta desenvolvedores há décadas. Essa abordagem de conteinerização fornece uma alternativa leve às máquinas virtuais tradicionais ao virtualizar o sistema operacional em vez do hardware subjacente. Essa eficiência significa que você pode executar vários contêineres em um único host, cada um com seu próprio conjunto isolado de processos e recursos.

O poder do Docker reside em sua simplicidade e em sua robusta interface de linha de comando (CLI). Com alguns comandos, você pode baixar uma imagem de um registro como o Docker Hub, executá-la como um contêiner e ter uma aplicação complexa, como um banco de dados ou um servidor web, funcionando em segundos. Isso é um salto monumental em relação aos dias de instalações manuais e gerenciamento complexo de dependências. No entanto, confiar apenas em comandos digitados manualmente é como possuir um carro esportivo e só dirigi-lo em primeira marcha. Você está experimentando a função principal, mas perdendo a velocidade, a potência e a elegância das quais ele é verdadeiramente capaz.

É aqui que a scriptagem entra em cena. Um script é, em sua essência, um conjunto de instruções salvo em um arquivo, projetado para ser executado por um programa. Para usuários do Docker, isso geralmente significa scripts de shell (como Bash) ou scripts escritos em uma linguagem de alto nível como Python. Esses scripts pegam os comandos individuais e atômicos da CLI do Docker e os entrelaçam em fluxos de trabalho automatizados e poderosos. Eles transformam processos manuais de múltiplas etapas, propensos a erros, em um único comando confiável. Eles são a chave para desbloquear todo o potencial do seu ambiente Docker.

Pense nas tarefas de rotina que você realiza diariamente. Iniciar um ambiente de desenvolvimento específico com vários contêineres vinculados. Fazer backup de um volume crítico de banco de dados. Limpar imagens e contêineres não utilizados para recuperar espaço em disco. Atualizar uma aplicação em execução para uma nova versão de imagem sem tempo de inatividade. Cada um desses fluxos de trabalho envolve uma sequência de comandos Docker, e cada um é um candidato perfeito para automação através de scriptagem. Um script bem escrito garante que essas tarefas sejam realizadas de forma consistente todas as vezes, eliminando o risco de erro humano, como esquecer um sinalizador de linha de comando ou digitar um nome de contêiner incorretamente.

Este livro nasce da necessidade prática dessa automação. Embora existam inúmeros recursos disponíveis para ensinar os fundamentos do Docker — o que é uma imagem, como escrever um Dockerfile, o propósito de um contêiner — muitos param por aí. Eles lhe dão os blocos de construção, mas nem sempre mostram como montá-los em algo maior. Este livro é diferente. Não é apenas mais um guia de comandos Docker; é um compêndio prático e prático de scripts úteis projetados para resolver problemas do mundo real e tornar sua vida como desenvolvedor, administrador de sistemas ou engenheiro DevOps significativamente mais fácil.

Vamos além dos comandos básicos docker run e docker build para explorar a arte da scriptagem. Este livro é uma coleção de receitas, um kit de ferramentas de soluções prontas para uso para os desafios comuns, e às vezes incomuns, que você enfrenta ao trabalhar com Docker. Cada capítulo é dedicado a uma tarefa específica e fornece um script completo e funcional que você pode usar imediatamente. Mais importante, vamos dissecar como cada script funciona, explicando os comandos, a lógica e as técnicas usadas, para que você não apenas use os scripts, mas também os compreenda, adapte e estenda para atender aos seus requisitos únicos.

Então, para quem é este livro? É para o desenvolvedor que deseja criar uma configuração consistente de ambiente de desenvolvimento local com um único comando. É para o administrador de sistemas que precisa gerenciar hosts Docker e automatizar tarefas de manutenção de rotina, como backups e limpeza. É para o profissional DevOps que está construindo pipelines robustos de integração contínua e implantação contínua (CI/CD). Em essência, este livro é para qualquer um que tenha experimentado aquele momento de "tem que haver uma maneira melhor" e esteja pronto para abraçar a automação.

O único pré-requisito é uma compreensão fundamental do Docker. Você deve estar familiarizado com conceitos essenciais como imagens, contêineres, volumes e redes. Você deve ter o Docker instalado e alguma experiência executando comandos básicos. No entanto, você não precisa ser um guru de scriptagem. Começaremos com scripts de shell simples e introduziremos gradualmente técnicas mais avançadas e até nos aprofundaremos no uso da API do Docker com Python, garantindo que o material seja acessível independentemente da sua proficiência atual em scriptagem.

Ao longo dos capítulos deste livro, embarcaremos em uma jornada do simples para o complexo. Começamos garantindo uma base sólida, cobrindo comandos essenciais e os fundamentos da construção de imagens com um Dockerfile e do gerenciamento de configurações multi-contêiner com o Docker Compose. Esses capítulos iniciais lançam as bases, garantindo que você tenha os blocos de construção necessários à sua disposição antes de começarmos a montá-los em fluxos de trabalho automatizados. Eles servem como uma reciclagem e uma linha de base para o trabalho de scriptagem que virá.

A partir daí, mergulhamos de cabeça no mundo da automação. Você aprenderá a escrever um script que pode baixar automaticamente uma nova versão de uma imagem e reiniciar um contêiner para concluir uma atualização, uma pedra angular da manutenção de aplicações em execução. Exploraremos a criação de scripts auxiliares genéricos que podem simplificar uma ampla gama de tarefas comuns, tornando suas interações de linha de comando com o Docker mais poderosas e menos verbosas. Esses scripts são projetados para serem ferramentas práticas que você pode integrar ao seu fluxo de trabalho imediatamente.

Uma parte significativa da nossa jornada será dedicada à bela arte do gerenciamento de recursos. Ambientes Docker, especialmente aqueles usados intensivamente para desenvolvimento e teste, podem rapidamente ficar cheios de imagens, volumes e contêineres parados não utilizados, consumindo valioso espaço em disco. Forneceremos e dissecaremos scripts especificamente projetados para limpar essa bagunça de forma segura e eficiente. Você aprenderá como automatizar a poda de imagens antigas e como implementar um script que remove inteligentemente apenas os recursos que não são mais necessários.

Dados são a força vital de muitas aplicações, e gerenciá-los dentro de um mundo conteinerizado apresenta seu próprio conjunto de desafios. Enfrentaremos isso de frente com capítulos sobre scriptagem do gerenciamento de volumes Docker. Você aprenderá a escrever scripts robustos para realizar uma das tarefas administrativas mais críticas: fazer backup dos seus dados importantes de um volume e, tão importante quanto, restaurá-los. Isso fornece uma rede de segurança e é uma habilidade essencial para qualquer um que execute aplicações com estado no Docker.

À medida que sua proficiência cresce, entraremos em território mais avançado. Veremos técnicas sofisticadas de Dockerfile que ajudam você a criar imagens menores, mais seguras e mais eficientes. Uma imagem otimizada é construída mais rápido, consome menos espaço em disco e tem uma superfície de ataque menor, tudo o que é crítico em um ambiente de produção. Mostraremos como estruturar seus Dockerfiles para tirar total proveito do mecanismo de cache de camadas do Docker para builds mais rápidos.

A automação se estende além da sua máquina local, e o desenvolvimento de software moderno está profundamente entrelaçado com plataformas de CI/CD. Um capítulo dedicado o guiará pelo processo de uso do GitHub Actions para automatizar a construção e o envio das suas imagens Docker para um registro. Isso preenche a lacuna entre seu repositório de código e seu ambiente de implantação, criando um pipeline contínuo do commit à imagem de contêiner.

Também exploraremos como scripts podem ser adaptados especificamente para ambientes de desenvolvimento. Isso inclui scripts que configuram pilhas de aplicações complexas, gerenciam diferentes contextos Docker para alternar entre daemons Docker locais e remotos, e escrevem a criação de redes personalizadas para garantir que seus contêineres possam se comunicar da forma que sua aplicação exige. Esses scripts ajudam a impor consistência em uma equipe de desenvolvedores, garantindo que todos estejam trabalhando em um ambiente idêntico.

A interação com contêineres não para quando eles estão em execução. Investigaremos como escrever scripts de verificações de saúde para monitorar o status das suas aplicações e como criar scripts de ponto de entrada personalizados que tornam seus contêineres mais flexíveis e configuráveis em tempo de execução. Você até aprenderá como contornar a CLI e interagir diretamente com o Docker Engine usando sua API, abrindo um mundo totalmente novo de possibilidades de automação com linguagens como Python.

Segurança é uma preocupação primordial em qualquer ambiente, e o Docker não é exceção. Um capítulo dedicado focará na scriptagem do manuseio seguro de segredos, um aspecto crítico da implantação de aplicações que precisam se conectar a bancos de dados ou outros serviços protegidos. Veremos diferentes estratégias para fornecer informações sensíveis aos seus contêineres sem codificá-las permanentemente em suas imagens ou scripts, que é um antipadrão comum, mas perigoso.

Finalmente, reuniremos tudo abordando fluxos de trabalho complexos do mundo real. Percorreremos a scriptagem da implantação de uma aplicação full-stack, desde a construção das imagens até o lançamento dos serviços interconectados. Também cobriremos scripts para tarefas administrativas como gerenciar usuários em um ambiente Docker compartilhado, parar e remover contêineres graciosamente para garantir desligamentos limpos, e criar ferramentas personalizadas para inspecionar e formatar informações de contêineres para obter a saída exata que você precisa.

A filosofia por trás dos scripts neste livro é de praticidade e adaptabilidade. Eles são escritos para serem o mais claros e diretos possível, com comentários para explicar as partes mais complexas. No entanto, não se destinam a ser artefatos imutáveis. Você é encorajado a pegá-los, modificá-los, quebrá-los e reconstruí-los para se adequarem perfeitamente às suas necessidades. O objetivo não é apenas fornecer uma biblioteca de scripts, mas capacitá-lo com o conhecimento para criar os seus próprios.

Para tirar o máximo proveito deste livro, encorajo você a ser um leitor ativo. Não apenas leia o texto; inicie seu terminal e execute os scripts. Experimente com os comandos e tente modificar o código para ver o que acontece. A melhor maneira de aprender scriptagem é fazendo, e a melhor maneira de entender uma ferramenta é usá-la. Configure um ambiente Docker local seguro onde você seja livre para experimentar sem medo de quebrar algo crítico.

A jornada de um usuário Docker manual, comando a comando, para um mestre da automação é recompensadora. Ela economizará seu tempo, reduzirá erros e, em última análise, permitirá que você se concentre nos aspectos mais interessantes e criativos do seu trabalho. A capacidade de encapsular um processo complexo em um único script executável é um superpoder no mundo do desenvolvimento de software e operações.

Este livro é seu guia para desenvolver esse superpoder. É hora de ir além da labuta da digitação repetitiva e abraçar a elegância da automação. Vamos parar de digitar e começar a escrever scripts.


CAPÍTULO UM: Introdução ao Docker: Comandos Essenciais.

Antes de se poder compor uma sinfonia, deve-se primeiro aprender a tocar as notas individuais. No mundo da automação com Docker, nossas notas são os comandos da interface de linha de comando (CLI). Estes são os verbos fundamentais que nos permitem comunicar nossas intenções ao daemon do Docker, o motor que impulsiona nosso mundo conteinerizado. Embora o objetivo final deste livro seja tecer esses comandos em scripts elegantes e poderosos, essa jornada deve começar com uma compreensão sólida dos próprios comandos. Este capítulo é sua caixa de ferramentas, um passeio guiado pelas ferramentas essenciais para as quais você recorrerá vez após vez. Dominar esses comandos é o primeiro e mais crítico passo para se tornar proficiente no Docker e, por extensão, em sua automação.

Exploraremos o ciclo de vida completo de um contêiner, desde encontrar o pacote de software correto em um registro público até executá-lo, inspecioná-lo, gerenciar seu estado e, finalmente, limpá-lo. Cada comando é um bloco de construção. Entender não apenas o que um comando faz, mas também suas várias opções e o contexto no qual é mais eficaz, é fundamental. Estas são as ferramentas que você usará para construir os fluxos de trabalho automatizados sofisticados nos capítulos que virão. Pense nisto como seu treinamento fundamental, garantindo que seu vocabulário seja forte antes de começar a escrever poesia.

Nossa jornada começa onde a maioria dos fluxos de trabalho do Docker começa: com uma imagem. Uma imagem é um projeto, um modelo somente leitura contendo a aplicação, suas bibliotecas e suas dependências. Essas imagens são normalmente armazenadas em um registro (registry), que é um repositório para armazená-las e distribuí-las. O registro público mais comum é o Docker Hub. A primeira coisa que você frequentemente precisará fazer é encontrar a imagem oficial para o software que deseja usar. Para isso, o comando docker search é um ponto de partida útil, embora básico. Ele consulta o Docker Hub por imagens que correspondam ao seu termo de busca.

Por exemplo, se você quisesse encontrar imagens relacionadas ao popular servidor web Nginx, executaria:

docker search nginx

A saída fornece uma lista de imagens com colunas para o nome, uma breve descrição, o número de estrelas (uma métrica aproximada de popularidade) e se a imagem é oficial. Imagens oficiais são um conjunto curado de repositórios do Docker, fornecendo um ponto de partida verificado e bem documentado para software comum. É quase sempre uma prática recomendada usar a imagem oficial se uma estiver disponível, pois elas são mantidas com segurança e estabilidade em mente.

Uma vez identificada a imagem que você deseja usar, como a imagem oficial nginx, você precisa trazê-la do registro para sua máquina local. Esse é o trabalho do comando docker pull. Este comando faz o download das camadas da imagem necessárias para montar a imagem completa no seu sistema. A sintaxe é direta, exigindo o nome da imagem e, opcionalmente, uma tag. Uma tag é usada para versionar uma imagem, como 1.21 ou latest. Se nenhuma tag for especificada, o Docker assume como padrão a marcada como latest.

Para baixar a imagem oficial do Nginx, você executaria:

docker pull nginx

Isso é equivalente a docker pull nginx:latest. Para baixar uma versão específica, você especificaria a tag assim: docker pull nginx:1.21. Usar tags de versão específicas em vez de latest é uma prática crucial para criar ambientes reprodutíveis e scripts confiáveis. A tag latest pode ser atualizada a qualquer momento pelo mantenedor da imagem, o que significa que seu script poderia se comportar de forma diferente de um dia para o outro. Fixar em uma versão específica garante que você está sempre trabalhando com o mesmo software exato. Após o pull, você pode ver todas as imagens na sua máquina local com o comando docker images.

Com uma imagem baixada para sua máquina, você tem o projeto. O próximo passo lógico é usar esse projeto para construir algo real: um contêiner. Um contêiner é uma instância executável de uma imagem. O comando para criar e iniciar um contêiner é docker run, arguivelmente o comando mais importante e rico em recursos da CLI do Docker. Sua forma básica é simples, mas seu poder reside na multiplicidade de flags que podem ser usadas para configurar como o contêiner é executado.

A execução mais simples possível deste comando é com uma imagem como hello-world, que foi projetada exatamente para este propósito.

docker run hello-world

Quando você executa isso, uma sequência de eventos se desenrola. O Docker verifica se a imagem hello-world está presente no seu sistema local. Se não estiver, ele a baixa automaticamente do Docker Hub. Em seguida, cria um novo contêiner a partir dessa imagem. Executa o comando embutido na imagem, que neste caso imprime uma mensagem amigável no seu terminal. Por fim, uma vez que o comando termina, o contêiner para. Este exemplo simples demonstra a função central de criar e executar um contêiner.

Para a maioria das aplicações do mundo real, no entanto, você precisará de mais controle. Você vai querer executar contêineres em segundo plano, interagir com eles, expô-los à sua rede e dar-lhes dados persistentes. É aqui que entram as flags para docker run. Vamos começar distinguindo entre dois modos primários de operação: interativo e desanexado (detached).

Um contêiner interativo é aquele ao qual você conecta seu terminal, permitindo executar comandos dentro dele diretamente. Isso é alcançado com as flags -it. A flag -i mantém a entrada padrão (STDIN) aberta, e a flag -t aloca um pseudo-TTY, o que essencialmente lhe dá um prompt de comando dentro do contêiner. Isso é perfeito para explorar uma imagem ou realizar uma tarefa única. Por exemplo, para executar um contêiner Ubuntu e obter um shell bash dentro dele, você usaria:

docker run -it ubuntu /bin/bash

O prompt do seu terminal mudaria, e você estaria agora executando comandos dentro do contêiner Ubuntu. Isso é incrivelmente útil para depuração ou desenvolvimento. Quando você digita exit, o processo bash termina e o contêiner para.

O modo alternativo é o modo desanexado, especificado com a flag -d. Este é o cavalo de batalha para executar serviços de longa duração, como servidores web, bancos de dados ou APIs. Quando você executa um contêiner no modo desanexado, o Docker inicia o contêiner e então devolve o controle ao prompt do terminal do host, deixando o contêiner rodando em segundo plano. O comando imprime o ID único do contêiner recém-criado como confirmação. Por exemplo, para iniciar um servidor web Nginx em segundo plano:

docker run -d nginx

Agora você tem um servidor web rodando, mas como acessá-lo? Por padrão, os contêineres são isolados da rede do host. Para expor um serviço rodando dentro de um contêiner, você deve mapear uma porta da máquina host para uma porta dentro do contêiner usando a flag -p. O formato é -p [porta_host]:[porta_conteiner]. Se quisermos acessar nosso servidor Nginx na porta 8080 da nossa máquina local, a mapeamos para a porta 80 dentro do contêiner, que é a porta padrão que o Nginx escuta.

docker run -d -p 8080:80 nginx

Agora, se você abrir um navegador web e navegar para http://localhost:8080, verá a página de boas-vindas padrão do Nginx, servida a partir do seu contêiner. Este mapeamento de portas é fundamental para tornar aplicações conteinerizadas úteis.

Quando você executa um contêiner, o Docker lhe atribui um nome aleatório, muitas vezes gerado de forma caprichosa, como vigilant_murdock ou dreamy_bassi. Embora divertidos, esses nomes não são úteis para automação. Se você quiser se referir de forma confiável a um contêiner específico em um script, precisa dar a ele um nome previsível. A flag --name permite que você faça exatamente isso. Um contêiner bem nomeado é o primeiro passo para um ambiente gerenciável.

docker run -d -p 8080:80 --name meu-servidor-web nginx

Agora, em vez de precisar encontrar seu nome ou ID aleatórios, você pode simplesmente se referir a este contêiner como meu-servidor-web nos comandos subsequentes, o que é muito mais conveniente e essencial para escrever scripts robustos.

Outro conceito crítico é a persistência de dados. O sistema de arquivos dentro de um contêiner é efêmero por padrão. Isso significa que, se você remover o contêiner, quaisquer dados criados ou modificados dentro dele são perdidos para sempre. Isso é bom para aplicações sem estado, mas desastroso para qualquer coisa que precise manter estado, como um banco de dados. O Docker resolve isso com volumes. Um volume é um mecanismo para persistir dados gerados e usados por contêineres Docker. Mergulharemos fundo em scripts de gerenciamento de volumes no Capítulo 13, mas o uso básico com docker run é essencial saber agora.

A flag -v é usada para montar um volume em um contêiner. Você pode deixar o Docker gerenciar o volume (um volume nomeado) ou mapear um diretório específico da sua máquina host para dentro do contêiner (um bind mount). Para um banco de dados MySQL, você pode querer persistir o diretório de dados:

docker run -d --name meu-banco -e MYSQL_ROOT_PASSWORD=minhasenhasecreta -v dados-mysql:/var/lib/mysql mysql

Neste comando, também introduzimos a flag -e, que define uma variável de ambiente dentro do contêiner. Esta é uma forma muito comum de passar detalhes de configuração, como senhas ou configurações, para a aplicação rodando no contêiner. A parte -v dados-mysql:/var/lib/mysql diz ao Docker para criar um volume nomeado chamado dados-mysql (se ainda não existir) e montá-lo no caminho /var/lib/mysql dentro do contêiner. Agora, mesmo que você remova o contêiner meu-banco, o volume dados-mysql permanecerá, e você poderá anexá-lo a um novo contêiner para retomar seu trabalho.

Finalmente, para muitas tarefas temporárias, como executar uma suíte de testes ou um processo de build, você cria um contêiner, ele realiza sua ação e então para. Por padrão, esse contêiner parado ainda existe no seu sistema. Com o tempo, isso pode levar a uma quantidade significativa de bagunça. A flag --rm diz ao Docker para remover automaticamente o contêiner assim que ele sair. Este é um recurso fantástico de limpeza.

docker run --rm -it ubuntu echo "Este contêiner desaparecerá quando eu terminar."

Uma vez que o comando echo é concluído, o contêiner é removido imediata e automaticamente, deixando seu sistema limpo. Usar --rm para contêineres de vida curta e tarefa única é uma prática recomendada que previne o acúmulo de contêineres parados.

Uma vez que você tem contêineres rodando, particularmente no modo desanexado, você precisa de uma maneira de ver o que está acontecendo. O comando principal para isso é docker ps. Por si só, este comando lista todos os contêineres em execução no seu sistema. A saída é uma tabela organizada mostrando várias informações úteis: o ID do contêiner, a imagem a partir da qual foi criado, o comando que está rodando, quando foi criado, seu status atual, quaisquer mapeamentos de porta e seu nome.

Esta visualização é crucial para obter uma visão rápida do seu ambiente ativo. No entanto, ela conta apenas parte da história. Para ver todos os contêineres, incluindo aqueles que pararam ou saíram, você deve adicionar a flag -a.

docker ps -a

Este comando é o seu recurso para um inventário completo. Você verá contêineres que saíram com sucesso (Status Exited (0)) e aqueles que falharam (ex: Exited (1)). Este é frequentemente o primeiro passo na depuração do porquê de um contêiner não estar rodando como esperado.

Para fins de scriptagem, a saída tabular padrão do docker ps nem sempre é ideal. Ela é projetada para olhos humanos. Quando você precisa passar uma lista de contêineres para outro comando, muitas vezes você quer apenas os IDs. A flag -q (quiet) modifica a saída para mostrar apenas os IDs dos contêineres, um por linha. Por exemplo, para obter uma lista de todos os IDs de contêineres, rodando ou parados:

docker ps -a -q

Esta saída pode ser usada diretamente em outros comandos. Por exemplo, um padrão comum para remover todos os contêineres parados é usar substituição de comando: docker rm $(docker ps -a -f "status=exited" -q). Aqui, também introduzimos a flag -f (ou --filter), que permite estreitar a lista com base em certos critérios, neste caso, o status do contêiner. Esta combinação de filtragem e saída silenciosa é uma técnica poderosa que forma a base de muitos scripts de limpeza.

Simplesmente saber que um contêiner está rodando muitas vezes não é suficiente. Você precisa ver sua saída ou interagir com ele. Para contêineres desanexados, que não têm sua saída conectada ao seu terminal, o comando docker logs é essencial. Ele busca os logs (saída padrão e erro padrão) de um contêiner.

docker logs meu-servidor-web

Isso exibirá todos os logs gerados pelo contêiner Nginx desde que ele iniciou. Para um serviço em execução contínua, você pode querer assistir aos logs em tempo real, similar ao comando tail -f no Linux. A flag -f (follow) para docker logs faz exatamente isso.

docker logs -f meu-servidor-web

Seu terminal agora transmitirá os logs à medida que são gerados, o que é inestimável para monitoramento e depuração ao vivo.

Às vezes, você precisa fazer mais do que apenas ver logs; você precisa executar um comando dentro de um contêiner que já está rodando. Por exemplo, você pode querer inspecionar um arquivo de configuração no seu contêiner Nginx em execução ou verificar o conteúdo de um banco de dados. Esse é o trabalho do comando docker exec. Ele permite que você "execute" um comando em um contêiner em execução.

Para obter um shell interativo dentro do nosso meu-servidor-web em execução, você usaria:

docker exec -it meu-servidor-web /bin/bash

Isso parece muito semelhante ao comando docker run -it, mas a diferença crucial é que o docker exec se conecta a um contêiner existente, em execução, enquanto o docker run cria um novo. Usar exec é a maneira padrão de realizar tarefas administrativas em um serviço em execução sem precisar pará-lo e reiniciá-lo.

O ciclo de vida de um contêiner não é apenas sobre criação; é também sobre controle. Você frequentemente precisará parar, iniciar e reiniciar seus contêineres. Os comandos para essas ações são diretos: docker stop, docker start e docker restart. O comando docker stop desliga graciosamente um contêiner enviando primeiro um sinal SIGTERM, permitindo que a aplicação realize um desligamento limpo. Se não parar dentro de um período de carência (tipicamente 10 segundos), o Docker envia um sinal SIGKILL para terminá-lo à força.

docker stop meu-servidor-web

Uma vez que um contêiner é parado, ele não aparece mais na saída padrão do docker ps, mas ainda existe e pode ser visto com docker ps -a. Para trazê-lo de volta à vida, você usa docker start.

docker start meu-servidor-web

O contêiner retomará com sua configuração anterior, incluindo seu nome e quaisquer volumes anexados. O comando docker restart é simplesmente um atalho conveniente que executa um stop seguido de um start, o que é útil para aplicar mudanças de configuração que exigem uma reinicialização do serviço.

Um ambiente Docker bem mantido é um ambiente limpo. Com o tempo, contêineres parados e imagens não utilizadas podem se acumular, consumindo espaço significativo em disco. Já vimos a flag --rm para docker run, mas você também precisa de comandos para limpar manualmente recursos existentes. O comando docker rm é usado para remover um ou mais contêineres parados.

docker rm [id_ou_nome_do_conteiner]

Você não pode remover um contêiner em execução a menos que use a flag -f (force), mas a abordagem mais limpa é sempre pará-lo primeiro e depois removê-lo. Você também pode passar uma lista de IDs de contêineres para remover vários contêineres de uma vez, uma técnica que, como mencionado, é perfeita para scriptagem.

Da mesma forma, as imagens podem ocupar ainda mais espaço que os contêineres. O comando docker rmi é usado para remover uma ou mais imagens. Uma imagem não pode ser removida se estiver sendo usada atualmente por um contêiner, mesmo um parado. Você deve remover os contêineres dependentes primeiro antes de poder remover a imagem na qual eles se baseiam.

docker rmi nginx:1.21

Estes comandos de limpeza manuais são eficazes, mas também são candidatos ideais para automação. Capítulos posteriores mostrarão como construir scripts que encontram e removem recursos não utilizados de forma inteligente, economizando seu tempo e espaço em disco.

Finalmente, há um comando que atua como uma ferramenta universal para inspeção profunda: docker inspect. Este comando pode ser usado em contêineres, imagens, volumes e redes. Ele retorna um array JSON detalhado contendo uma riqueza de informações sobre o objeto Docker especificado. A saída pode ser avassaladora no início, mas é um recurso incrivelmente poderoso para automação.

docker inspect meu-servidor-web

Isso imprimirá um grande objeto JSON na tela, detalhando tudo sobre o contêiner: seu estado, sua configuração, suas configurações de rede (incluindo seu endereço IP interno), seus pontos de montagem de volume e muito mais.

O verdadeiro poder do docker inspect para scriptagem é desbloqueado com sua flag --format. Esta flag permite que você forneça um template Go para extrair pedaços específicos de informação da saída JSON. Em vez de analisar um enorme arquivo JSON com uma ferramenta como jq, você pode pedir ao Docker para lhe dar apenas o ponto de dado que precisa. Por exemplo, para obter apenas o endereço IP interno de um contêiner:

docker inspect --format='{{.NetworkSettings.IPAddress}}' meu-servidor-web

Esta capacidade de consultar precisamente o estado e a configuração de qualquer objeto Docker é o que torna o docker inspect uma pedra angular da scriptagem avançada. Você pode usá-lo para buscar informações dinâmicas, como o endereço IP de um contêiner, e alimentá-las em outros comandos ou arquivos de configuração, criando automação verdadeiramente dinâmica e inteligente.

Estes comandos—pull, run, ps, logs, exec, stop, rm, rmi e inspect—formam o vocabulário central do Docker. Eles são as ferramentas essenciais que você usará todos os dias. Ao entender suas funções e opções, você construiu a base necessária. Agora você pode gerenciar o ciclo de vida completo de um contêiner manualmente. Com esta compreensão sólida dos blocos de construção individuais, estamos agora prontos para dar o próximo passo: definir nossos próprios projetos para aplicações aprendendo a construir um Dockerfile.


This is a sample preview. The complete book contains 27 sections.