1622

我开始使用 Docker。我正在使用 WordPress 基础镜像和 docker-compose。

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

4

27 回答 27

2331

docker attach将让您连接到您的 Docker 容器,但这与ssh. 例如,如果您的容器正在运行网络服务器,docker attach则可能会将您连接到网络服务器进程的标准输出。它不一定会给你一个外壳。

docker exec命令可能是您正在寻找的;这将允许您在现有容器内运行任意命令。例如:

docker exec -it <mycontainer> bash

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

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

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

我可以跑:

$ 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

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

$ docker exec -it d2d4a89aaee9 ip addr

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

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
于 2015-05-11T16:44:52.333 回答
389

要 bash 进入正在运行的容器,请输入:

docker exec -t -i container_name /bin/bash

或者

docker exec -ti container_name /bin/bash

或者

docker exec -ti container_name sh
于 2015-10-11T01:34:24.003 回答
109

历史记录:在我写这个答案时,问题的标题是:“如何 ssh 进入 docker 容器?”

正如其他答案所证明的那样,使用docker exec不是 SSH在本地可访问的运行容器中执行预安装的命令(包括 shell)并与之交互是很常见的:

docker exec -it (container) (command)

注意:以下答案基于 Ubuntu(2016 年)。非 Debian 容器需要对安装过程进行一些翻译。

比方说,出于您自己的原因,您确实想使用 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)

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

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

以下是一些相关资源:

于 2016-05-16T03:36:26.413 回答
48

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

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

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

$ docker-compose exec web bash
于 2017-11-24T09:21:39.447 回答
28

注意:此答案推广了我编写的工具。

我创建了一个容器化的 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

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

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

于 2015-10-03T20:56:09.293 回答
28

使用以下命令启动到 Docker 容器的会话:

sudo docker exec -i -t (container ID) bash
于 2015-11-18T09:43:50.573 回答
28

如果容器已经退出(可能是由于一些错误),你可以这样做

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

或者

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

或者

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

创建一个新容器并将外壳放入其中。由于您指定了 --rm,因此当您退出 shell 时,容器将被删除。

于 2018-11-09T06:26:28.513 回答
25

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

winpty docker exec -it <container_id> sh

很可能,您已经安装了Git Bash如果没有,请确保安装它。

于 2017-02-09T09:04:32.590 回答
24

在某些情况下,您的图像可以是基于 Alpine 的。在这种情况下,它会抛出:

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

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

docker exec -it 9f7d99aa6625 ash

或者

docker exec -it 9f7d99aa6625 sh
于 2018-04-27T05:26:30.683 回答
19

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

docker exec -it d8c25fde2769 cmd

其中d8c25fde2769是容器 ID。

于 2017-06-13T08:50:11.767 回答
15

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

于 2017-09-17T19:45:59.620 回答
14

GOINSIDE解决方案

安装goinside命令行工具:

sudo npm install -g goinside

并进入具有适当终端大小的 docker 容器:

goinside docker_container_name

旧答案

我们已将此片段放入~/.profile

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

这不仅使每个人都能够通过以下方式进入正在运行的容器:

goinside containername

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

此外,如果您点击链接,您的 docker 容器名称也将完成命令。

于 2018-03-14T15:16:14.003 回答
13

这很简单

列出所有 Docker 镜像:

sudo docker images

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

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

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

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

这将使您对容器进行终端控制。现在您可以在容器内执行所有类型的 shell 操作。像这样ls会输出文件系统根目录下的所有文件夹。

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
于 2018-07-12T08:47:42.447 回答
12

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

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

docker exec -it [container_id] /bin/bash

你会写:

dbash [container_id]

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

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}
于 2019-07-16T08:34:57.463 回答
9
$ docker exec -it <Container-Id> /bin/bash

或者根据外壳,它可以是

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

您可以通过命令获取容器 IDdocker ps

-i= 互动

-t= 分配一个伪 TTY

于 2019-01-22T05:46:43.443 回答
8

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

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

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

于 2019-03-11T17:46:09.550 回答
8

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

选项 1:创建一个新的 bash 进程并加入它(更容易)

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

选项 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之后启动。

于 2020-07-23T16:04:16.890 回答
7

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

这样您就可以立即查看本地路径的变化。

docker run -v /Users/<path>:/<container path> 
于 2015-05-12T05:19:17.560 回答
7

采用:

docker attach <container name/id here>

另一种方法,虽然有危险,但使用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)
于 2017-02-02T18:03:02.760 回答
7

使用这个命令:

docker exec -it containerid /bin/bash
于 2018-07-26T13:02:34.817 回答
4

如果您安装了 Docker Kitematic,则可以使用 GUI。从 Docker 图标打开Kitematic并在Kitematic窗口中选择您的容器,然后单击该exec图标。

您也可以在此 GUI 中查看容器日志和大量容器信息(在设置选项卡中)。

从菜单中选择 Kitematic

点击执行

于 2018-04-29T03:56:44.263 回答
4

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

如果容器有bash外壳

docker exec -it test /bin/bash

如果容器有bourne外壳并且大多数情况下它存在

docker run -it test /bin/sh
于 2020-05-31T23:52:50.943 回答
2

就我而言,出于某种原因,我需要检查每个容器中涉及的所有网络信息。所以以下命令必须在容器中有效......

ip
route
netstat
ps
...

我检查了所有这些答案,没有一个对我有帮助。我在其他网站上搜索过信息。我不会在这里添加超级链接,因为它不是用英文写的。因此,我只是为与我有相同要求的人提供了一个摘要解决方案。

假设您有一个名为 light-test 的正在运行的容器。请按照以下步骤操作。

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. 该命令将得到类似的回复/var/run/docker/netns/xxxx
  • 然后ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx。该目录可能不存在,mkdir /var/run/netns请先执行。
  • 现在您可以执行ip netns exec xxxx ip addr show以探索容器中的网络世界。

PS。xxxx始终与从第一个命令接收到的值相同。当然,任何其他命令都是有效的,即ip netns exec xxxx netstat -antp|grep 8080.

于 2018-09-04T04:48:54.127 回答
1

另一种选择是使用nsenter

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
于 2015-05-11T17:32:49.020 回答
1

如果您使用的是 Docker Compose,那么这将带您进入 Docker 容器。

docker-compose run container_name /bin/bash

在容器内部,它将带您到 Dockerfile 中定义的 WORKDIR。您可以通过以下方式更改工作目录

WORKDIR directory_path # E.g  /usr/src -> container's path
于 2018-02-02T11:37:02.127 回答
1

有两个选项我们可以使用这些方法直接连接到 docker 终端shellbash但通常不支持 bash 并且默认支持 sh 终端要 sh 进入正在运行的容器,请输入:

docker exec -it container_name/container_ID sh

要 bash 进入正在运行的容器,请输入:

docker exec -it container_name/container_ID bash

并且您只想使用 bash 终端,而不是像您Dockerfile一样安装 bash 终端RUN apt install bash -y

于 2022-02-07T16:02:44.653 回答
-4

对于 docker-compose up (Docker4Drupal)

docker-compose exec php bash

我在 Linux 笔记本电脑上使用Docker for Drupal 。运行容器后,我使用“ docker-compose exec php bash”连接容器,这样我就可以运行 drush commandos。这对我来说可以。

于 2017-09-11T17:04:57.977 回答