Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 3

Detached vs. Interactive Containers

Recommended resources

Olá! Bem-vindo de volta.

Na lição anterior, desvendamos a arquitetura do Docker, detalhando como o Docker Client, dockerd, containerd e runc trabalham em conjunto para transformar um comando em um contêiner em execução. Agora que você entende a "maquinaria" interna, vamos aprender a operar o controle principal: o comando docker run.

O objetivo desta lição é que você se torne proficiente em executar contêineres em dois modos fundamentais: detached (em segundo plano) e interactive (interativo). Dominar esses modos é crucial, pois eles correspondem aos dois cenários mais comuns no desenvolvimento: executar serviços de longa duração (como sua API .NET) e executar ferramentas de linha de comando para depuração ou tarefas pontuais.

A Anatomia do docker run

Antes de executarmos nosso primeiro contêiner, vamos conectar o comando à arquitetura que estudamos. Lembre-se de que docker run é um comando de alto nível que abstrai uma série de etapas.

Internal Mechanics of the 'docker run' Command
Este diagrama detalha o que acontece nos bastidores quando você executa `docker run`. O comando é decomposto em etapas como `image pull`, `container create` e `container start`, orquestradas pela cadeia `dockerd` -> `containerd` -> `runc` que vimos anteriormente.

Modo Padrão: Foreground (Attached)

Por padrão, quando você executa um contêiner, seu terminal fica "anexado" (attached) aos fluxos de saída padrão (stdout) e erro padrão (stderr) do processo principal do contêiner.

Vamos experimentar isso com um servidor web Nginx. Abra seu terminal e execute:

docker run nginx

Você notará duas coisas:

  1. Logs do Nginx começarão a aparecer diretamente no seu terminal.
  2. Seu terminal ficará bloqueado, aguardando a finalização do processo do Nginx.

Este modo é útil para depuração rápida, pois você vê a saída em tempo real. Para parar o contêiner, pressione Ctrl+C. Isso envia um sinal SIGINT ao processo, geralmente resultando em seu encerramento. No entanto, para serviços que devem rodar continuamente, como APIs e bancos de dados, este não é o modo ideal.


Modo Detached: Rodando Serviços em Segundo Plano

Para executar um contêiner como um serviço em segundo plano, usamos a flag -d (de "detached"). Isso libera seu terminal imediatamente após iniciar o contêiner.

O vídeo a seguir demonstra como executar um contêiner em modo detached e como verificar se ele está em execução.

Docker Tutorial for Beginners

Este trecho do vídeo 'Docker Tutorial for Beginners' do canal mCoding mostra de forma prática a diferença entre executar um contêiner em foreground e usar a flag -d para executá-lo em segundo plano.

Assista do minuto 10:03 ao 10:34. O vídeo mostrará como usar a flag -d e o que o comando retorna (o ID do contêiner). Preste atenção em como o terminal fica livre após a execução.

Agora, execute você mesmo o comando para iniciar o Nginx em modo detached:

docker run -d nginx

O comando retornará uma longa string de caracteres. Esse é o ID completo do contêiner, seu identificador único. Seu terminal está livre. Mas como sabemos que o contêiner está rodando? Usamos o comando docker ps:

docker ps

A saída mostrará uma tabela com os contêineres em execução, incluindo um ID de contêiner abreviado, a imagem usada (nginx), o comando executado, há quanto tempo foi criado, seu status e um nome gerado aleatoriamente (como quirky_darwin).

O modo detached é o padrão para a maioria das aplicações que você irá implantar, incluindo sua API .NET, pois elas são projetadas para rodar continuamente sem interação direta pelo terminal.


Modo Interativo: Interagindo com o Contêiner

E se você precisar de um shell dentro do contêiner para depurar, executar um cliente de banco de dados ou usar uma ferramenta de linha de comando? Para isso, usamos o modo interativo, que é ativado pela combinação das flags -i e -t.

