Docker 守护进程全局配置统一团队开发环境

无论是在本地还是服务器上使用 Docker,您是否也曾厌倦了在每个项目的 docker-compose.yml 文件中反复粘贴相同的配置?

  • 总是将 DNS 设置为 1.1.1.18.8.8.8
  • 将日志驱动程序固定为 json-file + max-size=10m
  • 代理、不安全注册表、默认网络范围等等…

这些配置与其作为容器的独立设置,不如将其提取为“主机全局默认值”,这样管理起来会轻松许多。而实现这一点的关键就是 Docker 守护进程全局配置(daemon.json

在接下来的内容中,我们将详细介绍:

  • 需要创建哪个文件
  • 文件应该放在哪里
  • 如何编写配置
  • 在何种情况下对哪些开发者或团队特别有用


1. Docker 守护进程的两种配置方式

Docker 守护进程(dockerd)主要有两种配置方式:

  1. 使用 JSON 配置文件(daemon.json推荐
  2. dockerd 运行时通过 CLI 标志传递选项

虽然两者可以混合使用,但如果同一个选项在两者中都被指定,守护进程将无法启动。 例如,如果您同时在 --log-driver 标志和 daemon.json 中配置了日志驱动程序,Docker 将在启动阶段报错并终止。

为了统一团队/服务器环境,我们通常建议:

“尽可能将所有配置集中在 daemon.json 中,并最大限度地减少使用命令行标志。”

2. daemon.json 文件位置

该文件的位置通常是 /etc/docker/daemon.json。当然,这是基于 Linux 的情况。

或许有人会在 Linux 以外的环境中使用 Docker,但我个人只在 Linux 上使用,所以对其他操作系统不太熟悉。不过,为了方便大家查阅,我将各操作系统的默认位置整理成表格如下:

环境 默认路径 备注
Linux (一般安装) /etc/docker/daemon.json 最常见的情况
Linux (snap 安装的 Docker) /var/snap/docker/current/config/daemon.json Ubuntu snap 包
Windows Server / Docker Engine C:\ProgramData\Docker\config\daemon.json
Docker Desktop (Mac / Windows) ~/.docker/daemon.json
  • 此文件默认可能不存在,如果不存在,请自行创建并使用。

3. 基本使用模式:“创建文件 → 重启守护进程”

以 Linux 为例,一般的工作流程如下:

  1. 编写/修改 daemon.json
{
  "dns": ["1.1.1.1", "8.8.8.8"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
  1. 提前验证配置文件是否有效
sudo dockerd --validate --config-file=/etc/docker/daemon.json
# 如果显示 "configuration OK" 则表示正常
  1. 重启 Docker 守护进程
sudo systemctl restart docker

从现在开始,新启动的容器除非有单独配置,否则都将继承这些全局设置作为默认值

4. 主要配置:全局固定 DNS 服务器

4.1 为什么要全局配置 DNS?

如果您的容器经常出现“无法解析外部 API”或“内部域名无法解析”等问题,那很可能因为它依赖于主机的 DNS 设置/环境

例如:

  • 整个团队希望使用 Cloudflare DNS (1.1.1.1)
  • 存在只能通过公司内部 DNS 服务器访问的端点

在这种情况下,与其在每个项目 docker-compose.yml 中添加 dns: 配置,不如直接在 Docker 守护进程层面进行统一,这样会方便得多。

4.2 配置示例 (daemon.json)

{
  "dns": ["1.1.1.1", "8.8.8.8"]
}

如果已存在 daemon.json 文件,只需在根 { ... } 中添加 "dns": [...] 条目即可。

⚠️ 注意: DNS 设置将反映在容器内部的 /etc/resolv.conf 中。它不会立即应用于已运行的容器,而是从新启动的容器开始生效

5. 主要配置 2 – 日志驱动程序与选项的全局设置

容器日志默认通过 json-file 驱动程序存储在 /var/lib/docker/containers/... 路径下。通过全局修改此设置,您可以:

  • 统一日志格式
  • 统一日志存储位置
  • 统一日志轮转策略

从而将这些策略批量应用于所有容器

5.1 默认 json-file 驱动程序 + 日志轮转

最常见的模式是“使用 json-file,但配置轮转以防止磁盘空间耗尽”。

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

这样配置后:

  • 每个容器的日志文件大小最大为 10MB
  • 最多保留 5 个日志文件
  • 超出部分将自动删除。

5.2 用于集中式日志收集的驱动程序 (fluentd, journald 等)

如果是平台团队或基础设施团队,通常会希望将所有容器的日志发送到集中式日志系统

例如,如果使用 Fluentd:

{
  "log-driver": "fluentd",
  "log-opts": {
    "fluentd-address": "localhost:24224",
    "tag": "{{.Name}}"
  }
}

这样配置后,无需单独使用 docker run --log-driver=... 命令,所有容器的日志都会自动发送到 Fluentd。

我个人也相当喜欢 journald 驱动程序。在基于 systemd 的 Linux 环境中,它可以将应用程序日志和 Docker 容器日志都集中到 journald,从而通过 journalctl 统一查询、过滤和保留策略。

如果希望将 journald 用作全局日志驱动程序,可以这样配置:

{
  "log-driver": "journald",
  "log-opts": {
    "tag": "{{.Name}}"
  }
}

由于这里将 tag 设置为容器名称,因此:

  • 可以通过 journalctl -f | grep {container_name} 快速实时查看日志
  • 可以结合 --since "10m ago" 等选项查看特定时间点之后的日志
  • 可以使用 -t 选项(基于标签/标识符)如 journalctl -f -t {container_name}精确筛选特定容器的日志

当然,也可以像 journalctl -u docker.service 那样按单元查看,但根据容器名称进行过滤更为直观,输入也更少,因此在实际工作中会更常用。

5.3 与 Compose / docker run 的关系

  • 全局 log-driver + log-opts 起到“默认值”的作用
  • 如果在单个容器中指定 logging: (Compose) 或 --log-driver, --log-opt(CLI),则仅该容器的配置会被覆盖

策略上建议:

  • 将通用值放入 daemon.json
  • 仅对特殊服务进行单独覆盖配置

6. 主要配置 3 – 代理、不安全注册表等全局网络设置

全局配置中还有一些常用的选项:

6.1 代理设置

如果公司内部网络只能通过代理访问外部,那么与其每次都设置环境变量,不如在守护进程层面配置代理

{
  "proxies": {
    "http-proxy": "http://proxy.example.com:3128",
    "https-proxy": "http://proxy.example.com:3128",
    "no-proxy": "localhost,127.0.0.1,.corp.example.com"
  }
}

这样,当 Docker 守护进程拉取镜像或在构建时使用网络时,都会遵循这些代理设置。

6.2 不安全注册表

如果必须使用没有 TLS 的注册表(例如内部开发),可以这样配置:

{
  "insecure-registries": ["my-registry.local:5000"]
}

这可能存在安全风险,因此务必注意仅在内部测试环境中使用


7. 主要配置 4 – 默认网络范围、存储驱动程序等

一些更偏向基础设施的选项:

7.1 自定义默认 bridge 网络范围

当您希望避免与 VPN 或公司内部网络 IP 冲突时:

{
  "default-address-pools": [
    {
      "base": "10.20.0.0/16",
      "size": 24
    }
  ]
}

这样配置后,Docker 在创建新的 bridge 网络时将使用 10.20.x.0/24 网段。

7.2 强制指定存储驱动程序

根据 Linux 发行版的不同,默认存储驱动程序可能有所差异。如果团队决定只使用 overlay2

{
  "storage-driver": "overlay2"
}

实际支持的存储驱动程序因操作系统/内核而异,因此务必查阅 dockerd 文档和发行版指南。


8. 如果您正经历“似曾相识”的困扰,是时候引入它了

您无需了解复杂的底层基础设施。如果您最近有以下经历,那么现在正是调整 daemon.json 的最佳时机:

  • 每次启动新项目时,都在 docker-compose.yml 中翻找并复制粘贴日志设置: 如果您还在从昨天的代码中复制 max-sizemax-file 设置并再次粘贴,那您已经在浪费宝贵的时间了。只需一次全局配置,所有容器都将自动以“精简”模式启动。
  • 在办公室运行正常的容器,一到咖啡馆或 VPN 环境就断网: 这是典型的“在我本地没问题啊?”的情况。如果您希望容器在任何网络环境下都能一致地与外部通信,而不受主机 DNS 设置的影响,那么全局固定 DNS 就是解决方案。
  • 为每个服务器节点逐一配置 Docker 设置而头晕脑胀: 您是否因为每个服务器的 Docker 设置细微差异而引发“幽灵 Bug”,导致反复排查?只需部署一个 daemon.json 文件,所有服务器都将像一支军队般遵循相同的规则运行。

当您厌倦了重复配置,或受够了因环境变化而导致的各种麻烦时,就是引入此设置的最佳时机。

总结

  • Docker 的全局默认值在 daemon.json 中管理。
  • 位置通常是 /etc/docker/daemon.json
  • 典型的全局配置示例:
    • DNS: "dns": ["1.1.1.1", "8.8.8.8"]
    • 日志驱动程序: "log-driver": "json-file", "log-opts": {...}
    • 代理、不安全注册表、默认网络范围、存储驱动程序…
  • 全局设置在处理重复配置以及在不同环境中部署大量节点时非常有用。

如果您仍在 docker-compose.ymldocker run 命令中反复使用相同的选项, 那么现在或许是时候将它们提升到 daemon.json了。

Docker 守护进程 JSON 设置