## [[Docker]] デーモンのグローバル設定でチーム開発環境を統一する {#sec-b2e039a7f45a} ローカル環境でもサーバー環境でもDockerを使用していると、プロジェクトごとに`docker-compose.yml`に同じ設定を何度もコピー&ペーストすることになりがちです。 * DNSを常に`1.1.1.1`、`8.8.8.8`に設定したり * ログドライバーを`json-file` + `max-size=10m`に固定したり * プロキシ、insecure registry、デフォルトのネットワーク帯域など… これらの設定は、**コンテナごとの個別設定ではなく、「ホスト全体のデフォルト値」** として一元管理することで、はるかに運用が楽になります。その役割を担うのが、まさに**Dockerデーモンのグローバル設定(`daemon.json`)** です。 以下で、どのファイルを、どこに作成し、どのように記述すべきか、そしてどのような状況でどのような開発者やチームに役立つかをまとめます。
## 1\. Dockerデーモンの設定方法2つ \{\#sec\-7390246eab38\} {#sec-9c4e8fa25a41} Dockerデーモン(`dockerd`)は、主に2つの方法で設定できます。 1. **JSON設定ファイル(`daemon.json`)を使用** ← *推奨* 2. `dockerd`実行時に**CLIフラグ**でオプションを渡す 両者を組み合わせて使用することも可能ですが、**同じオプションを両方で指定すると、デーモンが起動しなくなります。** 例えば、`--log-driver`フラグと`daemon.json`の両方にログドライバーを設定してしまうと、Dockerは起動時にエラーを出して停止します。 チーム/サーバー環境を統一するためには、通常、「可能な限り`daemon.json`に集約し、フラグは最小限にとどめる」ことをお勧めします。 ## 2. `daemon.json`の場所 {#sec-97a08839a2de} ファイルの場所は、**`/etc/docker/daemon.json`** です。もちろん、これはLinuxの場合です。 DockerをLinux以外の環境で使用されている方もいらっしゃるかもしれませんが、私はLinuxでのみ使用しているため、他のOSについては詳しくありません。しかし、OSごとのデフォルトの場所を一覧にすると以下のようになります。 | 環境 | デフォルトパス | 備考 | | --- | ----- | --- | | 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\. 基本的な使用パターン:「ファイル作成 → デーモン再起動」 \{\#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-compose.yml`に`dns:`を追加するよりも**、Dockerデーモンレベルで統一する方がはるかに便利です。 ### 4.2 設定例(`daemon.json`) {#sec-2a85a418cbea} ```json { "dns": ["1.1.1.1", "8.8.8.8"] } ``` 既存の`daemon.json`がある場合は、ルートの`{ ... }`内に`"dns": [...]`項目を追加すればOKです。 > ⚠️ **注意:** 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}}" } } ``` このように設定しておけば、別途`docker run --log-driver=...`を指定しなくても、すべてのコンテナのログが自動的にFluentdへ転送されます。 個人的には**`journald`ドライバー**もかなり気に入っています。systemdベースのLinux環境であれば、アプリケーションログとDockerコンテナログをすべてjournaldに集約し、`journalctl`だけで検索・フィルタリング・保存ポリシーを統一できるからです。 `journald`をグローバルログドライバーとして使用したい場合は、例えば以下のように設定できます。 ```json { "log-driver": "journald", "log-opts": { "tag": "{{.Name}}" } } ``` ここで`tag`をコンテナ名として使用しているため: * `journalctl -f | grep {container_name}`の形式で**リアルタイムログを素早く確認でき** * `--since "10m ago"`のようなオプションを組み合わせて**特定時点以降のログのみを見ることも可能で** * `journalctl -f -t {container_name}`のように`-t`オプション(タグ/識別子基準)を使って**特定のコンテナログだけをピンポイントで**確認することもできます。 もちろん、`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 デフォルトのbridgeネットワーク帯域のカスタマイズ {#sec-00d891d2b55d} VPNや社内ネットワークとIPアドレスが重複するのを避けたい場合: ```json { "default-address-pools": [ { "base": "10.20.0.0/16", "size": 24 } ] } ``` このようにすると、Dockerが新しいbridgeネットワークを作成する際に`10.20.x.0/24`帯域を使用するようになります。 ### 7.2 ストレージドライバーの強制 {#sec-04d867ec1442} Linuxディストリビューションによっては、デフォルトのストレージドライバーが異なる場合があります。チームで`overlay2`のみを使用すると決めている場合: ```json { "storage-driver": "overlay2" } ``` > 実際のサポート可能なストレージドライバーはOS/カーネルによって異なるため、`dockerd`のドキュメントとディストリビューションのガイドを必ず確認する必要があります。 *** ## 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`に集約するタイミング**かもしれません。 ![Dockerデーモンjson設定の画像](https://blog.mikihands.com/media/editor_temp/6/00f7dbc8-f71e-485b-b9a9-e9514af1ba73.png)