Pesquisa de site

Como usar docker exec para executar comandos em um contêiner Docker


Introdução

Docker é uma ferramenta de conteinerização que ajuda os desenvolvedores a criar e gerenciar contêineres Linux portáteis e consistentes.

Ao desenvolver ou implantar contêineres, muitas vezes você precisará olhar dentro de um contêiner em execução para inspecionar seu estado atual ou depurar um problema. Para esse fim, o Docker fornece o comando docker exec para executar programas em contêineres já em execução.

Neste tutorial, aprenderemos sobre o comando docker exec e como usá-lo para executar comandos e obter um shell interativo em um contêiner Docker.

Implante seus aplicativos Docker do GitHub usando DigitalOcean App Platform. Deixe a DigitalOcean se concentrar em dimensionar seu aplicativo.

Pré-requisitos

Este tutorial pressupõe que você já tenha o Docker instalado e que seu usuário tenha permissão para executar o docker. Se você precisar executar o docker como usuário root, por favor lembre-se de acrescentar sudo aos comandos deste tutorial.

Para obter mais informações sobre como usar o Docker sem acesso ao sudo, consulte a seção Executando o comando do Docker sem o Sudo do nosso tutorial Como instalar o Docker.

Iniciando um contêiner de teste

Para usar o comando docker exec, você precisará de um contêiner Docker em execução. Se você ainda não possui um contêiner, inicie um contêiner de teste com o seguinte comando docker run:

docker run -d --name container-name alpine watch "date >> /var/log/date.log"

Este comando cria um novo contêiner Docker a partir da imagem oficial alpine. Esta é uma imagem de contêiner Linux popular que usa Alpine Linux, uma distribuição Linux leve e mínima.

Usamos o sinalizador -d para separar o contêiner do nosso terminal e executá-lo em segundo plano. --name container-name nomeará o contêiner como container-name. Você pode escolher qualquer nome que desejar aqui ou deixar totalmente desmarcado para que o Docker gere automaticamente um nome exclusivo para o novo contêiner.

Em seguida temos alpine, que especifica a imagem que queremos usar para o contêiner.

E finalmente, temos watch "date >> /var/log/date.log". Este é o comando que queremos executar no contêiner. watch executará repetidamente o comando fornecido, a cada dois segundos por padrão. O comando que watch irá executar neste caso é date >> /var/log/date.log. date imprime a data e hora atuais, assim:

Fri Jul 23 14:57:05 UTC 2021

A parte >> /var/log/date.log do comando redireciona a saída de date e a anexa ao arquivo /var/log/date. registro. A cada dois segundos, uma nova linha será anexada ao arquivo e, após alguns segundos, ficará mais ou menos assim:

Fri Jul 23 15:00:26 UTC 2021
Fri Jul 23 15:00:28 UTC 2021
Fri Jul 23 15:00:30 UTC 2021
Fri Jul 23 15:00:32 UTC 2021
Fri Jul 23 15:00:34 UTC 2021

Na próxima etapa, aprenderemos como encontrar os nomes dos contêineres Docker. Isso será útil se você já tiver um contêiner de destino, mas não tiver certeza de qual é o nome dele.

Encontrando o nome de um contêiner Docker

Precisaremos fornecer ao docker exec o nome (ou ID do contêiner) do contêiner com o qual queremos trabalhar. Podemos encontrar essas informações usando o comando docker ps:

docker ps

Este comando lista todos os contêineres Docker em execução no servidor e fornece algumas informações de alto nível sobre eles:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
76aded7112d4   alpine    "watch 'date >> /var…"   11 seconds ago   Up 10 seconds             container-name

Neste exemplo, o ID e o nome do contêiner estão destacados. Você pode usar qualquer um deles para informar ao docker exec qual contêiner usar.

Se desejar renomear seu contêiner, use o comando docker rename:

docker rename container-name new-name

A seguir, executaremos vários exemplos de uso de docker exec para executar comandos em um contêiner Docker.

Executando um shell interativo em um contêiner Docker

Se você precisar iniciar um shell interativo dentro de um Docker Container, talvez para explorar o sistema de arquivos ou depurar processos em execução, use docker exec com -i e -t sinalizadores.

O sinalizador -i mantém a entrada aberta para o contêiner, e o sinalizador -t cria um pseudoterminal ao qual o shell pode ser anexado. Esses sinalizadores podem ser combinados assim:

docker exec -it container-name sh

Isso executará o shell sh no contêiner especificado, fornecendo um prompt básico do shell. Para sair do contêiner, digite exit e pressione ENTER:

exit

Se a imagem do seu contêiner incluir um shell mais avançado, como bash, você poderá substituir sh pelo bash acima.

Executando um comando não interativo em um contêiner Docker

Se você precisar executar um comando dentro de um contêiner Docker em execução, mas não precisar de nenhuma interatividade, use o comando docker exec sem nenhum sinalizador:

