Como faço para executar um comando em um contêiner Docker já existente?

Eu criei um contêiner com -d para que não seja interativo.

 docker run -d shykes/pybuilder bin/bash 

Eu vejo que o contêiner saiu:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d6c45e8cc5f0 shykes/pybuilder:latest "bin/bash" 41 minutes ago Exited (0) 2 seconds ago clever_bardeen 

Agora gostaria de executar comandos ocasionais na máquina e sair. Apenas para obter a resposta.

Eu tentei ligar a máquina. Eu tentei append. Eu pensei que poderia chamar run com um contêiner, mas isso não parece ser permitido. Usar o start parece apenas rodar e depois existir rapidamente.

Eu gostaria de voltar ao modo interativo depois de sair.

Eu tentei:

 docker attach d6c45e8cc5f0 

Mas eu recebo:

 2014/10/01 22:33:34 You cannot attach to a stopped container, start it first 

Mas se eu começar, sai mesmo assim. Pegue 22. Eu não posso vencer.

Em outubro de 2014, a equipe do Docker introduziu o comando docker exec : https://docs.docker.com/engine/reference/commandline/exec/

Portanto, agora você pode executar qualquer comando em um contêiner em execução sabendo apenas seu ID (ou nome):

 docker exec -it  echo "Hello from container!" 

Observe que o comando exec funciona apenas no contêiner já em execução. Se o contêiner estiver parado no momento, será necessário primeiro executá-lo com o seguinte comando:

 docker run -it -d shykes/pybuilder /bin/bash 

O mais importante aqui é a opção -d , que é detached . Isso significa que o comando fornecido inicialmente ao contêiner ( /bin/bash ) será executado em segundo plano e o contêiner não será interrompido imediatamente .

Seu contêiner vai sair quando o comando que você deu vai acabar. Use as seguintes opções para mantê-lo ativo:

  • -i Mantenha STDIN aberto mesmo se não estiver conectado.
  • -t Aloca um pseudo-TTY.

Portanto, seu novo comando de run é:

 docker run -it -d shykes/pybuilder bin/bash 

Se você gostaria de append a um contêiner já em execução:

 docker exec -it CONTAINER_ID /bin/bash 

Nestes exemplos /bin/bash é usado como o comando.

Para expandir a resposta do katrmr, se o contêiner estiver parado e não puder ser iniciado devido a um erro, será necessário commit lo para uma imagem. Então você pode lançar o bash na nova imagem:

 docker commit [CONTAINER_ID] temporary_image docker run --entrypoint=bash -it temporary_image 

Então eu acho que a resposta é simples do que muitas respostas enganosas acima.

Para iniciar um contêiner existente que está parado

 docker start  

Para parar um contêiner em execução

 docker stop  

Então, para fazer login no shell interativo de um contêiner

 docker exec -it  bash 

Algumas das respostas aqui são enganosas porque dizem respeito a contêineres em execução, não interrompidos.

Sven Dowideit explicou no fórum do Docker que os contêineres estão vinculados a seus processos (e o Docker não pode alterar o processo de um contêiner parado, aparentemente devido, pelo menos, à sua estrutura interna: https://github.com/docker/docker/issues / 1437 ). Então, basicamente, a única opção é commit o container a uma imagem e run lo com um comando diferente.

Veja https://forums.docker.com/t/run-command-in-stopped-container/343
(Acredito que a ENTRYPOINTENTRYPOINT with arguments” também não funcionaria, já que você ainda não conseguiria alterar os argumentos para um contêiner parado.)

Eu tive que usar o bash -c para executar o comando: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

Criando um container e enviando comandos para ele, um por um:

 docker create --name=my_new_container -it ubuntu docker start my_new_container // ps -a says 'Up X seconds' docker exec my_new_container /path/to/my/command // ps -a still says 'Up X+Y seconds' docker exec my_new_container /path/to/another/command 

Esta é uma resposta combinada que fiz usando a resposta CDR LDN acima e a resposta que encontrei aqui .

O exemplo a seguir inicia um contêiner do Arch Linux a partir de uma imagem e instala o git nesse contêiner usando a ferramenta pacman :

 sudo docker run -it -d archlinux /bin/bash sudo docker ps -l sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm" 

Isso é tudo.

Supondo que a imagem esteja usando o ponto de input padrão /bin/sh -c , a execução de /bin/bash sairá imediatamente no modo daemon ( -d ). Se você quiser que esse contêiner execute um shell interativo, use -it vez de -d . Se você quiser executar comandos arbitrários em um contêiner geralmente executando outro processo, você pode tentar nsenter ou nsinit . Dê uma olhada em https://blog.codecentric.de/en/2014/07/enter-docker-container/ para os detalhes.

Infelizmente, é impossível replace o ENTRYPOINT por argumentos com o docker run --entrypoint para atingir esse objective.

Nota: você pode sobrescrever a configuração ENTRYPOINT usando –entrypoint, mas isso só pode definir o binário para exec (não será usado sh -c).

Pipe um comando para stdin

Deve remover o -t para que funcione:

 echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash 

Isso pode ser mais conveniente do que usar as opções da CLI às vezes.

Testado com:

 sudo docker run --name ub16 -it ubuntu:16.04 bash 

então em outro shell:

 echo 'touch myfile' | sudo docker exec -i ub16 bash 

Então no primeiro shell:

 ls -l myfile 

no Docker 1.13.1, host do Ubuntu 16.04.

Resposta simples: inicie e anexe ao mesmo tempo. Neste caso, você está fazendo exatamente o que pediu.

 docker start  && docker attach  

Certifique-se de alterar