## [[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デーモン設定の二つの方法 {#sec-9c4e8fa25a41} Dockerデーモン(`dockerd`)は、主に二つの方法で設定できます。 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-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. 主要設定1:DNSサーバーをグローバルで固定する {#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": [...]`項目を追加すれば大丈夫です。 > ⚠️ **注意:** 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" } } ``` このように設定すると、 * コンテナごとのログファイルサイズが最大`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-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-efc333459aa9} ### 7.1 デフォルトのブリッジネットワーク帯域のカスタマイズ {#sec-00d891d2b55d} VPNや社内ネットワークとIPアドレスが重複するのを避けたい場合: ```json { "default-address-pools": [ { "base": "10.20.0.0/16", "size": 24 } ] } ``` このように設定すると、Dockerが新しいブリッジネットワークを作成する際に`10.20.x.0/24`帯域を使用します。 ### 7.2 ストレージドライバーの強制 {#sec-04d867ec1442} Linuxディストリビューションによっては、デフォルトのストレージドライバーが異なる場合があります。チームで`overlay2`のみを使用すると決めた場合: ```json { "storage-driver": "overlay2" } ``` > 実際にサポートされるストレージドライバーはOS/カーネルによって異なるため、`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": {...}` * プロキシ、insecure registry、デフォルトのネットワーク帯域、ストレージドライバー… * グローバル設定は、繰り返される設定を減らし、多数のノードを多様な環境でデプロイする際に役立ちます。 `docker-compose.yml`や`docker run`に同じオプションを何度も書いているなら、 **今こそ`daemon.json`に集約するタイミング**かもしれません。 ![Dockerデーモン`daemon.json`設定のイメージ](https://blog.mikihands.com/media/editor_temp/6/00f7dbc8-f71e-485b-b9a9-e9514af1ba73.png)