1. 概述

Docker Compose 可以根据 docker-compose.yml 文件中定义的服务自动启动并运行相关容器。但是一旦容器运行起来之后,Docker 并没有直接提供一个命令来查看是哪个 docker-compose.yml 文件启动了这些容器。

在实际运维过程中,我们可能会遇到这样的问题:需要管理和重启服务,却记不起 docker-compose.yml 文件的具体路径。本文将介绍如何通过一个正在运行的容器来反向定位其对应的 docker-compose.yml 文件的位置。

2. 问题分析

Docker 和 Docker Compose 是紧密协作的工具。Docker Compose 会将 docker-compose.yml 中的配置转换为一系列的 Docker 命令来启动容器。然而,Docker 本身并不记录启动容器时所使用的 docker-compose.yml 文件的路径,这就导致我们无法直接通过容器反推配置文件的位置。

不过,Docker Compose 会在创建容器时设置一些元数据(metadata),其中就包括标签(labels)。这些标签中包含项目名称等信息,我们可以利用这些信息来辅助定位 docker-compose.yml 文件。

举个例子:

$ tree
.
├── first_compose_project
│   └── docker-compose.yml
└── second_compose_project
    └── docker-compose.yml

2 directories, 2 files

如上结构所示,我们有两个 Docker Compose 项目目录,每个目录下都有一个 docker-compose.yml 文件。接下来我们将通过容器信息来定位这些文件。

3. 使用标签定位 docker-compose.yml

我们可以通过容器的标签信息来定位其对应的 docker-compose.yml 文件。

3.1 查看容器标签信息

使用 docker inspect 命令可以查看容器的详细信息,包括标签:

$ docker inspect container_name

我们重点关注输出中的如下标签字段:

"Labels": {
    "com.docker.compose.project": "project_name",
}

这个标签的值就是项目的名称,通常和 docker-compose.yml 所在目录名一致。

3.2 列出所有 Compose 容器

我们可以使用 docker ps 命令并结合标签过滤器列出所有由 Docker Compose 启动的容器:

$ docker ps --filter "label=com.docker.compose.project"
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                    NAMES
6981dadd4d23   postgres:13       "docker-entrypoint.s…"   39 minutes ago   Up 39 minutes   5432/tcp                 second_compose_project_db_1
ddb325f5d405   python:3.9-slim   "python -m http.serv…"   39 minutes ago   Up 39 minutes   0.0.0.0:8000->8000/tcp   second_compose_project_app_1
682358d4a278   nginx:latest      "/docker-entrypoint.…"   39 minutes ago   Up 39 minutes   0.0.0.0:8080->80/tcp     first_compose_project_web_1
ef3a66d20fd1   redis:latest      "docker-entrypoint.s…"   39 minutes ago   Up 39 minutes   6379/tcp                 first_compose_project_redis_1

进一步提取容器名称:

$ docker ps --filter "label=com.docker.compose.project" --format "{{.Names}}"
second_compose_project_db_1
second_compose_project_app_1
first_compose_project_web_1
first_compose_project_redis_1

接着,使用 docker inspect 提取每个容器的项目名:

$ docker inspect --format '{{ index .Config.Labels "com.docker.compose.project" }}' $container_name

通过项目名,我们就能定位到对应的 docker-compose.yml 文件路径,例如:

/home/maurice/docker-management/$project_name/docker-compose.yml

3.3 使用 Bash 脚本自动化定位

为了简化操作,我们可以编写一个 Bash 脚本来自动化整个过程。

创建文件 find_compose_script.sh

#!/bin/bash

base_dir="/home/maurice/docker-management"

containers=$(docker ps --filter "label=com.docker.compose.project" --format "{{.Names}}")

for container in $containers; do
    project_name=$(docker inspect -f '{{ index .Config.Labels "com.docker.compose.project" }}' $container)
    compose_file="$base_dir/$project_name/docker-compose.yml"

    if [ -f "$compose_file" ]; then
        echo "For project $project_name, docker-compose.yml was located at $compose_file"
        cd "$base_dir/$project_name" && docker-compose -f $compose_file restart
        echo
    else
        echo "docker-compose.yml for project $project_name not found!"
    fi
done

运行脚本输出示例:

$ bash find_compose_script.sh
For project second_compose_project, docker-compose.yml was located at /home/maurice/docker-management/second_compose_project/docker-compose.yml
Restarting second_compose_project_db_1  ... done
Restarting second_compose_project_app_1 ... done

For project first_compose_project, docker-compose.yml was located at /home/maurice/docker-management/first_compose_project/docker-compose.yml
Restarting first_compose_project_web_1   ... done
Restarting first_compose_project_redis_1 ... done

✅ 脚本逻辑清晰,适用于多个项目目录结构的场景。

4. 总结

通过本文,我们掌握了如何从一个正在运行的容器中定位其对应的 docker-compose.yml 文件路径。

核心方法是利用 Docker Compose 在容器上设置的标签 com.docker.compose.project,结合 docker inspectdocker ps 命令获取项目名,从而定位文件路径。同时,我们还提供了一个 Bash 脚本用于自动化操作,提升运维效率。

⚠️ 注意:此方法依赖于你对项目目录结构的了解。如果项目不是按照 docker-compose project name 命名目录的,可能需要调整脚本逻辑。

通过掌握这些技巧,你可以更轻松地管理多个 Docker Compose 项目,避免“找不到配置文件”的尴尬。


原始标题:Finding the Location of docker-compose.yml From a Running Container