Dockerデーモンのグローバル設定でチーム開発環境を統一する

ローカルでもサーバーでもDockerを利用していると、プロジェクトごとにdocker-compose.ymlに同じ設定を何度もコピー&ペーストしていることに気づくでしょう。

  • DNSを常に1.1.1.18.8.8.8に設定する
  • ログドライバーをjson-file + max-size=10mに固定する
  • プロキシ、insecure registry、デフォルトのネットワーク帯域など…

これらはコンテナごとの個別設定ではなく、「ホスト全体のデフォルト値」として切り出せば、管理が格段に楽になります。その役割を担うのが、まさにDockerデーモンのグローバル設定(daemon.jsonです。

以下で、

  • どのようなファイルを
  • どこに作成し
  • どのように記述すべきか
  • どのような状況で、どのような開発者/チームに役立つか

についてまとめます。


1. Dockerデーモン設定の二つの方法

Dockerデーモン(dockerd)は、主に二つの方法で設定できます。

  1. JSON設定ファイル(daemon.json)を使用推奨
  2. dockerd実行時にCLIフラグでオプションを渡す

両方を組み合わせて使うことも可能ですが、同じオプションを両方で指定すると、デーモンが起動しません。例えば、--log-driverフラグとdaemon.jsonの両方にログドライバーを設定すると、Dockerは起動時にエラーを出して停止します。

チームやサーバー環境の統一には、通常、

「可能な限りdaemon.jsonに集約し、フラグは最小限にする」

ことをお勧めします。

2. daemon.jsonの場所について

ファイルの場所は/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. 基本的な利用パターン:「ファイル作成 → デーモン再起動」

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. 主要設定1:DNSサーバーをグローバルで固定する

4.1 なぜDNSをグローバルで設定するのか?

コンテナが「なぜか外部APIを見つけられない」「内部ドメインが解決できない」といった問題に頻繁に遭遇する場合、ほとんどはホストのDNS設定や環境に依存していることが原因です。

例えば:

  • チーム全体でCloudflare DNS(1.1.1.1)を使いたい
  • 社内DNSサーバー経由でしかアクセスできないエンドポイントがある

このような場合、プロジェクトごとにdocker-compose.ymldns:を追加するよりも、Dockerデーモンの段階で統一する方がはるかに便利です。

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

このように設定すると、

  • コンテナごとのログファイルサイズが最大10MBとなり
  • 最大5つまでが保持され
  • 超過分は自動的に削除されます。

5.2 中央ログ収集用ドライバー (fluentd, journald など)

プラットフォームチームやインフラチームであれば、すべてのコンテナのログを中央ロギングシステムに送りたいと考えることが多いでしょう。

例えば、Fluentdを使用する場合:

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

このように設定しておけば、別途docker run --log-driver=...を指定することなく、すべてのコンテナのログが自動的にFluentdへ転送されます。

個人的にはjournaldドライバーもかなり気に入っています。systemdベースのLinux環境であれば、アプリケーションログとDockerコンテナログをすべてjournaldに集約し、journalctlだけで検索・フィルタリング・保存ポリシーを統一できるからです。

journaldをグローバルログドライバーとして使いたい場合は、例えば次のように設定できます:

{
  "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との関係

  • グローバルなlog-driver + log-opts は「デフォルト値」の役割
  • 個別のコンテナでlogging: (Compose) あるいは--log-driver--log-opt(CLI)を指定すると、そのコンテナのみを上書きします

戦略的には、

  • 共通の値をdaemon.jsonに設定し
  • 特殊なサービスのみ個別に上書きする

構成をお勧めします。


6. 主要設定3:プロキシ、insecure registryなど、グローバルネットワーク設定

グローバル設定でよく使われるその他のオプションもあります。

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 insecure registry

TLSがないレジストリをどうしても使用しなければならない状況(社内開発用など)であれば:

{
  "insecure-registries": ["my-registry.local:5000"]
}

セキュリティ上のリスクがあるため、内部テスト環境でのみ使用するよう注意が必要です。


7. 主要設定4:デフォルトのネットワーク帯域、ストレージドライバーなど

7.1 デフォルトのブリッジネットワーク帯域のカスタマイズ

VPNや社内ネットワークとIPアドレスが重複するのを避けたい場合:

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

このように設定すると、Dockerが新しいブリッジネットワークを作成する際に10.20.x.0/24帯域を使用します。

7.2 ストレージドライバーの強制

Linuxディストリビューションによっては、デフォルトのストレージドライバーが異なる場合があります。チームでoverlay2のみを使用すると決めた場合:

{
  "storage-driver": "overlay2"
}

実際にサポートされるストレージドライバーはOS/カーネルによって異なるため、dockerdのドキュメントとディストリビューションのガイドを必ず確認してください。



8. こんな「デジャヴ」を経験しているなら導入すべき

複雑なインフラ事情を詳しく知る必要はありません。もし最近、以下のような経験をしたことがあるなら、今こそdaemon.jsonを触るべきタイミングです。

  • 新しいプロジェクトを開始するたびにdocker-compose.ymlを探し回ってログ設定をコピペしている:昨日書いたコードからmax-sizemax-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": {...}
    • プロキシ、insecure registry、デフォルトのネットワーク帯域、ストレージドライバー…
  • グローバル設定は、繰り返される設定を減らし、多数のノードを多様な環境でデプロイする際に役立ちます。

docker-compose.ymldocker runに同じオプションを何度も書いているなら、 今こそdaemon.jsonに集約するタイミングかもしれません。

Dockerデーモンdaemon.json設定のイメージ