Как унифицировать среду разработки команды с помощью глобальных настроек демона Docker

Работая с Docker как локально, так и на сервере, вы, вероятно, постоянно копируете и вставляете одни и те же настройки в docker-compose.yml для каждого проекта.

  • Например, постоянно устанавливаете DNS на 1.1.1.1, 8.8.8.8
  • Фиксируете драйвер логов как json-file + max-size=10m
  • Прокси, небезопасные реестры, диапазон IP-адресов для сети по умолчанию и т.д.

Такие параметры гораздо проще в управлении, если выносите их не как индивидуальные настройки контейнера, а как «глобальные значения по умолчанию для всего хоста». Именно для этого и служит глобальная конфигурация демона Docker (daemon.json).

Ниже мы рассмотрим:

  • какой файл
  • где его создать
  • как его настроить
  • и в каких ситуациях это будет полезно для разработчиков и команд.


1. Два способа настройки демона Docker

Демон Docker (dockerd) можно настроить двумя основными способами:

  1. Использование файла конфигурации JSON (daemon.json)Рекомендуется
  2. Передача опций в виде флагов CLI при запуске dockerd

Их можно комбинировать, но если одна и та же опция указана в обоих местах, демон вообще не запустится. Например, если вы укажете драйвер логов как во флаге --log-driver, так и в daemon.json, Docker выдаст ошибку на этапе запуска и завершит работу.

Для унификации командной/серверной среды обычно рекомендуется:

«Максимально использовать daemon.json и минимизировать использование флагов CLI».

2. Расположение daemon.json

Файл обычно находится по пути /etc/docker/daemon.json. Конечно, это для Linux.

Возможно, есть пользователи Docker в средах, отличных от Linux, но поскольку я использую его только в Linux, я не очень знаком с другими ОС. Однако вот таблица с расположением файла по умолчанию для разных операционных систем:

Среда Путь по умолчанию Примечания
Linux (стандартная установка) /etc/docker/daemon.json Наиболее распространенный случай
Linux (Docker установлен через snap) /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-сервер компании

В таких случаях гораздо удобнее унифицировать настройки DNS на уровне демона Docker, вместо того чтобы добавлять dns: в docker-compose.yml для каждого проекта.

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"
  }
}

Таким образом:

  • Максимальный размер файла логов для каждого контейнера составляет 10 МБ
  • Сохраняется не более 5 файлов
  • Избыточные файлы автоматически удаляются.

5.2 Драйверы для централизованного сбора логов (fluentd, journald и др.)

Для команд платформы или инфраструктуры часто возникает необходимость отправлять логи всех контейнеров в централизованную систему логирования.

Например, при использовании Fluentd:

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

В этом случае логи всех контейнеров будут автоматически отправляться в Fluentd без необходимости указывать docker run --log-driver=... для каждого.

Лично мне также очень нравится драйвер journald. В среде Linux на базе systemd он позволяет собирать логи приложений и логи контейнеров 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 Настройка диапазона IP-адресов для сети bridge по умолчанию

Если вы хотите избежать пересечения IP-адресов с VPN или корпоративной сетью:

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

Таким образом, при создании новой сети bridge Docker будет использовать диапазон 10.20.x.0/24.

7.2 Принудительное использование драйвера хранения

Драйвер хранения по умолчанию может отличаться в зависимости от дистрибутива Linux. Если ваша команда решила использовать только overlay2:

{
  "storage-driver": "overlay2"
}

Обратите внимание, что фактически поддерживаемые драйверы хранения зависят от ОС/ядра, поэтому обязательно сверьтесь с документацией dockerd и руководством по вашему дистрибутиву.


8. Внедряйте, если вам знакомо это «дежавю»

Вам не обязательно разбираться в сложной инфраструктуре. Если вы недавно сталкивались с чем-то из перечисленного ниже, пришло время заняться daemon.json.

  • При каждом запуске нового проекта вы роетесь в docker-compose.yml и копируете/вставляете настройки логирования: Если вы снова и снова ищете настройки max-size, max-file из вчерашнего кода, вы уже впустую тратите драгоценное время. Достаточно один раз вынести их в глобальные настройки, и все контейнеры будут запускаться в «режиме экономии».
  • Контейнер, который отлично работал в офисе, теряет доступ к интернету в кафе или через VPN: Типичный случай фразы «у меня на локалке всё работало». Если вы хотите, чтобы ваши контейнеры стабильно взаимодействовали с внешним миром в любой сетевой среде, не завися от настроек DNS хоста, то глобальная фиксация DNS — это то, что вам нужно.
  • У вас кружится голова от необходимости вручную настраивать множество серверных узлов: Вы тратите время на «призрачные баги», возникающие из-за незначительных различий в настройках Docker на каждом сервере? Достаточно развернуть один файл 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": {...}
    • Прокси, небезопасные реестры, диапазон IP-адресов для сети по умолчанию, драйвер хранения…
  • Глобальные настройки полезны при повторяющихся конфигурациях и развертывании большого количества узлов в различных средах.

Если вы продолжаете использовать одни и те же опции в docker-compose.yml или docker run, возможно, пришло время перенести их в daemon.json.

Изображение настройки Docker daemon.json