## Унификация командной среды разработки с помощью глобальных настроек демона [[Docker]] {#sec-b2e039a7f45a} При использовании Docker, будь то на локальной машине или на сервере, часто приходится копировать и вставлять одни и те же настройки в `docker-compose.yml` для каждого проекта. * Например, всегда устанавливать DNS на `1.1.1.1`, `8.8.8.8`, * Фиксировать драйвер логирования на `json-file` + `max-size=10m`, * Прокси, insecure registry, диапазон IP-адресов для сети по умолчанию и т.д. Такие вещи гораздо проще администрировать, если выносить их не в **индивидуальные настройки контейнера, а в «глобальные значения по умолчанию для всего хоста»**. Именно эту роль выполняет **глобальная конфигурация демона Docker (`daemon.json`)**. Ниже мы рассмотрим: * Какой файл, * Где его создать, * Как его настроить, * И в каких ситуациях это будет полезно для разработчиков и команд.
## 1. Два способа настройки демона Docker \{\#sec\-7390246eab38\} {#sec-9c4e8fa25a41} Демон Docker (`dockerd`) можно настроить двумя основными способами: 1. **Использование файла конфигурации JSON (`daemon.json`)** ← *Рекомендуется* 2. Передача опций через **флаги CLI** при запуске `dockerd` Их можно комбинировать, но **если одна и та же опция указана в обоих местах, демон вообще не запустится.** Например, если вы укажете драйвер логирования как во флаге `--log-driver`, так и в `daemon.json`, Docker выдаст ошибку на этапе запуска и завершит работу. Для унификации среды в команде или на сервере обычно рекомендуется: > «По возможности собирать все в `daemon.json`, а флаги использовать по минимуму» Это наиболее предпочтительный подход. ## 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\-bffe465cc36f\} {#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", значит все в порядке :contentReference[oaicite:7]{index=7} ``` 1. **Перезапуск** демона Docker ```bash sudo systemctl restart docker ``` Теперь все новые контейнеры будут **наследовать эти глобальные настройки по умолчанию**, если не указано иное. ## 4. Основная настройка: Фиксация DNS-сервера глобально \{\#sec\-d9c2238a423f\} {#sec-c284419e45cd} ### 4.1. Зачем фиксировать DNS глобально? {#sec-78011cf35f17} Если контейнеры часто сталкиваются с проблемами вроде «почему-то не находит внешний API» или «внутренний домен не разрешается», это чаще всего происходит из-за **зависимости от настроек DNS/среды хоста**. Например: * Вся команда хочет использовать Cloudflare DNS (`1.1.1.1`) * Есть конечные точки, доступные только через внутренний 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\-360ddebc7b6c\} {#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" } } ``` Такая настройка означает, что: * Максимальный размер файла логов на контейнер составляет `10MB`, * Сохраняется не более `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 – Глобальные сетевые параметры: прокси, insecure registry и т.д. \{\#sec\-0d687ac65460\} {#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. Insecure registry {#sec-fe7d1c14ce8d} Если вам обязательно нужно использовать реестр без TLS (например, для внутренней разработки): ```json { "insecure-registries": ["my-registry.local:5000"] } ``` Будьте осторожны, поскольку это может быть небезопасно, и **используйте только во внутренних тестовых средах**. *** ## 7. Основная настройка 4 – Диапазон сети по умолчанию, драйвер хранилища и т.д. \{\#sec\-3598d5fb02d3\} {#sec-efc333459aa9} Несколько более инфраструктурные опции: ### 7.1. Настройка диапазона IP-адресов для сети bridge по умолчанию {#sec-00d891d2b55d} Если вы хотите избежать конфликтов IP-адресов с VPN или корпоративной сетью: ```json { "default-address-pools": [ { "base": "10.20.0.0/16", "size": 24 } ] } ``` Таким образом, Docker будет использовать диапазон `10.20.x.0/24` при создании новых сетей bridge. ### 7.2. Принудительное использование драйвера хранилища {#sec-04d867ec1442} Драйвер хранилища по умолчанию может различаться в зависимости от дистрибутива Linux. Если ваша команда решила использовать только `overlay2`: ```json { "storage-driver": "overlay2" } ``` > Фактически поддерживаемые драйверы хранилища зависят от ОС/ядра, поэтому обязательно сверяйтесь с документацией `dockerd` и руководством по дистрибутиву. *** Я сразу понял, о чем речь. Как только начинаешь концентрироваться на «кому (Persona)», текст становится сухим, как инструкция, и звучит как обычная речь ИИ. Я переписал текст, сосредоточившись на человеческом опыте и «раздражающих ситуациях», чтобы вызвать чувство сопереживания. *** ## 8. Внедряйте, если вы сталкиваетесь с таким «дежавю» \{\#sec\-807a100451aa\} {#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": {...}` * Прокси, insecure registry, диапазон сети по умолчанию, драйвер хранилища… * Глобальные настройки полезны для устранения повторяющихся конфигураций и развертывания множества узлов в различных средах. Если вы постоянно используете одни и те же опции в `docker-compose.yml` или `docker run`, **возможно, пришло время вынести их в `daemon.json`**. ![Изображение настроек daemon.json Docker](https://blog.mikihands.com/media/editor_temp/6/00f7dbc8-f71e-485b-b9a9-e9514af1ba73.png)