我如何进入Docker容器的shell?

And*_*rew 989 docker docker-container

我开始使用Docker了.我正在使用WordPress基本图像和docker-compose.

我正在尝试ssh到其中一个容器中来检查在初始构建期间创建的文件/目录.我试图跑docker-compose run containername ls -la,但那没有做任何事情.即使它确实如此,我宁愿有一个控制台,我可以遍历目录结构,而不是运行单个命令.使用Docker执行此操作的正确方法是什么?

lar*_*sks 1487

docker attach将让你连接到你的Docker容器,但这不是真的一样ssh.例如,如果容器正在运行Web服务器,docker attach则可能会将您连接到Web服务器进程的stdout.它不一定会给你一个shell.

这个docker exec命令可能就是你要找的; 这将允许您在现有容器中运行任意命令.例如:

docker exec -it <mycontainer> bash
Run Code Online (Sandbox Code Playgroud)

当然,您运行的任何命令都必须存在于容器文件系统中.

在上面的命令中<mycontainer>是目标容器的名称或ID.你是否在使用并不重要docker compose; 只需运行docker ps并使用ID(第一列中显示的十六进制字符串)或名称(显示在最后一列中).例如,给出:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 
Run Code Online (Sandbox Code Playgroud)

我可以跑:

$ 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
Run Code Online (Sandbox Code Playgroud)

我可以通过运行来完成同样的事情:

$ docker exec -it d2d4a89aaee9 ip addr
Run Code Online (Sandbox Code Playgroud)

同样,我可以在容器中启动一个shell;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
Run Code Online (Sandbox Code Playgroud)

  • 此外,`docker exec`仅适用于运行容器(否则使用`docker run -it --entrypoint/bin/bash`或类似). (62认同)
  • 为方便起见,`-it`是`-i`和`-t`的组合,它们是`--interactive`("即使没有附加也保持STDIN打开")`--tty`("Allocate a pseudo" -tty"). (52认同)
  • 在基于Alpine Linux的容器上,您可能没有bash,所以如果是这样,请使用sh代替. (16认同)
  • @ L0j1k是`docker run -it --entrypoint / bin / bash &lt;imageid&gt; --any --more --args`,只是为了向人们说明 (4认同)
  • 这只是一个基本的unix权限问题,并不是特别对docker(或这个问题或这个答案). (3认同)
  • @AlexanderMills 是的,为了进一步澄清,您拥有的那些 `--any --more --args` 将被输入到图像定义为它的 `CMD` 而不是 Docker 的任何内容中(或者如果你的图像只定义了一个 `ENTRYPOINT ` 并且没有 `CMD`,那么这些选项将被输入到 `/bin/bash` 中,正如您在此处指定的那样)。因此,例如任何其他 `docker run` 选项(例如 `--net "host"`)都需要放在 `&lt;imageid&gt;` 之前。 (3认同)

Agu*_*hez 275

要打入正在运行的容器,请键入:

docker exec -t -i container_name /bin/bash
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢`docker exec -it`而不是`docker exec -t -i` (5认同)
  • / bin/bash不是必需的,只是bash为我做了 (3认同)
  • 假设它是一个 Linux 容器? (2认同)
  • @nakamin根据文档,添加 -u 或 --user 标志将允许您指定用户。https://docs.docker.com/engine/reference/commandline/exec/ (2认同)

nob*_*bar 77

让我们说,由于你自己的原因,你真的想要使用SSH.它需要几个步骤,但它可以完成.以下是您将在容器内运行以进行设置的命令...

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)
Run Code Online (Sandbox Code Playgroud)

现在,您甚至可以使用X11转发到SSH客户端来运行图形应用程序(如果它们安装在容器中):

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client
Run Code Online (Sandbox Code Playgroud)

以下是一些相关资源:

  • 在我写这个答案时,问题的标题是:“如何 ssh 到 docker 容器?” 多年来,问题和答案一直被闯入者和机器人编辑——在某些情况下,可能会改变意图。我之前的评论已被匿名删除。 (3认同)

Jer*_*ers 23

注意:这个答案促进了我写的工具.

我已经创建了一个容器化的SSH服务器,您可以"粘贴"任何正在运行的容器.这样您就可以为每个容器创建合成.唯一的要求是容器有Bash.