docker exec container-name tail /var/log/date.log

Este comando executará tail /var/log/date.log no contêiner container-name e gerará os resultados. Por padrão, o comando tail imprimirá as últimas dez linhas de um arquivo. Se estiver executando o contêiner de demonstração que configuramos na primeira seção, você verá algo assim:

Mon Jul 26 14:39:33 UTC 2021
Mon Jul 26 14:39:35 UTC 2021
Mon Jul 26 14:39:37 UTC 2021
Mon Jul 26 14:39:39 UTC 2021
Mon Jul 26 14:39:41 UTC 2021
Mon Jul 26 14:39:43 UTC 2021
Mon Jul 26 14:39:45 UTC 2021
Mon Jul 26 14:39:47 UTC 2021
Mon Jul 26 14:39:49 UTC 2021
Mon Jul 26 14:39:51 UTC 2021

Isso é essencialmente o mesmo que abrir um shell interativo para o contêiner Docker (como feito na etapa anterior com docker exec -it container-name sh) e, em seguida, executando o comando tail /var/log/date.log. No entanto, em vez de abrir um shell, executar o comando e depois fechar o shell, este comando retorna a mesma saída em um único comando sem abrir um pseudoterminal.

Executando comandos em um diretório alternativo em um contêiner Docker

Para executar um comando em um determinado diretório do seu contêiner, use o sinalizador --workdir para especificar o diretório:

docker exec --workdir /tmp container-name pwd

Este comando de exemplo define o diretório /tmp como o diretório de trabalho e, em seguida, executa o comando pwd, que imprime o diretório de trabalho atual:

/tmp

O comando pwd confirmou que o diretório de trabalho é /tmp.

Executando comandos como um usuário diferente em um contêiner Docker

Para executar um comando como um usuário diferente dentro do seu contêiner, adicione o sinalizador --user:

docker exec --user guest container-name whoami

Isso usará o usuário guest para executar o comando whoami no contêiner. O comando whoami imprime o nome de usuário do usuário atual:

guest

O comando whoami confirma que o usuário atual do contêiner é guest.

Passando variáveis de ambiente para um contêiner Docker

Às vezes você precisa passar variáveis de ambiente para um contêiner junto com o comando a ser executado. O sinalizador -e permite especificar uma variável de ambiente:

docker exec -e TEST=sammy container-name env

Este comando define a variável de ambiente TEST como igual a sammy e, em seguida, executa o comando env dentro do contêiner. O comando env então imprime todas as variáveis de ambiente:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/root

A variável TEST está definida como sammy.

Para definir múltiplas variáveis, repita o sinalizador -e para cada uma delas:

docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env

Se você quiser passar um arquivo cheio de variáveis de ambiente, você pode fazer isso com o sinalizador --env-file.

Primeiro, crie o arquivo com um editor de texto. Abriremos um novo arquivo com nano aqui, mas você pode usar qualquer editor com o qual se sinta confortável:

nano .env

Estamos usando .env como nome de arquivo, pois é um padrão popular para usar esses tipos de arquivos para gerenciar informações fora do controle de versão.

Escreva suas variáveis KEY=value no arquivo, uma por linha, como a seguir:

TEST=sammy
ENVIRONMENT=prod

Salve e feche o arquivo. Para salvar o arquivo e sair do nano, pressione CTRL+O, depois ENTER para salvar, depois CTRL+X para sair.

Agora execute o comando docker exec, especificando o nome de arquivo correto após --env-file:

docker exec --env-file .env container-name env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
ENVIRONMENT=prod
HOME=/root

As duas variáveis no arquivo estão definidas.

Você pode especificar vários arquivos usando vários sinalizadores --env-file. Se as variáveis nos arquivos se sobrepuserem, o arquivo listado por último no comando substituirá os arquivos anteriores.

Erros Comuns

Ao usar o comando docker exec, você pode encontrar alguns erros comuns:

Error: No such container: container-name

O erro No such container significa que o contêiner especificado não existe e pode indicar um nome de contêiner incorreto. Use docker ps para listar seus contêineres em execução e verifique novamente o nome.

Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running

Esta mensagem not running significa que o contêiner existe, mas está parado. Você pode iniciar o contêiner com docker start container-name

Error response from daemon: Container container-name is paused, unpause the container before exec

O erro Container is pauseed explica o problema bastante bem. Antes de continuar, você precisa retomar o contêiner com docker unpause container-name.

Conclusão

Neste tutorial, aprendemos como executar comandos em um contêiner Docker em execução, juntamente com algumas opções de linha de comando disponíveis ao fazer isso.

Para obter mais informações sobre o Docker em geral, consulte nossa página de tags do Docker, que contém links para tutoriais do Docker, páginas de perguntas e respostas relacionadas ao Docker e muito mais.

Para obter ajuda com a instalação do Docker, dê uma olhada em Como instalar e usar o Docker no Ubuntu.