Como entro no shell de um contêiner do Docker?

1163

Estou começando a trabalhar com o Docker. Estou usando a imagem base do WordPress e o docker-compondo.

Estou tentando ssh em um dos contêineres para inspecionar os arquivos / diretórios que foram criados durante a compilação inicial. Eu tentei correr docker-compose run containername ls -la, mas isso não fez nada. Mesmo assim, prefiro ter um console onde possa percorrer a estrutura de diretórios, em vez de executar um único comando. Qual é a maneira correta de fazer isso com o Docker?

Andrew
fonte
Parece que a resposta é anexada ao docker. Mas como posso chegar a isso com o docker-compondo?
11303 Andrew
3
Use docker exec askubuntu.com/a/543057/35816 . Obter o ID do contêiner usandodocker ps
Mauricio Scheffer
26
sudo docker run -it --entrypoint /bin/bash <container_name>leva você para o contêiner interativamente. Em seguida, pode-se inspecionar o sistema de arquivos no recipiente utilizandocd <path>
Sergei

Respostas:

1735

docker attachpermitirá que você se conecte ao seu contêiner do Docker, mas isso não é o mesmo ssh. Se o seu contêiner estiver executando um servidor da web, por exemplo, docker attachprovavelmente você será conectado ao stdout do processo do servidor da web. Não vai necessariamente dar uma concha.

O docker execcomando é provavelmente o que você está procurando; isso permitirá que você execute comandos arbitrários dentro de um contêiner existente. Por exemplo:

docker exec -it <mycontainer> bash

Obviamente, qualquer comando que você esteja executando deve existir no sistema de arquivos do contêiner.

No comando acima <mycontainer>está o nome ou o ID do contêiner de destino. Não importa se você está usando ou não docker compose; basta executar docker pse usar o ID (uma sequência hexadecimal exibida na primeira coluna) ou o nome (exibido na coluna final). Por exemplo, dado:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Eu posso correr:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Eu poderia realizar a mesma coisa executando:

$ docker exec -it d2d4a89aaee9 ip addr

Da mesma forma, eu poderia iniciar um shell no contêiner;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
larsks
fonte
76
Além disso, docker execfunciona apenas na execução de contêineres (caso contrário, use docker run -it --entrypoint /bin/bashou similar).
L0j1k
59
para sua conveniência, -ité uma combinação de -ie -tque é --interactive("Mantenha o STDIN aberto, mesmo que não esteja anexado"), respectivamente --tty("Aloque um pseudo-TTY").
Adrian Foder
23
Nos contêineres baseados no Alpine Linux, você pode não ter o bash; portanto, use sh.
Robin Green
9
@ L0j1k é docker run -it --entrypoint /bin/bash <imageid> --any --more --args, só para esclarecer para as pessoas
Alexander Mills
2
@AlexanderMills Sim, e para esclarecer ainda mais, aqueles que --any --more --argsvocê possui serão inseridos no que a imagem definiu como sendo CMDe não no Docker (ou se sua imagem definir apenas um ENTRYPOINTe não CMD, essas opções serão inseridas /bin/bashconforme especificado aqui. ) Assim, por exemplo, qualquer outra docker runopção (por exemplo --net "host") precisa ir antes da <imageid>.
L0j1k 22/05/19
302

Para bater em um contêiner em execução, digite o seguinte:

docker exec -t -i container_name /bin/bash

ou

docker exec -ti container_name /bin/bash

ou

docker exec -ti container_name sh
Agustí Sánchez
fonte
Presumindo que seja um contêiner Linux?
Peter Mortensen
5
/ bin / bash não era exigido apenas o bash fez isso por mim
Anand Varkey Philips
6
Eu preferiria em docker exec -itvez dedocker exec -t -i
VaTo
qual é a diferença @VaTo #
AATHITH RAJENDRAN
@AATHITHRAJENDRANI apenas prefere uma forma mais curta do comando em vez de ter dois sinalizadores, você pode incluir essas duas opções no mesmo argumento -it.
VaTo 23/07/19
85

Digamos que, por razões suas, você realmente deseja usar o SSH. São necessários alguns passos, mas isso pode ser feito. Aqui estão os comandos que você executaria dentro do contêiner para configurá-lo ...

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Agora você pode até executar aplicativos gráficos (se estiverem instalados no contêiner) usando o encaminhamento X11 para o cliente SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Aqui estão alguns recursos relacionados:

nobar
fonte
34

Se você está aqui procurando uma resposta específica do Docker Compose como eu, ela fornece uma maneira fácil, sem precisar procurar o ID do contêiner gerado.

docker-compose execleva o nome do serviço conforme seu docker-compose.ymlarquivo.

Portanto, para obter um shell Bash para o serviço 'web', você pode:

$ docker-compose exec web bash
bcmcfc
fonte
docker-compose runtambém funciona, se o seu contêiner ainda não existir.
Paul
23

Aviso : esta resposta promove uma ferramenta que escrevi.

