Teste de velocidade de mirrors Docker: 3 métodos + scripts de troca automática

Você já passou por isso? O pipeline de CI/CD fica preso em 99% no docker pull, os logs repetem “connection timeout” e “TLS handshake timeout”, e o deploy já está parado há dez minutos.
Na semana passada, um dos meus projetos caiu exatamente nessa armadilha. Não chegou a derrubar uma implantação de madrugada, mas foram 7 tentativas seguidas, cada uma exigindo trocar manualmente o mirror, reiniciar o Docker daemon e tentar de novo. Quase meia hora perdida. O pior é que você nem sabe qual mirror ainda funciona: o acelerador da Alibaba Cloud limita bastante servidores fora da própria nuvem, o mirror da USTC parou em junho do ano passado, e alguns mirrors de terceiros que prometem ser “rápidos” às vezes nem passam em um teste básico de conectividade.
Isso leva a uma pergunta bem prática: como testar rapidamente e encontrar o mirror Docker mais rápido para o seu ambiente de rede atual?
Este texto não vai só listar uma pilha de endereços para você testar um por um, porque esse tipo de artigo já existe aos montes. O foco aqui é outro: a lógica técnica por trás do teste de velocidade, os prós e contras de três métodos de medição e dois scripts de automação prontos para usar, em Shell e Python. No final, também compartilho dados testados em maio de 2026 sobre mirrors disponíveis na China, para você saber quais fontes ainda são realmente utilizáveis.
Comparando métodos de teste: ping, HTTP HEAD e pull real
Existem três formas comuns de testar mirrors Docker: teste com ping, teste com HTTP HEAD e pull real de uma imagem. Cada uma tem vantagens e limitações. A tabela abaixo resume as diferenças.
| Método | Princípio | Vantagens | Limitações | Melhor uso |
|---|---|---|---|---|
| Teste com ping | Tempo de resposta ICMP | Simples e rápido | Não reflete a velocidade real de download; alguns servidores bloqueiam ping | Triagem inicial |
| Teste com HTTP HEAD | Endpoint /v2/ da Registry API | API padronizada; valida suporte a V2 | Mede conectividade, não velocidade de download | Verificação de disponibilidade |
| Pull real | docker pull de uma imagem real | É o reflexo mais fiel da velocidade real | Demora mais e consome banda | Validação final |
Por que ping não é preciso o suficiente?
Muita gente pensa primeiro em ping, porque é simples: uma linha de comando já mostra a latência. Só que ping mede resposta ICMP, e isso não tem nada a ver diretamente com o download real de uma imagem Docker.
Um exemplo: determinado servidor de mirror pode bloquear ICMP, como muitos provedores de nuvem fazem por segurança. Nesse caso, o ping mostra timeout, mas as requisições HTTP funcionam normalmente. O contrário também acontece: alguns nós de CDN respondem ping em 20ms, mas a requisição HTTP passa por redirecionamentos, negociação TLS e limitação de banda. Na prática, o download fica lento demais.
O jeito padrão de testar com HTTP HEAD
A especificação Docker Registry API v2 define um endpoint de verificação de saúde: /v2/. Você envia uma requisição HEAD ou GET para esse endpoint. Se receber 200 OK, significa que aquela Registry suporta a API V2 e está disponível naquele momento.
A lógica central é esta:
curl -I -m 5 https://docker.xuanyuan.me/v2/
Se você vir HTTP/2 200, esse mirror está acessível. O tempo de resposta, medido desde o envio da requisição até o recebimento dos headers, dá uma boa noção de latência de rede. Não é velocidade de download, mas já permite avaliar conectividade e rapidez de resposta.
Pull real: a validação mais fiel
O método mais confiável é, claro, fazer docker pull de uma imagem real. Eu costumo usar Alpine, que tem cerca de 5 MB, porque é pequena, baixa rápido e não consome tanta banda.
time docker pull alpine:latest
Observe o tempo real: ele representa o tempo total desde o início da requisição até a conclusão do pull. A partir daí, você pode calcular a velocidade média de download, dividindo o tamanho da imagem pelo tempo total. Essa é a velocidade que você vai sentir de verdade durante um deploy.
Mas esse método tem um problema: é lento. Testar um mirror pode levar de alguns segundos a dezenas de segundos. Testar dez mirrors pode tomar alguns minutos. Além disso, pode haver diferença de cache entre os mirrors: alguns já têm Alpine em cache, outros não. Isso afeta a comparação.
Minha recomendação: primeiro use HTTP HEAD para filtrar rapidamente os mirrors conectáveis, removendo os que não respondem ou respondem muito devagar. Depois use pull real para validar os 3 a 5 candidatos mais rápidos. Assim você ganha eficiência sem abrir mão de um resultado confiável.
Script Shell: teste de velocidade e troca automática em um comando
Se você trabalha com operações ou vive ajustando servidores, um script Shell provavelmente é o caminho mais rápido. Escrevi um script que testa mirrors em paralelo, ordena os resultados automaticamente e atualiza o daemon.json. Dá para usar direto.
Lógica principal: teste paralelo + ordenação automática
A ideia do script é simples: definir uma lista de mirrors, testar o endpoint /v2/ de cada um com curl, ordenar os resultados por tempo de resposta, selecionar os mais rápidos e modificar /etc/docker/daemon.json.
Veja primeiro a função de teste:
#!/bin/bash
# Lista de mirrors testados como disponíveis em maio de 2026
MIRRORS=(
"https://docker.xuanyuan.me"
"https://docker.1ms.run"
"https://docker.m.daocloud.io"
"https://atomhub.openatom.cn"
)
# Testa o tempo de resposta de um mirror em milissegundos
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" # Mirrors com falha recebem um valor muito alto
fi
}
Há um detalhe importante aqui: uso date +%s%N para pegar um timestamp em nanossegundos e divido por 1000000 para converter o tempo para milissegundos. Mirrors que falham, ou seja, que não retornam status HTTP 200, recebem 999999 milissegundos. Assim eles caem para o fim da ordenação.
Teste paralelo com xargs
Testar dez mirrors um por um é lento demais. Por isso uso xargs -P para paralelizar:
# Testa todos os mirrors em paralelo
results=$(printf "%s\n" "${MIRRORS[@]}" | \
xargs -P 4 -I {} bash -c 'test_mirror "$@"' _ {})
# Ordena por tempo de resposta em ordem crescente
sorted=$(echo "$results" | sort -t '|' -k1 -n)
# Exibe o resultado ordenado
echo "Resultado do teste de velocidade (quanto menor o tempo de resposta, melhor):"
echo "$sorted" | while IFS='|' read time url; do
if [[ "$time" != "999999" ]]; then
echo " ${time}ms $url"
else
echo " [falha] $url"
fi
done
xargs -P 4 significa executar 4 tarefas em paralelo. Você pode ajustar esse número conforme o servidor: em ambiente de teste, 2 a 4 já costuma bastar; em produção, 8 a 10 pode fazer sentido.
Atualizando o daemon.json automaticamente
O último passo é gravar os 3 mirrors mais rápidos no daemon.json.
# Extrai os 3 mirrors mais rápidos
top3=$(echo "$sorted" | grep -v "999999" | head -n 3 | cut -d '|' -f 2)
# Monta o array JSON
mirrors_json=$(echo "$top3" | sed 's/.*/"&"/' | tr '\n' ',' | sed 's/,$//')
# Atenção: sobrescrever diretamente pode apagar configurações existentes.
# Se o seu daemon.json já tiver outros campos, como data-root ou log-driver,
# faça o merge manualmente.
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [$mirrors_json]
}
EOF
echo "daemon.json atualizado. Mirrors mais rápidos:"
echo "$top3"
# Reinicia o serviço Docker; requer permissão de root
if [[ $EUID -eq 0 ]]; then
systemctl restart docker
echo "Serviço Docker reiniciado. A configuração já está ativa."
else
echo "Permissão de root necessária para reiniciar o Docker. Execute manualmente: sudo systemctl restart docker"
fi
Como usar
Salve o script como docker-mirror-test.sh e adicione permissão de execução com chmod +x:
chmod +x docker-mirror-test.sh
sudo ./docker-mirror-test.sh # Requer root para modificar daemon.json
Depois da execução, você verá uma saída parecida com esta:
Resultado do teste de velocidade (quanto menor o tempo de resposta, melhor):
45ms https://docker.xuanyuan.me
68ms https://docker.1ms.run
120ms https://docker.m.daocloud.io
[falha] https://atomhub.openatom.cn
daemon.json atualizado. Mirrors mais rápidos:
https://docker.xuanyuan.me
https://docker.1ms.run
https://docker.m.daocloud.io
Vale reforçar uma pegadinha: se o servidor já tiver outras configurações Docker, como data-root ou log-driver, sobrescrever o daemon.json diretamente vai apagar esses campos. O caminho mais seguro é ler a configuração atual e apenas adicionar ou substituir registry-mirrors, em vez de sobrescrever tudo. O script em Python abaixo faz exatamente isso, então recomendo priorizá-lo quando a configuração for mais complexa.
Script Python: temporização mais precisa e melhor tratamento de erro
Se você não se sente tão à vontade com Shell, ou precisa de temporização mais precisa e tratamento de erro melhor, a versão em Python fica mais tranquila. A biblioteca requests permite controlar timeout com precisão, capturar exceções variadas e ainda roda em macOS, Windows e Linux.
Função principal de teste
import requests
import time
import json
from pathlib import Path
# Lista de mirrors testados como disponíveis em maio de 2026
MIRRORS = [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://atomhub.openatom.cn",
]
def test_mirror(url, timeout=5):
"""Testa o tempo de resposta de um mirror em milissegundos."""
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 # Converte para milissegundos
if r.status_code == 200:
return elapsed, url
else:
return float('inf'), url
except requests.exceptions.RequestException:
return float('inf'), url
Aqui também há um detalhe: uso allow_redirects=True porque alguns mirrors redirecionam para nós de CDN, e o que importa é o tempo de resposta final. Também adiciono um User-Agent para reduzir o risco de algum CDN tratar a requisição como scraping e bloqueá-la.
Teste paralelo com ThreadPoolExecutor
O módulo concurrent.futures do Python oferece um pool de threads, mais flexível que xargs:
from concurrent.futures import ThreadPoolExecutor, as_completed
def test_all_mirrors(mirrors, max_workers=4):
"""Testa todos os mirrors em paralelo."""
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 devolve os resultados conforme cada tarefa termina, evitando bloqueios desnecessários. Você pode usar max_workers=8 ou mais, dependendo do desempenho do servidor e da largura de banda.
Atualizando daemon.json sem apagar a configuração existente
Esta versão lê o daemon.json atual e adiciona o campo registry-mirrors, em vez de sobrescrever o arquivo inteiro:
def update_daemon_json(fastest_mirrors, daemon_path="/etc/docker/daemon.json"):
"""Atualiza o daemon.json preservando a configuração existente."""
path = Path(daemon_path)
# Lê a configuração atual
if path.exists():
config = json.loads(path.read_text())
else:
config = {}
# Atualiza registry-mirrors
config["registry-mirrors"] = fastest_mirrors[:3]
# Grava a configuração
path.write_text(json.dumps(config, indent=2))
print(f"{daemon_path} atualizado. Mirrors mais rápidos:")
for m in fastest_mirrors[:3]:
print(f" {m}")
def main():
print("Testando mirrors Docker...")
results = test_all_mirrors(MIRRORS)
print("\nResultado do teste de velocidade (quanto menor o tempo de resposta, melhor):")
for elapsed, url in results:
if elapsed != float('inf'):
print(f" {elapsed:.0f}ms {url}")
else:
print(f" [falha] {url}")
# Extrai mirrors válidos
valid_mirrors = [url for elapsed, url in results if elapsed != float('inf')]
if valid_mirrors:
update_daemon_json(valid_mirrors)
print("\nReinicie o serviço Docker para aplicar a configuração: sudo systemctl restart docker")
else:
print("\nTodos os mirrors falharam. Verifique a rede ou a lista de mirrors.")
if __name__ == "__main__":
main()
Como usar
Salve o script como docker-mirror-test.py e execute:
python3 docker-mirror-test.py
Exemplo de saída:
Testando mirrors Docker...
Resultado do teste de velocidade (quanto menor o tempo de resposta, melhor):
42ms https://docker.xuanyuan.me
71ms https://docker.1ms.run
118ms https://docker.m.daocloud.io
[falha] https://atomhub.openatom.cn
/etc/docker/daemon.json atualizado. Mirrors mais rápidos:
https://docker.xuanyuan.me
https://docker.1ms.run
https://docker.m.daocloud.io
Reinicie o serviço Docker para aplicar a configuração: sudo systemctl restart docker
Na prática, a versão em Python é um pouco mais lenta que a versão Shell, algo como 10 a 20 ms de overhead. Em troca, ela oferece mais precisão e lida melhor com erros. Se a configuração Docker do seu servidor for mais complexa, a versão Python é mais segura, porque não apaga outros campos.
Dados testados de mirrors na China em 2026
O estado dos mirrors muda rápido: o que funcionava no ano passado pode ter parado este ano; o que era rápido no mês passado pode estar limitado agora. Organizei abaixo os dados testados em maio de 2026 como referência.
Mirrors disponíveis testados
| Mirror | Endereço | Velocidade média | Estabilidade | Observações |
|---|---|---|---|---|
| Xuanyuan Mirror | https://docker.xuanyuan.me | 12,3 MB/s | 99,2% | Suporte multiplataforma, operação compatível dentro da China |
| 1ms Mirror | https://docker.1ms.run | 11,8 MB/s | 99,5% | SLA de nível financeiro, boa opção para empresas |
| DaoCloud | https://docker.m.daocloud.io | 9,5 MB/s | 97,6% | Serviço antigo, útil como opção de backup |
| AtomHub | https://atomhub.openatom.cn | 8,2 MB/s | 100% | Projeto público oficial da OpenAtom Foundation |
Esses dados vêm de um relatório testado da comunidade de desenvolvedores da Tencent Cloud, de março de 2026. Eu também validei com HTTP HEAD e os números parecem basicamente consistentes. Xuanyuan Mirror e 1ms Mirror foram os mais rápidos e estáveis, então são os primeiros que eu testaria.
Mirrors que já perderam utilidade entre 2024 e 2026
Estes mirrors já foram utilizáveis, mas hoje estão descontinuados ou com limitação pesada:
| Mirror | Endereço | Status | Observações |
|---|---|---|---|
| USTC | https://docker.mirrors.ustc.edu.cn | Descontinuado | Parou de atender publicamente em junho de 2024 |
| NetEase | http://hub-mirror.c.163.com | Descontinuado | Sincronização encerrada; imagens desatualizadas |
| Acelerador oficial da Alibaba Cloud | https://registry.cn-hangzhou.aliyuncs.com | Limitação pesada | Limita servidores fora da Alibaba Cloud; não recomendo |
Sendo bem direto, eu também já caí na pegadinha do acelerador da Alibaba Cloud. Configurei esse acelerador em um servidor da Tencent Cloud e o pull de imagens vivia dando timeout. Só depois entendi que a Alibaba Cloud limita bastante servidores que não estão na própria infraestrutura. Se você usa Alibaba Cloud ECS, o acelerador pode ser realmente rápido. Em ambientes de outros provedores, não conte com isso.
A situação de usuários de NAS e desenvolvedores na China
Se você usa NAS da Synology ou da ZSpace, escolher mirror pode ser ainda mais chato. Alterar a configuração Docker em um NAS não é tão simples quanto em um servidor comum, e alguns sistemas até bloqueiam a edição do daemon.json.
Nesse caso, minha sugestão é usar AtomHub, projeto oficial da OpenAtom Foundation. Ele tem caráter público, não limita tráfego e não cobra. A estabilidade foi de 100%. A velocidade não bate Xuanyuan ou 1ms, mas pelo menos é estável e disponível. Além disso, o AtomHub não depende de um provedor de nuvem específico, então a experiência tende a ser mais consistente entre plataformas.
Nota sobre validade temporal: o estado dos mirrors muda rápido, e os dados deste texto vão até maio de 2026. Antes de usar em produção, rode os scripts de teste acima periodicamente, ou configure uma tarefa agendada para testar e atualizar a configuração toda semana.
Boas práticas para configurar daemon.json
Depois do teste de velocidade, o próximo passo é configurar o Docker daemon. Uma configuração correta permite tolerância a falhas: se o primeiro mirror falhar, o Docker tenta o próximo automaticamente.
Configuração recomendada
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
Configurar 2 ou 3 mirrors já é suficiente. Não coloque mirrors demais: o Docker tenta em ordem e retorna assim que o primeiro disponível responde. Os seguintes nem chegam a ser usados. Uma lista longa só aumenta o custo de resolução e a chance de incluir fontes inválidas.
Como funciona a tolerância a falhas do Docker
O campo registry-mirrors do Docker daemon funciona assim:
- Você executa
docker pull ubuntu:latest - O Docker tenta primeiro o primeiro mirror:
docker.xuanyuan.me - Se o primeiro mirror der timeout ou retornar erro, o Docker troca automaticamente para o segundo:
docker.1ms.run - Se todos os mirrors falharem, só então ele volta para a fonte oficial do Docker Hub
A vantagem é clara: se um mirror cair, seu deploy não precisa parar. A desvantagem também existe: se o primeiro mirror estiver lento, mas não falhar, o Docker continua usando ele e não muda automaticamente para uma opção mais rápida.
Por isso, testar periodicamente faz sentido. O mirror mais rápido deve ficar em primeiro, e o segundo mais rápido deve ficar logo depois.
Verificando se a configuração entrou em vigor
Depois de alterar a configuração, reinicie o serviço Docker:
sudo systemctl restart docker
Em seguida, valide se os mirrors foram aplicados:
docker info | grep -A 5 "Registry Mirrors"
Você verá algo parecido com isto:
Registry Mirrors:
https://docker.xuanyuan.me/
https://docker.1ms.run/
https://docker.m.daocloud.io/
Se isso aparecer, a configuração funcionou. A partir daí, ao baixar imagens, o Docker vai priorizar esses mirrors.
Caminho de configuração no macOS e no Windows
Se você usa Docker Desktop no macOS ou no Windows, o caminho de configuração é diferente:
- macOS: abra Docker Desktop → Settings → Docker Engine → edite o JSON
- Windows: o mesmo caminho, em Settings → Docker Engine
O conteúdo da configuração é igual; o que muda é a interface. Depois de editar, clique em “Apply & Restart”, e o Docker Desktop reinicia automaticamente.
Vale lembrar: o daemon.json também pode conter outros campos, como data-root, para caminho de armazenamento das imagens, log-driver, para driver de logs, e storage-driver, para driver de armazenamento. Se você já usa esses campos, combine-os com registry-mirrors no mesmo JSON. Não sobrescreva o arquivo inteiro. A versão Python do script já cuida disso; na versão Shell, você precisa fazer o merge manualmente.
Resumo
Depois de tudo isso, a ideia central cabe em três pontos:
-
Método de teste: primeiro use HTTP HEAD para filtrar mirrors conectáveis; depois use pull real para validar os candidatos mais rápidos. Não use ping como critério principal, porque ele mede resposta ICMP e não tem relação direta com velocidade de download.
-
Scripts de automação: a versão Shell serve para deploy rápido em operações; a versão Python é melhor para medição mais precisa e uso multiplataforma. As duas conseguem atualizar
daemon.jsonautomaticamente e reduzem o trabalho manual. -
Escolha de mirrors: em testes de maio de 2026, Xuanyuan Mirror e 1ms Mirror foram os mais rápidos e estáveis; AtomHub é uma boa opção para usuários de NAS e cenários públicos. Mirrors já inválidos, como USTC, NetEase e a versão limitada da Alibaba Cloud, devem ficar fora da configuração.
Recomendações práticas:
- Baixe o script de teste deste texto, em Shell ou Python, e meça os mirrors no seu ambiente de rede atual
- Configure uma tarefa agendada, com
cronousystemd timer, para testar e atualizar a configuração toda semana. Mirrors mudam rápido; só a validação recorrente dá segurança - Se você cuida do CI/CD de uma equipe, integre o script ao pipeline e valide a disponibilidade dos mirrors antes do deploy. Isso evita alertas no meio da noite por falha no pull de imagens
Por fim, se este texto foi útil, vale compartilhar com o time ou com outros desenvolvedores do seu grupo. Problemas com mirrors Docker são bem comuns, e muita gente ainda perde tempo trocando fonte manualmente.
15 min de leitura · Publicado em: 27 mai 2026 · Atualizado em: 14 jul 2026
Guia prático Docker
Se você chegou pela busca, o caminho mais rápido é ir para o post anterior ou próximo desta série.
Anterior
Guia de mirrors do Docker na China em 2026: resolva o timeout no pull em 5 minutos
Como avaliar os mirrors do Docker disponíveis na China em 2026: configure o daemon.json, teste a velocidade, trate proxies corporativos e pull-through cache e diferencie o limite do Docker Hub (429) de uma falha no mirror para diagnosticar um timeout no docker pull em 5 minutos.
Parte 23 de 38
Próximo
Timeout no docker pull em rede corporativa: DNS, proxy e mirrors
Docker pull travando ou dando timeout em rede corporativa? Veja um fluxo completo de diagnóstico com DNS, proxy e mirrors, além de uma lista de fontes testadas em maio de 2026.
Parte 25 de 38



Comentários
Entre com GitHub para comentar