Docker 容器与卷
Docker 容器的文件系统可以像任何文件夹一样在面板中浏览,Docker 卷也一样。在网络菜单中选择连接到 Docker…,或点击驱动器栏中的 Docker 标签,引擎便会出现在活动面板中。
这是一个插件,并且出厂时是关闭的。请在配置 ▸ 插件…中开启。它默认关闭,是因为与 Docker 守护进程的连接在这台 Mac 上拥有与你相同的权限——见下文的它能访问什么。
你会看到什么¶
顶层是三个文件夹:
- Compose Projects — 由 Docker Compose 启动的全部容器,先按项目、再按服务分组。只有一个容器的服务就是那个容器:
my-stack/backend/etc就是后端的/etc。有多个副本的服务会为它们保留一层,每个容器一个文件夹。 - Standalone Containers — 其余的一切,无论是否在运行。
- Volumes — 每个 Docker 卷,各自作为一个驱动器。
再往下就是真正的文件系统:F3 查看文件,F4 编辑,F5 复制到另一个面板,F7 新建文件夹。另一个面板可以是任何东西——本地文件夹、压缩包、S3 存储桶。
分组是从 Compose 给自己容器和卷打的标签中读取的,因此即使某个栈的 docker-compose.yml 早已不在这台机器上,分组依然正确。
卷单独列出是有意为之。 卷的寿命长于创建它的容器,可以被多个容器共享,而你要找的数据通常正是在卷里。当前没有任何容器挂载的卷同样可以浏览。
列¶
右键点击面板的列标题,即可添加此提供程序自己的列:
- 状态 —
● running、○ stopped、◌ paused、! restarting。 - 访问 —
RW;只读根文件系统或只读挂载为RO;Docker 卷为VOL;挂载进容器的你自己的文件夹为BIND;tmpfs 为TMP。 - 镜像、ID。
- 挂载 — 对于实际上是挂载点的目录,说明它是什么:
Volume: my-stack_db-data,或 bind 背后的主机路径。你就是这样找到 Volumes 下的哪个卷存放着某个容器的数据。
已停止的容器¶
已停止的容器同样会列出,其文件系统可读可写。Docker 的文件 API 对一个月没运行过的容器也会作答,这正是它像驱动器而非进程列表的原因。
有两件事需要真正在运行的容器:删除和重命名。Docker Engine API 对这两者都没有相应操作——在容器内删除或移动文件的唯一办法就是在其中执行些什么——因此对已停止的容器,两者都会被拒绝,而不是佯装成功。
该期待什么¶
写入以 root 身份进入,删除则以容器自身的用户身份执行。 这是 Docker 的安排,而非此处的选择:把文件复制进去使用引擎的归档 API,它以 root 写入;删除或重命名则在容器内执行命令,而该命令以镜像配置的用户身份运行。因此,刚刚还能复制进去的文件,删除时可能因权限被拒绝而失败。Peach Commander 不会以 root 身份去绕过这一点,而是把容器说的话告诉你。
只读的容器或挂载会拒绝写入,并将其报告为权限错误而非失败。
读取符号链接读到的是它指向的内容。 面板在 Attr 列中仍将其显示为链接;F3 显示目标的内容,而不是一个空文件。
较大的已停止容器,其根目录可能无法列出。 Docker 没有任何用于列出目录的调用。读取一个目录意味着把它作为归档取回,而归档包含其下的一切——对于基于完整镜像构建的已停止容器,这可能是数十 GB,因此列出会被拒绝,而不是把全部读完。更深层的目录不受影响,正在运行的容器也不受影响:过大而无法作为归档读取的目录由容器自己列出。若你只想走归档这条路,请见下面的设置。
把整个容器复制出来,就是复制它的整个文件系统——包括 /proc 和 /dev。请复制你需要的目录,而不是 /。
它能访问什么¶
此插件与你在终端里会连到的引擎对话:若你设置了 DOCKER_HOST 就用它,否则用当前的 docker context,再否则用 Docker Desktop、Colima、Rancher Desktop、Lima 和 Podman 的常见套接字。Podman 之所以可用,是因为它提供同样的 API。
访问 Docker 守护进程通常意味着对其所在机器的广泛访问。此插件拥有的权限与你完全相同,并且不多要一分:它不保存任何凭据,从不触碰你磁盘上 Docker 自己的目录,也不代表你执行任何特权操作。
它唯一会创建的是一个一次性容器——而且只是为了访问没有任何现存容器挂载的卷,因为卷只有从挂载它的东西内部才看得见。该容器从不启动,带有 Peach Commander 的标签,并在你离开该驱动器时被移除。
对容器或卷的操作¶
右键点击容器或卷,Docker 子菜单会提供驱动器本身说不出来的东西:
- Inspect — 引擎所知道的关于它的一切,以格式化的 JSON 显示在一个可以滚动、可以选取的窗口 里。
- Show Logs — 该容器写出的最后 500 行。
- Show Mounts — 它所带的每一个挂载、各自是什么,以及能否写入。
- Copy ID — 把容器的完整 id 或卷的名字放到剪贴板。是完整的 id,不是 ID 列显示的那十二个字符:
这是为了粘贴进
docker命令,而短 id 只是一个前缀,可能有一天不再唯一。 - Jump to Volume — 在一个实际上是卷的目录上,前往 Volumes 下的那个卷。这是挂载列的另一半: 列告诉你是哪个卷,这一项把你带过去。
- Open Compose Project — 前往该容器所属的项目。
- Start、Stop、Restart、Pause、Unpause — 这些是改变容器而不是读取它,所以会先 询问。Start 也是上面那两条拒绝的出口:删除和重命名需要一个正在运行的容器。
这些条目只在 Docker 驱动器内出现;在你自己的文件夹上根本不存在。
日志同时也是一个文件。 每个容器的根目录下都有 docker-logs.txt——它并不是容器里的文件:读取它是向引擎索取日志。在它上面按 F3 会在查看器中打开,于是查看器的搜索、跳转到某一行和编码选择都适用,这是单独一个窗口给不了的。真正带有同名文件的容器显示它自己的那个,而虚拟的这个无法写入。
设置¶
配置 ▸ 设置 ▸ Docker 里有全部这些。同样的值也在 ~/Library/Application Support/PeachCommander/Docker/docker.ini 的一个小文件里——用脚本准备机器时改的就是它:
Endpoint— 用来代替自动找到的地址。ExecFallback— 设为0时,插件只使用 Docker 的归档 API:它便绝不会在容器内执行任何东西,代价是无法列出非常大的目录,也无法删除和重命名。ProbeBudgetMB、MaxBudgetMB、MaxBudgetSeconds— 在退而求其次或放弃之前,一个目录的归档值得读取多少。HelperImage— 上述一次性容器所用的镜像(默认为机器上已有的任意镜像)。ShowAnonymousVolumes— 设为0时,隐藏那些因无人命名而被 Docker 用长哈希当作名字的卷。
此版本中没有的¶
通过 SSH 或 TLS 连接的远程引擎、交互式 shell,以及作为只读文件系统的镜像。