Eu criei um servidor SSH em contêiner que você pode 'colar' em qualquer contêiner em execução. Dessa forma, você pode criar composições com cada contêiner. O único requisito é que o contêiner tenha Bash.

O exemplo a seguir iniciaria um servidor SSH conectado a um contêiner com o nome 'meu-contêiner'.

docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

ssh localhost -p 2222

Quando você se conecta a esse serviço SSH (com o cliente SSH de sua escolha), uma sessão Bash será iniciada no contêiner com o nome 'meu contêiner'.

Para mais informações e documentação, consulte: https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
fonte
1
Isso é muito fofo. A grande vantagem de fazer desta maneira é que você está recebendo um terminal totalmente funcional. Quando usei a abordagem "docker exec", não consegui limpar o conteúdo do terminal, lessestava exibindo um aviso toda vez que o rodava etc. O uso do contêiner de Jeroen está me proporcionando uma experiência muito melhor até agora. Apenas verifique a documentação . O comando de amostra na resposta não parece mais válido.
Rafał G. 18/06
1
é uma ótima ferramenta. Você sabe como posso usá-lo como um agente docker de pipeline de jenkins? i Quer Jenkins para transferir alguns arquivos pelo SCP para um host remoto e executá-los com SSH
Gilson
21

Se você estiver usando o Docker no Windows e quiser obter acesso de shell a um contêiner, use o seguinte:

winpty docker exec -it <container_id> sh

Provavelmente, você já tem o Git Bash instalado. Caso contrário, instale-o.

Cosmin Ababei
fonte
1
Presume um contêiner do Linux Docker?
Peter Mortensen
1
docker exec -ti <container_id> cmd funciona bem
PBo 16/01
17

Se o contêiner já tiver saído (talvez devido a algum erro), você poderá

$ docker run --rm -it --entrypoint /bin/ash image_name

ou

$ docker run --rm -it --entrypoint /bin/sh image_name

ou

$ docker run --rm -it --entrypoint /bin/bash image_name

para criar um novo contêiner e colocar um shell nele. Como você especificou --rm, o contêiner será excluído quando você sair do shell.

user674669
fonte
16

Em alguns casos, sua imagem pode ser baseada no Alpine. Nesse caso, ele lançará:

Falha no tempo de execução do OCI: exec falhou: container_linux.go: 348: o processo de contêiner iniciado causou "exec: \" bash \ ": arquivo executável não encontrado em $ PATH": desconhecido

Porque /bin/bashnão existe. Em vez disso, você deve usar:

docker exec -it 9f7d99aa6625 ash

ou

docker exec -it 9f7d99aa6625 sh
Deoxyseia
fonte
15

SSH em um contêiner Docker usando este comando:

sudo docker exec -i -t (container ID) bash
Tjs
fonte
12

Para conectar-se ao cmd em um contêiner do Windows, use

docker exec -it d8c25fde2769 cmd

Onde d8c25fde2769 é o ID do contêiner.

Aqeel Qureshi
fonte
11

É simples !

Liste todas as suas imagens do Docker:

sudo docker images

No meu sistema, ele mostrou a seguinte saída:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

Eu tenho duas imagens do Docker no meu PC. Digamos que eu queira executar o primeiro.

sudo docker run -i -t ubuntu:latest /bin/bash

Isso lhe dará controle terminal do contêiner. Agora você pode executar todos os tipos de operações de shell dentro do contêiner. Como fazer ls, todas as pastas serão exibidas na raiz do sistema de arquivos.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Patel Sunil
fonte
11

Para inspecionar arquivos, execute docker run -it <image> /bin/shpara obter um terminal interativo. A lista de imagens pode ser obtida por docker images. Ao contrário docker execdesta solução, também funciona quando uma imagem não inicia (ou fecha imediatamente após a execução).

eu vou
fonte
Presumindo uma imagem do Linux Docker?
Peter Mortensen
10

SOLUÇÃO GOINSIDE

instale a goinsideferramenta de linha de comando com:

sudo npm install -g goinside

e entre em um contêiner de encaixe com um tamanho de terminal adequado com:

goinside docker_container_name

resposta antiga

Colocamos este trecho em ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

Isso não apenas torna todos capazes de entrar em um contêiner em execução com:

goinside containername

Ele também resolve um problema de longa duração sobre os tamanhos fixos dos terminais de contêineres do Docker . O que é muito irritante se você enfrentar.

Além disso, se você seguir o link, também terá a conclusão do comando para os nomes dos contêineres do Docker.

Soorena
fonte
1
Obrigado. Funciona como um encanto, pelo menos para as imagens que já possuem o bash. Não pode funcionar para imagens com base alpinas, no entanto, pode ser corrigido com uma função diferente escrito especificamente para sh / cinzas etc.
Gaurav Bhaskar
8
$ docker exec -it <Container-Id> /bin/bash

Ou, dependendo da casca, pode ser