以下示例将启动连接到名为"my-container"的容器的SSH服务器.

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
Run Code Online (Sandbox Code Playgroud)

当您连接到此SSH服务(使用您选择的SSH客户端)时,将在名为"my-container"的容器中启动Bash会话.

有关更多指示和文档,请参阅:https://github.com/jeroenpeeters/docker-ssh


bcm*_*cfc 23

如果您正在寻找像我一样的Docker Compose特定答案,它提供了一种简单的方法,而无需查找生成的容器ID.

docker-compose exec根据您的docker-compose.yml文件获取服务的名称.

因此,要为您的"网络"服务获取Bash shell,您可以执行以下操作:

$ docker-compose exec web bash
Run Code Online (Sandbox Code Playgroud)


Cos*_*bei 17

如果您在Windows上使用Docker并希望获得对容器的shell访问权限,请使用以下命令:

winpty docker exec -it <container_id> sh
Run Code Online (Sandbox Code Playgroud)

最有可能的是,你已经安装了Git Bash.如果不这样做,请确保安装它.


小智 15

使用以下命令SSH到Docker容器中:

sudo docker exec -i -t (container ID) bash
Run Code Online (Sandbox Code Playgroud)

  • 或者短一点:`sudo docker exec -it &lt;container ID&gt; bash` (2认同)

art*_*boy 14

2022年解决方案

考虑另一种选择

你为什么需要它?

有一堆基于distroless基础镜像的现代 docker 镜像(它们两者都没有/bin/bash/bin/sh),因此不可能docker exec -it {container-name} bash进入它们。

如何对任何容器进行脱壳

使用开瓶器

  • 需要在您的环境中添加别名opener wordpress
  • 任何地方都可以工作docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock artemkaxboy/opener wordpress

wordpress可以使用要连接的任何容器的名称或 ID 或图像名称


怎么运行的

Opener是一组包装在 docker 镜像中的 python 脚本。它通过任何唯一属性(名称、ID、端口、图像)查找目标容器,尝试使用bash. 如果bash未找到,开启程序将尝试使用 进行连接sh。最后,如果sh未找到,则 opener 将安装busybox到目标容器中并使用 busybox shell 连接到目标,opener 将busybox在断开连接期间删除。


Aqe*_*shi 12

要连接到Windows容器中的cmd,请使用

docker exec -it d8c25fde2769 cmd
Run Code Online (Sandbox Code Playgroud)

其中d8c25fde2769是容器ID.


Deo*_*eia 12

在某些情况下,您的图像可以基于阿尔卑斯山.在这种情况下,它将抛出:

OCI运行时exec失败:exec失败:container_linux.go:348:启动容器进程导致"exec:\"bash \":$ PATH中找不到可执行文件":未知

因为/bin/bash不存在.而不是这个你应该使用:

docker exec -it 9f7d99aa6625 ash
Run Code Online (Sandbox Code Playgroud)

要么

docker exec -it 9f7d99aa6625 sh
Run Code Online (Sandbox Code Playgroud)


Guy*_*Guy 12

我创建了一个终端功能,以便更轻松地访问容器的终端。也许对你们也有用:

所以结果是,而不是键入:

docker exec -it [container_id] /bin/bash
Run Code Online (Sandbox Code Playgroud)

你会写:

dbash [container_id]
Run Code Online (Sandbox Code Playgroud)

将以下内容放入您的 ~/.bash_profile (或任何其他适合您的文件),然后打开一个新的终端窗口并享受快捷方式:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}
Run Code Online (Sandbox Code Playgroud)


use*_*669 11

如果容器已经退出(可能是由于某些错误),则可以执行

$ docker run --rm -it --entrypoint /bin/ash image_name
Run Code Online (Sandbox Code Playgroud)

要么

$ docker run --rm -it --entrypoint /bin/sh image_name
Run Code Online (Sandbox Code Playgroud)

要么

$ docker run --rm -it --entrypoint /bin/bash image_name
Run Code Online (Sandbox Code Playgroud)

创建一个新容器并放入一个外壳。由于您指定了--rm,因此退出外壳程序时将删除该容器。


Soo*_*ena 8

GOINSIDE SOLUTION

安装goinside命令行工具:

sudo npm install -g goinside
Run Code Online (Sandbox Code Playgroud)

