Como faço para executar um comando num contentor de estivadores já existente?
-d
por isso não é interativo.
docker run -d shykes/pybuilder bin/bash
vejo que o contentor 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 eu gostaria de executar comandos ocasionais na máquina e sair. Só para obter a resposta.
Tentei ligar a máquina. Tentei ligar-me. Pensei que podia ligar com um contentor, mas isso não parece ser permitido. Usar {[6] } parece correr e depois existir rapidamente.
Gostaria de voltar ao modo interactivo depois sair.
Eu tentei.
docker attach d6c45e8cc5f0
Mas eu tenho:
2014/10/01 22:33:34 You cannot attach to a stopped container, start it first
Mas se eu começar, sai na mesma. Apanha 22. Não posso ganhar.
12 answers
Em outubro de 2014, a equipa de estivadores introduziu o comando {[[9]}: https://docs.docker.com/engine/reference/commandline/exec/
Então agora você pode executar qualquer comando em um container correndo apenas sabendo o seu ID (Ou Nome):
docker exec -it <container_id_or_name> echo "Hello from container!"
Lembre-se que o comando exec
só funciona no contentor já em execução. Se o contentor estiver parado de momento, terá de o executar primeiro com o seguinte comando:
docker run -it -d shykes/pybuilder /bin/bash
A coisa mais importante aqui é a opção -d
, que significa detached
. Isso significa que o comando que você forneceu inicialmente para o container (/bin/bash
) será executado em segundo plano e o container não irá parar imediatamente .
O seu contentor irá sair porque o comando que lhe deu irá acabar. Use as seguintes opções para mantê-lo vivo:
-
-i
Mantenha o STDIN aberto mesmo que não esteja ligado. -
-t
atribui um pseudo-TTY.
Então o teu novo comando run
é:
docker run -it -d shykes/pybuilder bin/bash
Se quiser anexar a um contentor já em funcionamento:
docker exec -it CONTAINER_ID /bin/bash
Nestes exemplos /bin/bash
é usado como comando.
Para expandir a resposta de katrmr, se o contêiner for parado e não puder ser iniciado devido a um erro, você vai precisar commit
para uma imagem. Então você pode lançar bash na nova imagem:
docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
Para iniciar um recipiente existente que é parado
docker start <container-name/ID>
Para parar um contentor em funcionamento
docker stop <container-name/ID>
Em seguida, para entrar na shell interativa de um container
docker exec -it <container-name/ID> bash
Sven Dowideit explicado na janela de Encaixe fórum que os recipientes estão vinculados ao respectivo processo (e a janela de Encaixe não podem alterar o processo de parada do recipiente, aparentemente devido à sua estrutura interna: https://github.com/docker/docker/issues/1437). Então, basicamente, a única opção é commit
o recipiente a uma imagem e run
- lo com diferentes comando.
Ver https://forums.docker.com/t/run-command-in-stopped-container/343
(I believe the "{[[2]} with arguments " approach wouldn't work either, since you still wouldn't be able to change the arguments to a stopped container.)
docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"
Criar um contentor e enviar 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 inventei usando a resposta CDR LDN acima e a resposta que encontrei aqui.
O seguinte exemplo inicia um Contentor de Arch Linux a partir de uma imagem, e depois instala git
nesse contentor 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"
É tudo.
Assumindo que a imagem está a usar o ponto de entrada por omissão /bin/sh -c
, a execução /bin/bash
irá sair imediatamente no modo do servidor (-d
). Se quiser que este contentor execute uma consola interactiva, use -it
em vez de -d
. Se quiser executar comandos arbitrários num contentor que execute normalmente outro processo, poderá querer tentar nsenter
ou nsinit
. Dá uma vista de olhos a https://blog.codecentric.de/en/2014/07/enter-docker-container / para os detalhes.
Infelizmente é impossível sobrepor {[[0]} com argumentos com docker run --entrypoint
para atingir este objectivo.
Nota: poderá sobrepor a configuração do ponto de entrada com o --entrypoint, mas isto só pode definir o binário para exec (não será usado nenhum sh-c).
Encaminhar um comando para o stdin
Tem de remover o -t
para que funcione:
echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash
Isto pode ser mais conveniente que usar opções CLI às vezes.
Testado com:
sudo docker run --name ub16 -it ubuntu:16.04 bash
Depois noutra concha:
echo 'touch myfile' | sudo docker exec -i ub16 bash
Depois na primeira concha:
ls -l myfile
Na doca 1.13.1, Hospedeira Ubuntu 16.04.
Resposta simples: Iniciar e anexar ao mesmo tempo. Neste caso, está a fazer exactamente o que pediu.
docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME>
Não te esqueças de mudar.<CONTAINER_ID/CONTAINER_NAME>