$ docker exec -it <Container-Id> /bin/sh

Você pode obter o ID do contêiner via docker pscomando

-i = interativo

-t = para alocar um psuedo-TTY

Ashutosh Chamoli
fonte
8

Eu criei uma função de terminal para facilitar o acesso ao terminal do contêiner. Talvez seja útil para vocês também:

Portanto, o resultado é, em vez de digitar:

docker exec -it [container_id] /bin/bash

você escreverá:

dbash [container_id]

Coloque o seguinte em seu ~ / .bash_profile (ou qualquer outra coisa que funcione para você), abra uma nova janela do terminal e aproveite o atalho:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}
Cara
fonte
7

você pode interagir com o terminal no container docker, passando a opção -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t significa terminal -i significa interativo

Alwin
fonte
6

docker execDefinitivamente será uma solução. Uma maneira fácil de trabalhar com a pergunta que você fez é montando o diretório dentro do Docker no diretório do sistema local .

Para que você possa visualizar as alterações no caminho local instantaneamente.

docker run -v /Users/<path>:/<container path> 
Pratik
fonte
1
seu comando está montando o diretório do host no contêiner.
Demonbane
sim! Faça um backup em outro diretório, monte o volume e mova o backup para a pasta montada.
Pratik
6

Usar:

docker attach <container name/id here>

A outra maneira, embora exista um perigo, é usar attach, mas se você Ctrl+ Csair da sessão, também interromperá o contêiner. Se você quiser apenas ver o que está acontecendo, use docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)
rbrooker
fonte
6

Use este comando:

docker exec -it containerid /bin/bash
Admin Hack
fonte
4

Se você tiver o Docker instalado Kitematic, poderá usar a GUI. Abra Kitematicno ícone do Docker e, na Kitematicjanela, selecione seu contêiner e clique no execícone.

Você pode ver o log do contêiner e muitas informações do contêiner (na guia Configurações) nesta GUI também.

Selecione Kitematic no menu

Clique em exec

Alireza Fattahi
fonte
2

No meu caso, por algum motivo, preciso verificar todas as informações envolvidas na rede em cada contêiner. Portanto, os seguintes comandos devem ser válidos em um contêiner ...

ip
route
netstat
ps
...

Eu verifiquei todas essas respostas, nenhuma foi útil para mim. Eu procurei informações em outros sites. Não adicionarei um super link aqui, pois ele não está escrito em inglês. Acabei de colocar este post com uma solução resumida para pessoas que têm os mesmos requisitos que eu.

Digamos que você tenha um contêiner em execução chamado light-test. Siga os passos abaixo.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Este comando receberá resposta como /var/run/docker/netns/xxxx.
  • Então ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. O diretório pode não existir, faça mkdir /var/run/netnsprimeiro.
  • Agora você pode executar ip netns exec xxxx ip addr showpara explorar o mundo da rede em contêiner.

PS. xxxxé sempre o mesmo valor recebido do primeiro comando. E, claro, quaisquer outros comandos são válidos, ie ip netns exec xxxx netstat -antp|grep 8080.

Light.G
fonte
1

Outra opção é usar o nsenter .

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
xuhdev
fonte
2
Existem vários problemas com nsenter. A primeira é que exige que você tenha acesso físico ao host do docker, o que não é um dado (você pode estar trabalhando com uma API do docker remoto). Além disso, a execução sob nsenterisenta você de várias restrições de segurança e recursos que o Docker coloca em prática (que pode ser um profissional ou um trapaceiro, dependendo do seu ambiente).
Larsks
1
Até o autor do nsenter diz usar docker exechoje em dia.
L0j1k
1
@larsks Sim, ambos têm seus próprios benefícios. Por exemplo, este é um benefício do nsenter over docker exec. docker execparece mais elegante para mim.
Xuhdev 11/05
2
@ L0j1k Apenas para ser menos confuso: a postagem que você indicou não é do autor do nsenter, mas do autor de uma imagem do Docker que executa o nsenter.
Xuhdev
1

Se você estiver usando o Docker Compose, isso o levará para dentro de um contêiner do Docker.

docker-compose run container_name /bin/bash

Dentro do contêiner, você será levado ao WORKDIR definido no Dockerfile. Você pode alterar seu diretório de trabalho

WORKDIR directory_path # E.g  /usr/src -> container's path
Sivakumar
fonte
0

Para executar em um contêiner em execução chamado test, abaixo estão os seguintes comandos

Se o contêiner tiver bashcasca

docker exec -it test /bin/bash

Se o contêiner tiver bournecasca e na maioria dos casos estiver presente

docker run -it test /bin/sh
nischay goyal
fonte
-3

Para composição do docker (Docker4Drupal)

docker-compose exec php bash

Eu uso o Docker for Drupal em um laptop Linux. Depois de executar o contêiner, eu uso ' docker-compose exec php bash' para conectar-me ao contêiner para poder executar comandos drush. Isso funciona bem para mim.

illutek
fonte