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.