Dado seu interesse em entender "como as coisas funcionam", é importante desmistificar o que cada flag faz:

  • -i (--interactive): Mantém o STDIN (entrada padrão) aberto. Essencialmente, conecta a entrada do seu teclado ao processo dentro do contêiner. Sem isso, você não conseguiria digitar nada.
  • -t (--tty): Aloca um "pseudo-TTY", que é uma emulação de um terminal. Isso faz com que o ambiente dentro do contêiner se comporte como um terminal de verdade, interpretando sinais de controle (como Ctrl+C), gerenciando o layout da tela e permitindo funcionalidades como histórico de comandos.

A combinação -it é o que nos dá uma sessão de shell totalmente interativa. Vamos executar um shell bash dentro de um contêiner baseado na imagem ubuntu:

docker run -it ubuntu /bin/bash

Seu prompt do terminal deve mudar para algo como root@<container_id>:/#. Parabéns, você está "dentro" do contêiner! Você pode executar comandos do Linux (ls, pwd, apt-get update, etc.) como se estivesse em uma máquina virtual leve e descartável. Para sair, basta digitar exit ou pressionar Ctrl+D.

O recurso a seguir oferece uma explicação técnica fantástica sobre como as flags -i e -t funcionam internamente, algo que você certamente apreciará.

How does docker stdin and tty flags work under the covers in containers?

Esta resposta do Stack Overflow fornece uma análise aprofundada e prática do funcionamento das flags -i e -t. Ela usa exemplos com o comando cat para ilustrar o comportamento de cada flag isoladamente e em conjunto, e até menciona a chamada de API subjacente.

Leia a resposta aceita (a primeira). Concentre-se nos exemplos que demonstram docker run -i, docker run -t e docker run -it. A segunda parte da resposta, que discute a chamada de API e a multiplexação de streams, fornecerá o nível de detalhe técnico que você procura.

Teste seu entendimento!

Você quer testar rapidamente uma funcionalidade da biblioteca requests do Python, mas não tem o Python instalado em sua máquina host. Você decide usar o Docker para isso.

Qual comando docker run você usaria para obter um shell interativo dentro de um contêiner com Python, a partir do qual você poderia instalar a biblioteca requests (com pip install requests) e, em seguida, iniciar o interpretador Python para fazer seus testes?

Show answer

O comando ideal seria:

docker run -it python:3.9-slim /bin/bash
  • docker run: O comando para iniciar um contêiner.
  • -it: As flags combinadas para uma sessão interativa com um TTY.
  • python:3.9-slim: Uma imagem oficial do Python, leve (slim), que já vem com Python e pip instalados.
  • /bin/bash: O comando que queremos executar dentro do contêiner, que sobrescreve o comando padrão da imagem (que seria iniciar o interpretador Python) para nos dar um shell.

Uma vez dentro do shell do contêiner, você poderia executar pip install requests e depois python para iniciar o interpretador e começar a testar.


Conclusão

Nesta lição, você aprendeu a usar o comando docker run para iniciar contêineres em dois modos essenciais que servem a propósitos muito diferentes.

Principais pontos a reter:

  • Modo Foreground (padrão): Anexa seu terminal ao contêiner. Útil para ver logs em tempo real, mas bloqueia o terminal. Ex: docker run nginx.
  • Modo Detached (-d): Executa o contêiner em segundo plano e retorna o ID do contêiner. Essencial para serviços de longa duração como servidores web e bancos de dados. Ex: docker run -d nginx.
  • Modo Interativo (-it): Fornece um shell interativo dentro do contêiner. Indispensável para depuração, exploração e execução de ferramentas de linha de comando. Ex: docker run -it ubuntu /bin/bash.
  • O comando docker ps é seu aliado para listar os contêineres que estão atualmente em execução.

Com a capacidade de executar contêineres, o próximo passo natural é aprender a gerenciá-los. Na próxima lição, focaremos no ciclo de vida do contêiner após sua criação, cobrindo os comandos docker start, stop, restart e remove para gerenciar e limpar seus contêineres de forma eficaz.