プロキシ環境で Docker を使う場合、どこに proxy を設定するのかを分けて考える必要があります。
Docker CLI に proxy を設定しても、Docker daemon が外部レジストリへ到達できるとは限りません。コンテナ内に proxy を設定しても、daemon の image pull には効きません。Docker build 時の proxy も、daemon の proxy とは別の話です。
この記事では、Docker daemon の外部接続を systemd drop-in で制御する方法を中心に、daemon、container、build の proxy の違いを整理します。
書籍
Docker の基本、コンテナ運用、開発環境構築を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
Docker の proxy はどこに効くのか
Docker の proxy 設定で混乱しやすいのは、設定先によって効く範囲が違うことです。
| 設定対象 | 主な用途 | 効く範囲 |
|---|---|---|
| Docker daemon | image pull、registry への接続 | dockerd の外部通信 |
| Docker CLI | CLI 自体の通信 | 基本的には client 側の動作 |
| Container | 起動したコンテナ内の外部通信 | アプリケーションや package manager の通信 |
| Docker build | build 中の package 取得 | RUN apt update など build step 内の通信 |
たとえば、docker pull nginx が失敗する場合、まず見るべきは Docker daemon の proxy 設定です。コンテナ内の HTTP_PROXY を設定しても、daemon の pull には効きません。
systemd drop-in で Docker daemon に設定する
systemd 管理の Docker では、サービスファイル本体を直接編集するのではなく、drop-in ファイルを作成して proxy を設定します。
パッケージ更新でサービスファイルが変わっても、drop-in は分離して管理できます。構成管理やレビューの観点でも、この方法の方が扱いやすいです。
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://proxy.example.local:3128"
Environment="HTTPS_PROXY=http://proxy.example.local:3128"
Environment="NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,192.168.0.0/16,registry.local"
EOFNO_PROXY には、内部レジストリ、内部 DNS、社内ネットワーク、localhost など、proxy を経由させない宛先を入れます。
設定を反映して確認する
drop-in を作成したら、systemd の設定を再読み込みし、Docker daemon を再起動します。その後、環境変数が反映されているか確認します。
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
systemctl status docker --no-pager確認時は、単に Docker が起動しているかだけでなく、Environment に proxy 設定が反映されているかを見ます。
image pull で確認する
Docker daemon の proxy 設定が必要になる代表例は、外部レジストリからの image pull です。
docker pull hello-world
docker image ls hello-world外部レジストリへの接続が proxy 経由で許可されている場合は、pull が成功します。失敗する場合は、proxy の宛先許可、認証、証明書、DNS、Docker daemon の環境変数を分けて確認します。
container 内 proxy とは別である
Docker daemon の proxy 設定は、起動したコンテナ内のアプリケーション通信にはそのまま適用されません。
コンテナ内で apt、curl、アプリケーションが外部通信する場合は、コンテナ側にも proxy 設定が必要になることがあります。
docker run --rm -e HTTP_PROXY=http://proxy.example.local:3128 -e HTTPS_PROXY=http://proxy.example.local:3128 ubuntu:24.04 env | grep -i proxyこの設定は、container 内のプロセスが見る環境変数です。Docker daemon が image を pull するための proxy とは責務が違います。
Docker build 時の proxy も分ける
Dockerfile の build 中に package を取得する場合も、proxy の扱いを分けて考えます。
build 時だけ必要な proxy を image に残したくない場合は、build argument として渡す方が扱いやすいことがあります。
docker build --build-arg HTTP_PROXY=http://proxy.example.local:3128 --build-arg HTTPS_PROXY=http://proxy.example.local:3128 -t example/app:dev .build 時の proxy は、Dockerfile の中で外部通信する処理に関係します。daemon の image pull、container 実行時の外部通信とは別の確認対象です。
内部レジストリと NO_PROXY
内部レジストリを使う環境では、NO_PROXY が特に重要です。
内部レジストリへの pull / push まで proxy 経由にしてしまうと、不要な経路を通ったり、証明書や名前解決の問題が増えたりします。内部向け通信は直接到達させ、外部レジストリだけ proxy 経由にする構成が自然です。
ただし、NO_PROXY の CIDR 表記や IPv6 表記の扱いは、実装によって差が出ることがあります。期待通りに除外されているかは、実際の pull / push とログで確認する必要があります。
トラブル時の確認点
Docker の proxy 問題は、単に proxy の URL が間違っているだけとは限りません。
| 症状 | 確認すること |
|---|---|
docker pull が失敗する | Docker daemon の proxy、DNS、proxy 側の宛先許可 |
container 内の curl が失敗する | container 側の環境変数、アプリケーション設定 |
build 中の apt update が失敗する | build argument、Dockerfile 内の proxy 設定 |
| 内部レジストリへ接続できない | NO_PROXY、証明書、名前解決、レジストリの TLS |
| 証明書エラーが出る | proxy の TLS inspection、CA 証明書、Docker daemon の trust 設定 |
重要なのは、どの通信が失敗しているのかを分けることです。daemon の通信、container の通信、build の通信を混ぜると、設定箇所を間違えます。
まとめ
Docker の proxy 設定では、Docker daemon、container、build の責務を分けて考える必要があります。
外部レジストリから image を pull するための proxy は、Docker daemon 側に設定します。systemd 環境では、drop-in ファイルを使うと管理しやすくなります。
一方で、container 内のアプリケーション通信や Docker build 中の外部通信は別の設定対象です。内部レジストリを使う場合は、NO_PROXY で内部通信を除外する設計も重要になります。
プロキシ環境で Docker を安定して使うには、どこに proxy を設定するかではなく、どの通信を誰が行っているのかを切り分けることが重要です。
関連する記事
- Docker プライベートレジストリとは何か – 外部接続を減らし、内部配布基盤を作る
- Harbor プライベートコンテナレジストリ構築 – Kubernetes / Docker 向け内部レジストリを用意する
- GROWI の外部接続設計 – プロキシ、プラグイン、閉域運用を分けて考える

