🐳

コンテナにおけるプロキシ設定と証明書対応

に公開

はじめに

社内プロキシがあると「公式手順どおり入れたのに通信が全部こける」ことが珍しくありません。実際には“全部”ではなく、通信経路が OS → APT → Docker CLI → Docker デーモン → レジストリ と分かれていて、足りない設定がある層だけが失敗しているパターンが多いです。そのため、困った操作をレイヤー表に当てはめて「どこが未設定か」を絞るのが近道です。


0. 動作環境

項目 バージョン
OS Ubuntu 22.04 LTS
Docker 28.5.2
ネットワーク 社内ネットワーク
外部 (GitHub / Docker Hub / GHCR) へ HTTP(S) 到達できること
プロキシ HTTP/HTTPS を必ず経由

2. レイヤー一覧

以下がコンテナで通信が上手くいかない場合においてのレイヤーごとの切り分け方一覧です。

レイヤー 目的 主ファイル / 手段 代表的なコマンド
OS環境変数 一般コマンド疎通 (curl) /etc/environment printenv
APT パッケージ取得 /etc/apt/apt.conf.d/80proxies apt update
Docker デーモン イメージ取得 / build 中通信 /etc/systemd/system/docker.service.d/*.conf docker pull hello-world
証明書 (OS) 全体 TLS 信頼 /usr/share/ca-certificates + update-ca-certificates HTTPS 系
証明書 (Docker) レジストリ個別 TLS /etc/docker/certs.d/<registry>/ca.crt 特定レジストリ pull

3. OS(環境変数)プロキシ設定

/etc/environment に以下を入れて再起動(再ログイン)します。
アプリによって大文字・小文字のどちらをチェックするかが分からないので、それぞれ設定します。

http_proxy="xxx"
https_proxy="xxx"
HTTP_PROXY="xxx"
HTTPS_PROXY="xxx"

以下で設定が反映されているかを確認します。

echo $http_proxy
printenv

4. APT 永続プロキシ設定

apt update でパッケージ取得が遅い・止まるときはここが未設定の場合があります。
80proxiesとしていますが、ファイル名は任意です。任意のファイルを作成し、Acquire::~の部分を記載してください。

sudo tee /etc/apt/apt.conf.d/80proxies >/dev/null <<'EOF'
Acquire::http::proxy "xxx";
Acquire::https::proxy "xxx";
EOF

その後 apt update でパッケージ取得できれば問題無しです。


5. Docker デーモンのプロキシ設定

Dockerではデーモン側のプロキシ設定が必要です。
以下を設定してください。

<設定>
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=xxx"
Environment="HTTPS_PROXY=xxx"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF

<設定反映>
sudo systemctl daemon-reload
sudo systemctl restart docker

<設定確認>
docker info

docker pull hello-world が失敗する場合、ここまでの設定が反映されていない可能性が高いです。


6. 証明書(CA)設定

通信が失敗したときに、x509のエラーが出ることがあります。
その場合は、以下の証明書の設定が必要です。

OS 全体

<設定>
sudo cp <CA_CERT_FILE> /usr/share/ca-certificates/
echo "<CA_CERT_FILE_NAME>" | sudo tee -a /etc/ca-certificates.conf

<設定反映>
sudo update-ca-certificates

<設定確認>
ls /etc/ssl/certs | grep <CA_CERT_FILE_BASE> || echo "CA cert not found"

Docker レジストリ(例: ghcr.io)

GitHub Container Registry(GHCR)などのプライベートコンテナレジストリを利用している場合は、Docker側にも証明書を配置させる必要があります。
今回の場合は、DockerHubには証明書を配置することはありませんでした。

<設定>
sudo mkdir -p /etc/docker/certs.d/ghcr.io
sudo cp <CA_CERT_FILE> /etc/docker/certs.d/ghcr.io/ca.crt

<設定反映>
sudo systemctl restart docker

該当の証明書チェーンまで必要の場合は、以下で取得できます。

例)ghcr.ioの場合

echo | openssl s_client -showcerts -servername ghcr.io -connect ghcr.io:443 2>/dev/null \
  | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ghcr-proxy-chain.crt

Discussion