1. 简介
在排查 Docker 容器问题时,我们有时需要查看容器内部运行的完整命令。幸运的是,Docker 提供了多种方式来查看运行中或已停止的容器的完整命令。

在本教程中,我们将探讨如何使用 docker psdocker inspect 以及第三方工具 runlike 来查看容器的命令。此外,我们还会分析在命令信息不完整时的应对方法。


2. 使用 docker ps
我们先运行一个 nginx:alpine 容器,并尝试查看其命令:

$ docker run -dp 8080:80 nginx:alpine
d00809d57....
admin@baeldung:~$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                   NAMES
d00809d57ae9   nginx:alpine   "/docker-entrypoint.…"   7 seconds ago   Up 7 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   confident_rubin

默认输出并未显示完整命令。为解决这个问题,可以使用 --no-trunc 参数:

$ docker ps -a --no-trunc
CONTAINER ID       IMAGE          COMMAND                                          CREATED         STATUS         PORTS                                   NAMES
d00809d57ae90...   nginx:alpine   "/docker-entrypoint.sh nginx -g 'daemon off;'"   4 minutes ago   Up 4 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   confident_rubin

如果只想显示关键信息,可配合 --format 使用:

$ docker ps -a --no-trunc --format "table{{.Names}}\t{{.CreatedAt}}\t{{.Command}}" 
NAMES             CREATED AT                      COMMAND
confident_rubin   2025-01-19 13:33:15 +0000 UTC   "/docker-entrypoint.sh nginx -g 'daemon off;'"

⚠️ 但要注意,这种方式不会显示命令中使用的环境变量值。


3. 使用 docker inspect
docker inspect 是一个更强大的命令,可以查看容器的详细状态信息,包括环境变量等。

查看 nginx 容器的入口命令:

$ docker inspect confident_rubin
[
    {
...
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
...
    }
]

可使用 jq 工具过滤输出:

$ docker inspect confident_rubin | jq '.[] | {Path,Args}'
{
  "Path": "/docker-entrypoint.sh",
  "Args": [
    "nginx",
    "-g",
    "daemon off;"
  ]
}

我们还可以运行一个带环境变量的容器来展示更复杂的情况:

$ docker run -dit -e OS_RELEASE_PATH=/etc/os-release alpine:3.21 sh -c 'cat ${OS_RELEASE_PATH}'

使用 docker inspect 查看完整命令和环境变量:

$ docker inspect trusting_cohen -f '{{.Name}} {{.Config.Env}} {{.Path}} {{.Args}}'
  fervent_hoover [OS_RELEASE_PATH=/etc/os-release PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin] sh [-c cat ${OS_RELEASE_PATH}]

4. 使用 runlike
runlike 是一个开源工具,可以根据已有容器的 ID 或名称输出重新运行该容器所需的完整命令。

安装并运行:

$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike trusting_cohen
docker run --name=trusting_cohen --hostname=90753df1e7f0 --env=OS_RELEASE_PATH=/etc/os-release --network=bridge --workdir=/ --runtime=runc -t alpine:3.21 sh -c 'cat ${OS_RELEASE_PATH}'

✅ 优点:输出中包含环境变量、网络配置、运行参数等,非常完整。


5. 查看 /docker-entrypoint.sh 命令
很多容器的命令只是执行了 /docker-entrypoint.sh 脚本。这时我们需要手动查看脚本运行了什么。

mysql:8.0-debian 为例:

$ docker run -d -e MYSQL_ROOT_PASSWORD=passwd123 mysql:8.0-debian

查看命令:

$ docker ps --no-trunc --format "table{{.Names}}\t{{.Command}}\t{{.Image}}"
NAMES                  COMMAND                         IMAGE
pedantic_stonebraker   "docker-entrypoint.sh mysqld"   mysql:8.0-debian

使用 ps 查看 PID 1 的进程:

$ docker exec pedantic_stonebraker ps -1
    PID TTY      STAT   TIME COMMAND
      1 ?        Ssl    0:43 mysqld

若无 ps 命令,可查看 /proc/1/cmdline

$ docker exec pedantic_stonebraker cat /proc/1/cmdline
mysqld

6. 总结
本文介绍了几种查看 Docker 容器完整命令的方法:

方法 是否显示环境变量 是否显示完整命令 备注
docker ps 简单但不完整
docker inspect 更强大,建议使用
runlike 可直接用于复制启动命令
/proc/1/cmdline 仅当前命令 适用于 entrypoint 场景

✅ 推荐组合使用 docker inspect + runlike,基本可以覆盖所有查看需求。


原始标题:Viewing Full Commands of Running or Stopped Docker Containers