Docker ミラーソース速度テスト実践:3 つの方法 + 自動切り替えスクリプト
こんな経験はありませんか?CI/CD パイプラインが docker pull の 99% で止まり、ログに “connection timeout” や “TLS handshake timeout” が繰り返し出て、デプロイが 10 分間止まったままになる。
先週、私のプロジェクトでも同じ罠にはまりました。深夜のデプロイ失敗ほどではありませんでしたが、7 回連続でリトライし、毎回手動でミラーソースを切り替え、Docker daemon を再起動——結果、解決まで約 30 分かかりました。いちばん困るのは、どのミラーソースが使えるのかわからないことです。Alibaba Cloud のアクセラレータは非 Alibaba サーバーでは厳しくレート制限され、中科大のミラーは昨年 6 月に停止。「高速」とうたうサードパーティ源は、接続性テストすら通らないこともあります。
ここで問いが浮かびます。今のネットワーク環境で、いちばん速いミラーソースをどうやって素早く見つけるか?
この記事では、ミラーアドレスを羅列して一つずつ試させるような内容は書きません(そういう記事は多すぎます)。速度テストの技術原理、3 つの方法の長所と短所、すぐ使える自動化スクリプト(Shell 版と Python 版)を説明します。最後に 2026 年 5 月の国内ミラーソース実測データも共有し、今どれが本当に使えるかをお伝えします。
速度テスト方法の比較 — ping、HTTP HEAD、実際の pull
ミラーソースの速度テストには 3 つの主流手法があります。ping テスト、HTTP HEAD テスト、実際のイメージ pull です。それぞれ長所と短所があるので、まず表で整理します。
| 方法 | 原理 | 長所 | 短所 | 適用シーン |
|---|---|---|---|---|
| Ping テスト | ICMP 応答時間 | シンプルで速い | 実際のダウンロード速度を反映しない。一部サーバーは ping を禁止 | 初期ふるい分け |
| HTTP HEAD テスト | Registry API の /v2/ エンドポイント | 標準 API で V2 対応を確認できる | 接続性のみ。ダウンロード速度ではない | 可用性の検証 |
| 実際の pull テスト | docker pull で本物のイメージを取得 | 実速度を最も正確に反映 | 時間がかかり、帯域を消費 | 最終確認 |
なぜ ping だけでは不十分か
多くの人が最初に ping を試します。コマンド一行でレイテンシが見えるからです。しかし ping は ICMP 応答を測るだけで、イメージのダウンロードとはまったく別物です。
例えば、あるミラーソースサーバーが ICMP を無効にしている(セキュリティ上、多くのクラウド事業者がそうします)と、ping はタイムアウトに見えても HTTP リクエストは問題なく通ります。逆に、CDN ノードの ping が 20ms でも、ルーティングや TLS ネゴシエーション、帯域制限のせいで HTTP ダウンロードは極端に遅いこともあります。
HTTP HEAD テストの標準的なやり方
Docker Registry API v2 仕様には、ヘルスチェック用エンドポイント /v2/ が定義されています。このエンドポイントに HEAD または GET を送り、200 OK が返れば、その Registry は V2 API に対応しており、現在利用可能です。
コアのロジックは次のとおりです。
curl -I -m 5 https://docker.xuanyuan.me/v2/
HTTP/2 200 が見えれば、そのミラーソースには今接続できます。リクエスト送信からヘッダー受信までの応答時間は、おおまかなネットワークレイテンシを示します——ダウンロード速度ではありませんが、接続性と応答の速さは判断できます。
実際の pull テスト:最も信頼できる検証
いちばん確実なのは、やはり docker pull で実イメージを取得することです。私は Alpine(約 5MB)をよく使います。小さく pull も速く、帯域をあまり食いません。
time docker pull alpine:latest
real の時間に注目してください。リクエスト開始から pull 完了までの総時間です。イメージサイズ ÷ 総時間で平均ダウンロード速度を算出でき、デプロイ時に体感する速度に近いです。
ただし欠点もあります。遅いことです。1 源あたり数秒〜数十秒、10 源なら数分。ミラー間のキャッシュ差もあり、Alpine をキャッシュ済みの源と未キャッシュの源では公平性が崩れます。
おすすめは、まず HTTP HEAD で接続可能なミラーを素早くふるい分け(接続不可・応答が遅いものを除外)、そのうえで上位 3〜5 源を実際の pull で最終確認することです。効率も結果の信頼性も両立できます。
Shell スクリプト実装 — ワンクリック速度テストと自動切り替え
運用担当やサーバーをいじることが多いなら、Shell スクリプトがいちばん手早いでしょう。並列速度テスト、自動ソート、daemon.json 更新まで行うスクリプトを用意しました。そのまま使えます。
コアロジック:並列速度テスト + 自動ソート
スクリプトの考え方はシンプルです。ミラーソースのリストを定義し、各源の /v2/ エンドポイント応答時間を curl で測定、結果をソートして上位数件を選び、/etc/docker/daemon.json を自動更新します。
まず速度テスト関数から。
#!/bin/bash
# ミラーソース一覧(2026 年 5 月時点で実測利用可能)
MIRRORS=(
"https://docker.xuanyuan.me"
"https://docker.1ms.run"
"https://docker.m.daocloud.io"
"https://atomhub.openatom.cn"
)
# 単一ミラーソースの応答時間を測定(ミリ秒)
test_mirror() {
local mirror=$1
local start=$(date +%s%N)
local http_code=$(curl -s -o /dev/null -w "%{http_code}" \
--connect-timeout 5 \
--max-time 10 \
"$mirror/v2/")
local end=$(date +%s%N)
local elapsed=$(( (end - start) / 1000000 ))
if [[ "$http_code" == "200" ]]; then
echo "$elapsed|$mirror"
else
echo "999999|$mirror" # 失敗した源は極大値としてマーク
fi
}
ここで date +%s%N でナノ秒タイムスタンプを取り、elapsed を 1000000 で割ってミリ秒に変換しています。失敗した源(HTTP ステータスが 200 以外)は 999999 ミリ秒としてマークし、ソート時に末尾へ回します。
並列速度テスト:xargs マルチスレッド
10 源を順番に測るのは遅すぎます。xargs -P で並列化します。
# すべてのミラーソースを並列で速度テスト
results=$(printf "%s\n" "${MIRRORS[@]}" | \
xargs -P 4 -I {} bash -c 'test_mirror "$@"' _ {})
# 応答時間でソート(昇順)
sorted=$(echo "$results" | sort -t '|' -k1 -n)
# ソート結果を出力
echo "速度テスト結果(応答時間が短いほど良い):"
echo "$sorted" | while IFS='|' read time url; do
if [[ "$time" != "999999" ]]; then
echo " ${time}ms $url"
else
echo " [失敗] $url"
fi
done
xargs -P 4 は 4 スレッド並列です。サーバー性能に合わせて調整してください。テスト環境なら 2〜4、本番なら 8〜10 まで上げても構いません。
daemon.json の自動更新
最後に、最速 3 源を daemon.json に書き込みます。
# 最速の 3 ソースを抽出
top3=$(echo "$sorted" | grep -v "999999" | head -n 3 | cut -d '|' -f 2)
# JSON 配列を構築
mirrors_json=$(echo "$top3" | sed 's/.*/"&"/' | tr '\n' ',' | sed 's/,$//')
# ⚠️ 警告:直接上書きすると既存設定が失われます!
# daemon.json に他のフィールド(data-root、log-driver)がある場合は手動でマージしてください
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [$mirrors_json]
}
EOF
echo "daemon.json を更新しました。最速ミラーソース:"
echo "$top3"
# Docker サービスを再起動(root 権限が必要)
if [[ $EUID -eq 0 ]]; then
systemctl restart docker
echo "Docker サービスを再起動しました。設定が有効になりました"
else
echo "Docker の再起動には root 権限が必要です。手動で実行してください:sudo systemctl restart docker"
fi
使い方
スクリプトを docker-mirror-test.sh として保存し、実行権限を付与します。
chmod +x docker-mirror-test.sh
sudo ./docker-mirror-test.sh # daemon.json の変更には root 権限が必要
実行後、出力はおおむね次のようになります。
速度テスト結果(応答時間が短いほど良い):
45ms https://docker.xuanyuan.me
68ms https://docker.1ms.run
120ms https://docker.m.daocloud.io
[失敗] https://atomhub.openatom.cn
daemon.json を更新しました。最速ミラーソース:
https://docker.xuanyuan.me
https://docker.1ms.run
https://docker.m.daocloud.io
ただし落とし穴があります。サーバーに既存の Docker 設定(data-root や log-driver など)がある場合、daemon.json を上書きするとそれらが消えます。より安全なのは既存設定を読み込み、registry-mirrors だけ追記することです。Python 版はこの処理を実装しているので、そちらを優先するのがおすすめです。
Python スクリプト実装 — 精密計測とエラーハンドリング
Shell に慣れていない、より精密な計測やエラー処理が欲しいなら Python 版が向いています。requests でタイムアウトを細かく制御し、各種例外も捕捉できます。macOS、Windows、Linux すべてで動きます。
コア速度テスト関数
import requests
import time
import json
from pathlib import Path
# ミラーソース一覧(2026 年 5 月時点で実測利用可能)
MIRRORS = [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://atomhub.openatom.cn",
]
def test_mirror(url, timeout=5):
"""単一ミラーソースの応答時間を測定(ミリ秒)"""
start = time.time()
try:
r = requests.head(
f"{url}/v2/",
timeout=timeout,
allow_redirects=True,
headers={"User-Agent": "docker-mirror-test/1.0"}
)
elapsed = (time.time() - start) * 1000 # ミリ秒に変換
if r.status_code == 200:
return elapsed, url
else:
return float('inf'), url
except requests.exceptions.RequestException:
return float('inf'), url
allow_redirects=True にしているのは、CDN ノードへリダイレクトされるミラーがあり、最終応答時間を追跡するためです。User-Agent ヘッダーで、一部 CDN のボット判定によるブロックを避けています。
並列速度テスト:ThreadPoolExecutor
Python の concurrent.futures は Shell の xargs より柔軟です。
from concurrent.futures import ThreadPoolExecutor, as_completed
def test_all_mirrors(mirrors, max_workers=4):
"""すべてのミラーソースを並列でテスト"""
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_url = {
executor.submit(test_mirror, url): url
for url in mirrors
}
for future in as_completed(future_to_url):
elapsed, url = future.result()
results.append((elapsed, url))
return sorted(results, key=lambda x: x[0])
as_completed は完了順に結果を返すのでブロックしません。max_workers=8 以上も、サーバー性能と帯域に応じて設定できます。
daemon.json の自動更新(既存設定を保持)
この版は既存の daemon.json を読み込み、registry-mirrors だけ更新します。上書きしません。
def update_daemon_json(fastest_mirrors, daemon_path="/etc/docker/daemon.json"):
"""daemon.json を更新(既存設定を保持)"""
path = Path(daemon_path)
# 既存設定を読み込み
if path.exists():
config = json.loads(path.read_text())
else:
config = {}
# registry-mirrors を更新
config["registry-mirrors"] = fastest_mirrors[:3]
# 設定を書き込み
path.write_text(json.dumps(config, indent=2))
print(f"{daemon_path} を更新しました。最速ミラーソース:")
for m in fastest_mirrors[:3]:
print(f" {m}")
def main():
print("ミラーソースを速度テスト中...")
results = test_all_mirrors(MIRRORS)
print("\n速度テスト結果(応答時間が短いほど良い):")
for elapsed, url in results:
if elapsed != float('inf'):
print(f" {elapsed:.0f}ms {url}")
else:
print(f" [失敗] {url}")
# 有効なミラーソースを抽出
valid_mirrors = [url for elapsed, url in results if elapsed != float('inf')]
if valid_mirrors:
update_daemon_json(valid_mirrors)
print("\nDocker サービスを再起動して設定を反映してください:sudo systemctl restart docker")
else:
print("\nすべてのミラーソースが失敗しました。ネットワークまたはミラーソース一覧を確認してください")
if __name__ == "__main__":
main()
使い方
スクリプトを docker-mirror-test.py として保存し、実行します。
python3 docker-mirror-test.py
出力例:
ミラーソースを速度テスト中...
速度テスト結果(応答時間が短いほど良い):
42ms https://docker.xuanyuan.me
71ms https://docker.1ms.run
118ms https://docker.m.daocloud.io
[失敗] https://atomhub.openatom.cn
/etc/docker/daemon.json を更新しました。最速ミラーソース:
https://docker.xuanyuan.me
https://docker.1ms.run
https://docker.m.daocloud.io
Docker サービスを再起動して設定を反映してください:sudo systemctl restart docker
Python 版は Shell 版よりわずかに遅い(おおよそ 10〜20ms のオーバーヘッド)ものの、精度とエラー処理は優れています。Docker 設定が複雑なサーバーでは、他フィールドを消さない Python 版のほうが安全です。
2026 年 国内ミラーソース実測データ
ミラーソースの状態は変わりやすい——昨年使えたものが今年止まる、先月速かったものが今月レート制限される、といったことが日常茶飯事です。2026 年 5 月の実測データを整理しました。
利用可能なミラーソース実測データ
| ミラーソース | アドレス | 平均速度 | 安定性 | 備考 |
|---|---|---|---|---|
| 軒轅ミラー | https://docker.xuanyuan.me | 12.3 MB/s | 99.2% | 全プラットフォーム対応、国内コンプライアンス運用 |
| ミリ秒ミラー | https://docker.1ms.run | 11.8 MB/s | 99.5% | 金融グレード SLA、エンタープライズ向け |
| DaoCloud | https://docker.m.daocloud.io | 9.5 MB/s | 97.6% | 老舗サービス、バックアップ候補 |
| AtomHub | https://atomhub.openatom.cn | 8.2 MB/s | 100% | 開放原子開源基金会公式の公益プロジェクト |
データは Tencent Cloud 開発者コミュニティの実測レポート(2026-03)に基づき、HTTP HEAD 速度テストでも検証済みです。軒轅ミラーとミリ秒ミラーが最速かつ最も安定しており、優先利用をおすすめします。
失効したミラーソース(2024〜2026)
かつて使えたが、現在は停止または厳しいレート制限の対象:
| ミラーソース | アドレス | 状態 | 備考 |
|---|---|---|---|
| 中科大 | https://docker.mirrors.ustc.edu.cn | ❌ 停止 | 2024 年 6 月に外部サービス終了 |
| NetEase | http://hub-mirror.c.163.com | ❌ 停止 | 同期停止、イメージが古い |
| Alibaba Cloud 公式アクセラレータ | https://registry.cn-hangzhou.aliyuncs.com | ⚠️ 厳しいレート制限 | 非 Alibaba サーバーでは非推奨 |
Alibaba Cloud アクセラレータの罠も踏みました。Tencent Cloud サーバーで Alibaba アクセラレータを設定すると pull が頻繁にタイムアウトし、後から非自社サーバーへのレート制限があると知りました。Alibaba Cloud ECS なら確かに速いですが、クラウドをまたぐ利用は期待しないほうが無難です。
NAS ユーザーと国内開発者の現状
Synology や Zspace など NAS ユーザーにとっては、選択肢がさらに狭い。NAS では Docker 設定の変更がサーバーほど簡単ではなく、daemon.json の編集権限自体がロックされていることもあります。
その場合は AtomHub(開放原子開源基金会公式)をおすすめします。公益プロジェクトでレート制限なし・無料、安定性 100%。速度は軒轅やミリ秒に及びませんが、安定して使えます。特定クラウドに依存せず、クロスプラットフォームの体験も一貫しています。
時効性の注意:ミラーソースの状態は変化が速く、本記事のデータは 2026 年 5 月時点です。前述の速度テストスクリプトで定期的に検証するか、cron や systemd timer で週次自動テスト・設定更新を設定することをおすすめします。
daemon.json 設定のベストプラクティス
速度テストの次は Docker daemon の設定です。正しく設定すれば、最初のミラーが失敗しても自動で次へ切り替わるフェイルオーバーが働きます。
推奨設定
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
2〜3 個で十分です。多すぎると Docker が順番に試すだけで解析コストが増え、失効源が混ざりやすくなります。最初の利用可能な源で返るため、後ろに並べた源はほとんど使われません。
Docker のフェイルオーバー機構
registry-mirrors の動きは次のとおりです。
docker pull ubuntu:latestを実行- Docker は最初のミラーを試す:
docker.xuanyuan.me - タイムアウトやエラーなら 2 番目へ:
docker.1ms.run - すべて失敗した場合のみ Docker Hub 公式へフォールバック
メリットは、1 源が落ちてもデプロイが止まりにくいこと。デメリットは、1 番目が遅くてもエラーにならなければ切り替わらないことです。
だから定期速度テストに意味があります。最速を 1 番目、次点を 2 番目に並べ替えましょう。
設定反映の確認
設定変更後、Docker を再起動します。
sudo systemctl restart docker
ミラーが有効か確認:
docker info | grep -A 5 "Registry Mirrors"
出力例:
Registry Mirrors:
https://docker.xuanyuan.me/
https://docker.1ms.run/
https://docker.m.daocloud.io/
これが見えれば設定成功です。以降の pull はこれらのミラーを優先します。
macOS と Windows の設定パス
Docker Desktop(macOS / Windows)ではパスが異なります。
- macOS:Docker Desktop → Settings → Docker Engine → JSON を編集
- Windows:同様に Settings → Docker Engine で編集
内容は同じで、UI だけ違います。変更後は “Apply & Restart” で Docker Desktop が自動再起動します。
daemon.json には data-root(イメージ保存パス)、log-driver、storage-driver など他のフィールドもあります。これらがある場合は registry-mirrors と同一 JSON にマージしてください。上書きしないこと。Python 版スクリプトはこの処理を実装済みです。Shell 版は手動マージが必要です。
まとめ
要点は 3 つです。
-
速度テスト方法:まず HTTP HEAD で接続可能なミラーをふるい分け、上位数件を実際の pull で確認。ping は ICMP 応答のみで、ダウンロード速度とは無関係です。
-
自動化スクリプト:Shell 版は運用向けの迅速デプロイ、Python 版は精密計測とクロスプラットフォーム向け。どちらも daemon.json を自動更新し、手動設定の手間を省けます。
-
ミラーソース選定:2026 年 5 月実測では軒轅ミラーとミリ秒ミラーが最速・最安定。NAS や公益利用には AtomHub。中科大、NetEase、レート制限版 Alibaba Cloud はもう使わないでください。
アクション提案:
- 本記事の速度テストスクリプト(Shell または Python)をダウンロードし、今のネットワーク環境で速度を計測する
- cron や systemd timer で週次自動テスト・設定更新を設定する——ミラー状態は変わりやすいので定期検証が重要
- チームの CI/CD を担当しているなら、デプロイ前にミラー可用性を検証するようパイプラインへ組み込む。深夜の pull 失敗アラートを防げます
最後に、役に立ったと思ったらチームや開発者グループで共有してください。ミラー問題はよくあるのに、手動切り替えを続けている人も多いはずです。
5分で読めます · 公開日: 2026年5月27日 · 更新日: 2026年6月1日
Docker 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Docker ボリューム実戦ガイド:5 つの事例でコンテナのデータ消失を解決
5 つの実践事例で Docker Volume の使い方を解説。基本概念から MySQL・Redis の永続化まで、コンテナ削除後もデータを残す方法を、Docker 初心者と開発者向けに丁寧に説明します。
第 11 / 37 記事
次の記事
社内ネットワーク Docker pull タイムアウトのトラブルシューティング:DNS・プロキシ・ミラー加速の完全ガイド
社内ネットワークで Docker pull がタイムアウトする場合の完全なトラブルシューティング手順。DNS 設定、プロキシ設定、ミラー加速の 3 つの核心を網羅。2026 年 5 月時点で利用可能なミラーソース一覧付きで、問題を素早く特定して解決できます。
第 13 / 37 記事
関連記事
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker インストールの落とし穴ガイド 2025:permission denied から正常起動までの完全解決策
コメント
GitHubアカウントでログインしてコメントできます