## Как унифицировать среду разработки команды с помощью глобальных настроек демона [[Docker]] {#sec-b2e039a7f45a} Работая с Docker как локально, так и на сервере, вы, вероятно, постоянно копируете и вставляете одни и те же настройки в `docker-compose.yml` для каждого проекта. * Например, постоянно устанавливаете DNS на `1.1.1.1`, `8.8.8.8` * Фиксируете драйвер логов как `json-file` + `max-size=10m` * Прокси, небезопасные реестры, диапазон IP-адресов для сети по умолчанию и т.д. Такие параметры гораздо проще в управлении, если выносите их не как **индивидуальные настройки контейнера**, а как **«глобальные значения по умолчанию для всего хоста»**. Именно для этого и служит **глобальная конфигурация демона Docker (`daemon.json`)**. Ниже мы рассмотрим: * какой файл * где его создать * как его настроить * и в каких ситуациях это будет полезно для разработчиков и команд.
## 1. Два способа настройки демона Docker {#sec-9c4e8fa25a41} Демон Docker (`dockerd`) можно настроить двумя основными способами: 1. **Использование файла конфигурации JSON (`daemon.json`)** ← *Рекомендуется* 2. Передача опций в виде **флагов CLI** при запуске `dockerd` Их можно комбинировать, но **если одна и та же опция указана в обоих местах, демон вообще не запустится.** Например, если вы укажете драйвер логов как во флаге `--log-driver`, так и в `daemon.json`, Docker выдаст ошибку на этапе запуска и завершит работу. Для унификации командной/серверной среды обычно рекомендуется: > «Максимально использовать `daemon.json` и минимизировать использование флагов CLI». ## 2. Расположение `daemon.json` {#sec-97a08839a2de} Файл обычно находится по пути **`/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. Основной шаблон использования: «Создать файл → Перезапустить демон» {#sec-875278239b12} Для Linux типичный рабочий процесс выглядит так: 1. **Создание/изменение `daemon.json`** ```json { "dns": ["1.1.1.1", "8.8.8.8"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } ``` 1. **Предварительная проверка** файла конфигурации на валидность ```bash sudo dockerd --validate --config-file=/etc/docker/daemon.json # Если выводится "configuration OK", значит, всё в порядке ``` 1. **Перезапуск** демона Docker ```bash sudo systemctl restart docker ``` Теперь все новые контейнеры, если для них не заданы индивидуальные настройки, будут **наследовать эти глобальные параметры в качестве значений по умолчанию**. ## 4. Основная настройка: Глобальная фиксация DNS-серверов {#sec-c284419e45cd} ### 4.1 Зачем глобальные DNS? {#sec-78011cf35f17} Если вы часто сталкиваетесь с проблемами, когда контейнеры «странным образом не могут найти внешний API» или «внутренние домены не разрешаются», это, скорее всего, связано с **зависимостью от настроек/среды DNS хоста**. Например: * Вся команда хочет использовать Cloudflare DNS (`1.1.1.1`) * Существуют конечные точки, доступные только через внутренний DNS-сервер компании В таких случаях гораздо удобнее унифицировать настройки DNS на уровне демона Docker, **вместо того чтобы добавлять `dns:` в `docker-compose.yml` для каждого проекта**. ### 4.2 Пример настройки (`daemon.json`) {#sec-2a85a418cbea} ```json { "dns": ["1.1.1.1", "8.8.8.8"] } ``` Если у вас уже есть `daemon.json`, просто добавьте запись `"dns": [...]` внутри корневого `{ ... }`. > ⚠️ **Внимание:** Настройки DNS отражаются в `/etc/resolv.conf` внутри контейнера. Они не применяются к уже запущенным контейнерам, а действуют **только для новых контейнеров, запускаемых после изменения**. ## 5. Основная настройка 2 – Глобальные параметры драйвера логирования {#sec-fe09c43b83b1} По умолчанию логи контейнеров сохраняются с помощью драйвера `json-file` в `/var/lib/docker/containers/...`. Глобальное изменение этого параметра позволяет: * Формат логов * Место хранения логов * Политику ротации логов применить **ко всем контейнерам одновременно**. ### 5.1 Драйвер `json-file` по умолчанию + ротация {#sec-26c5fb9056b5} Самый распространенный шаблон — это «использовать `json-file`, но настроить ротацию, чтобы не переполнять диск». ```json { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "5" } } ``` Таким образом: * Максимальный размер файла логов для каждого контейнера составляет `10 МБ` * Сохраняется не более `5` файлов * Избыточные файлы автоматически удаляются. ### 5.2 Драйверы для централизованного сбора логов (fluentd, journald и др.) {#sec-e7499afd6f5d} Для команд платформы или инфраструктуры часто возникает необходимость отправлять логи всех контейнеров в **централизованную систему логирования**. Например, при использовании Fluentd: ```json { "log-driver": "fluentd", "log-opts": { "fluentd-address": "localhost:24224", "tag": "{{.Name}}" } } ``` В этом случае логи всех контейнеров будут автоматически отправляться в Fluentd без необходимости указывать `docker run --log-driver=...` для каждого. Лично мне также очень нравится **драйвер `journald`**. В среде Linux на базе systemd он позволяет собирать логи приложений и логи контейнеров Docker в одном месте — journald, что упрощает унификацию политик просмотра, фильтрации и хранения с помощью `journalctl`. Если вы хотите использовать `journald` в качестве глобального драйвера логов, вы можете настроить его, например, так: ```json { "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` {#sec-8d284e8a0dfd} * **Глобальные `log-driver` + `log-opts`** играют роль «значений по умолчанию» * Если для отдельного контейнера указаны `logging:` (Compose) или `--log-driver`, `--log-opt` (CLI), то **только этот контейнер переопределяет** глобальные настройки. Стратегически рекомендуется использовать следующую конфигурацию: * Общие значения — в daemon.json * Специальные сервисы — с индивидуальным переопределением *** ## 6. Основная настройка 3 – Глобальные сетевые параметры: прокси, небезопасные реестры и т.д. {#sec-bc2f973bcb11} Существуют и другие часто используемые глобальные параметры. ### 6.1 Настройка прокси {#sec-753696ea7a1f} Если доступ к внешним ресурсам возможен только через корпоративный прокси, вы можете **настроить прокси на уровне демона**, вместо того чтобы каждый раз добавлять переменные окружения. ```json { "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 Небезопасный реестр {#sec-fe7d1c14ce8d} Если необходимо использовать реестр без TLS (например, для внутренней разработки): ```json { "insecure-registries": ["my-registry.local:5000"] } ``` Это может быть опасно с точки зрения безопасности, поэтому следует использовать **только во внутренних тестовых средах**. *** ## 7. Основная настройка 4 – Диапазон сети по умолчанию, драйвер хранения и т.д. {#sec-efc333459aa9} ### 7.1 Настройка диапазона IP-адресов для сети bridge по умолчанию {#sec-00d891d2b55d} Если вы хотите избежать пересечения IP-адресов с VPN или корпоративной сетью: ```json { "default-address-pools": [ { "base": "10.20.0.0/16", "size": 24 } ] } ``` Таким образом, при создании новой сети bridge Docker будет использовать диапазон `10.20.x.0/24`. ### 7.2 Принудительное использование драйвера хранения {#sec-04d867ec1442} Драйвер хранения по умолчанию может отличаться в зависимости от дистрибутива Linux. Если ваша команда решила использовать только `overlay2`: ```json { "storage-driver": "overlay2" } ``` > Обратите внимание, что фактически поддерживаемые драйверы хранения зависят от ОС/ядра, поэтому обязательно сверьтесь с документацией `dockerd` и руководством по вашему дистрибутиву. *** ## 8. Внедряйте, если вам знакомо это «дежавю» {#sec-e2c8a9ca03d5} Вам не обязательно разбираться в сложной инфраструктуре. Если вы недавно сталкивались с чем-то из перечисленного ниже, пришло время заняться `daemon.json`. * **При каждом запуске нового проекта вы роетесь в `docker-compose.yml` и копируете/вставляете настройки логирования:** Если вы снова и снова ищете настройки `max-size`, `max-file` из вчерашнего кода, вы уже впустую тратите драгоценное время. Достаточно один раз вынести их в глобальные настройки, и все контейнеры будут запускаться в «режиме экономии». * **Контейнер, который отлично работал в офисе, теряет доступ к интернету в кафе или через VPN:** Типичный случай фразы «у меня на локалке всё работало». Если вы хотите, чтобы ваши контейнеры стабильно взаимодействовали с внешним миром в любой сетевой среде, не завися от настроек DNS хоста, то глобальная фиксация DNS — это то, что вам нужно. * **У вас кружится голова от необходимости вручную настраивать множество серверных узлов:** Вы тратите время на «призрачные баги», возникающие из-за незначительных различий в настройках Docker на каждом сервере? Достаточно развернуть один файл `daemon.json`, и все серверы будут работать по одним и тем же правилам. *** > Если вам надоели повторяющиеся настройки или утомила рутина, связанная с изменениями среды, то сейчас самое время внедрить эти параметры. ## Итоги {#sec-857c80428df3} * Глобальные значения по умолчанию 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](https://blog.mikihands.com/media/editor_temp/6/00f7dbc8-f71e-485b-b9a9-e9514af1ba73.png)