并进入具有适当终端尺寸的docker容器内:

goinside docker_container_name
Run Code Online (Sandbox Code Playgroud)

老答案

我们把这个片段放在~/.profile:

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

这不仅使每个人都能够进入一个正在运行的容器中:

goinside containername
Run Code Online (Sandbox Code Playgroud)

它还解决了有关固定Docker容器终端大小的长期问题.如果你面对它,这是非常烦人的.

此外,如果您按照链接,您也将获得Docker容器名称的命令完成.


小智 8

很简单!

列出所有Docker镜像:

sudo docker images
Run Code Online (Sandbox Code Playgroud)

在我的系统上,它显示以下输出:

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
Run Code Online (Sandbox Code Playgroud)

我的电脑上有两个Docker镜像.假设我想运行第一个.

sudo docker run -i -t ubuntu:latest /bin/bash
Run Code Online (Sandbox Code Playgroud)

这将使您终端控制容器.现在,您可以在容器内执行所有类型的shell操作.喜欢做ls就会输出文件系统根目录下的所有文件夹.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Run Code Online (Sandbox Code Playgroud)


nis*_*yal 8

要执行到名为 的正在运行的容器中test,下面是以下命令

如果容器有bash

docker exec -it test /bin/bash
Run Code Online (Sandbox Code Playgroud)

如果容器有bourne壳并且大多数情况下都有壳

docker run -it test /bin/sh
Run Code Online (Sandbox Code Playgroud)


小智 6

使用:

docker attach <container name/id here>
Run Code Online (Sandbox Code Playgroud)

尽管有危险,但另一种方法是使用attach,但是如果您Ctrl+ C退出会话,则也将停止容器。如果您只想查看发生了什么,请使用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)
Run Code Online (Sandbox Code Playgroud)


Adm*_*ack 6

使用此命令:

docker exec -it containerid /bin/bash
Run Code Online (Sandbox Code Playgroud)


ter*_*der 6

根据目标,至少有 2 个选项。

选项 1:创建一个新的 bash 进程并加入其中(更简单)

  • 示例开始: docker exec -it <containername> /bin/bash
  • 退出:输入 exit
  • 优点:适用于所有容器(不依赖于 CMD/Entrypoint)
  • 反对:使用自己的会话和自己的环境变量创建一个新进程

选项 2:附加到已经运行的 bash (更好)

  • 示例开始: docker attach --detach-keys ctrl-d <containername>
  • 退出:使用键ctrld
  • Pro:加入容器中完全相同的运行 bash。您具有相同的会话和相同的环境变量。
  • 反对:仅当 CMD/Entrypoint 是交互式 bashCMD ["/bin/bash"]CMD ["/bin/bash", "--init-file", "myfile.sh"] AND如果容器已使用交互式选项启动时才有效,例如docker run -itd <image>(-i=interactive, -t=tty 和 -d=deamon [opt])

我们发现选项 2 更有用。例如,我们更改apache2-foreground为普通背景apache2并在此bash之后启动。


小智 5

docker exec肯定是一个解决方案。处理您所问问题的一种简单方法是将Docker内部的目录挂载到本地系统的目录中

这样您可以立即查看本地路径中的更改。

docker run -v /Users/<path>:/<container path> 
Run Code Online (Sandbox Code Playgroud)


igo*_*igo 5

要检查文件,请运行docker run -it <image> /bin/bash以获取交互式终端。可以通过获取图像列表docker images。与docker exec该解决方案相反,在图像不启动(或在运行后立即退出)的情况​​下也可以使用。


Ash*_*oli 5

$ docker exec -it <Container-Id> /bin/bash
Run Code Online (Sandbox Code Playgroud)

或者取决于外壳,它可以是

$ docker exec -it <Container-Id> /bin/sh
Run Code Online (Sandbox Code Playgroud)

您可以通过命令获取container-Iddocker ps

-i =互动

-t =分配伪TTY


小智 5

您可以通过传递选项-ti与docker容器中的终端进行交互

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu
Run Code Online (Sandbox Code Playgroud)

-t代表终端-i代表互动


Mas*_*ick 5

如果您不想在 docker 构建文件中指定入口点,这是最好的选择。

sudo docker run -it --entrypoint /bin/bash <container_name>
Run Code Online (Sandbox Code Playgroud)