Python 如何检测当前 Python 是否运行在 Docker 容器里

最可靠方法是检查/proc/1/cgroup文件是否包含docker、lxc、crio或containerd等字符串,辅以/.dockerenv文件存在性验证,兼顾cgroup v1/v2兼容性与容器运行时多样性。

可以通过检查特定的系统文件或环境特征来判断 Python 是否运行在 Docker 容器中。最常用、可靠且轻量的方法是读取 /proc/1/cgroup 文件并查找容器相关标识(如 dockerlxccrio 等)。

检查 /proc/1/cgroup 文件内容

在 Linux 容器中,进程 1(通常是 init 或容器入口进程)的 cgroup 信息会包含容器运行时的标识。Docker 默认使用 docker- 前缀或 systemd 下的 docker- slice,而较新版本(尤其是使用 cgroup v2 的环境)可能出现在 io.containerd.docker- 字符串中。

Python 示例代码:

def is_running_in_docker():
    try:
        with open('/proc/1/cgroup', 'r') as f:
            for line in f:
                if 'docker' in line or 'lxc' in line or 'crio' in line or 'containerd' in line:
                    return True
        # cgroup v2 场景:检查 /proc/1/mountinfo 或 /proc/1/cgroup 路径是否含 containerd/docker
        with open('/proc/1/cgroup', 'r') as f:
            content = f.read()
            if 'containers' in content and ('docker' in content or 'containerd' in content):
                return True
    except (FileNotFoundError, PermissionError):
        pass
    return False

print(is_running_in_docker()) # True / False

检查 /proc/1/environ 是否含容器环境变量

部分容器运行时(如 Docker)会在 PID 1 进程的环境变量中注入特定字段,例如 container=lxccontainer=docker。虽然不是所有 Docker 配置都启用该行为(取决于 --env 或守护进程配置),但仍可作为辅助判断依据。

用法示例:

def is_container_env_var_set():
    try:
        with open('/proc/1/environ', 'rb') as f:
            env_bytes = f.read()
            env_str = env_bytes.decode('utf-8', errors='ignore')
            for pair in env_str.split('\x00'):
                if pair.startswith('container='):
                    value = pair.split('=', 1)[1].strip().lower()
                    if value in ('docker', 'lxc', 'runc', 'containerd'):
  

return True except (FileNotFoundError, PermissionError): pass return False

检查是否存在典型容器路径或文件

某些容器运行时会在文件系统中留下痕迹,例如:

  • /.dockerenv:Docker 传统标识文件(存在即强信号,但部分镜像或 rootless 模式下可能缺失)
  • /proc/1/cgroup 中包含 docker-lxc-crio-io.containerd. 等字符串
  • /proc/sys/fs/binfmt_misc/ 下有容器相关注册项(较少用)

推荐组合使用,提高鲁棒性:

import os

def is_in_docker():

方法1:检查 /.dockerenv

if os.path.exists('/.dockerenv'):
    return True
# 方法2:检查 cgroup 内容
try:
    with open('/proc/1/cgroup', 'r') as f:
        for line in f:
            if any(x in line for x in ['docker', 'lxc', 'crio', 'containerd', 'systemd/docker']):
                return True
except OSError:
    pass
return False

注意点与边界情况

以下情况可能导致误判或漏判:

  • 使用 podmanrootless Docker 时,/.dockerenv 可能不存在,需依赖 cgroup 判断
  • cgroup v2 环境下,/proc/1/cgroup 内容格式简化(单行),需匹配更宽泛的关键词如 containerddocker
  • Kubernetes Pod 中运行的容器,底层可能是 containerd,此时应识别 io.containerd. 而非仅 docker
  • 某些安全加固容器会隐藏 /proc 下的部分信息(如通过 seccomp 或 procfs 挂载限制),此时检测可能失败

实际项目中建议优先使用 cgroup 检查 + /.dockerenv 双重验证,兼顾兼容性与准确性。