Собственное зеркало Docker Hub
30 мая 2024 г. server
Сегодня Docker заблокировал доступ к своему репозиторию контейнеров hub.docker.com для пользователей из России. Поэтому я поднял себе уютное приватное прокси-зеркало в странах не столь отдаленных. Покажу как это быстро сделать.
UPD. 04.06.24. hub.docker.com уже снова доступен в России
Проблема
Ошибка выглядит как 403 в ответ на docker pull любого образа (веб-морда hub.docker.com тоже недоступна):
#docker pull nginx:latest
Error response from daemon: pull access denied for nginx, repository does not exist or may require 'docker login': denied: <html><body><h1>403 Forbidden</h1>
Since Docker is a US company, we must comply with US export control regulations. In an effort to comply with these, we now block all IP addresses that are located in Cuba, Iran, North Korea, Republic of Crimea, Sudan, and Syria. If you are not in one of these cities, countries, or regions and are blocked, please reach out to https://hub.docker.com/support/contact/
</body></html>
Быстрофикс
Я перепробовал кучу зеркал из интернета, вот это единственное, которое вызывает доверие и работает надежно - https://dockerhub.timeweb.cloud. Если не хочется заморачиваться со своим, то можно использовать его. Для этого в файл /etc/docker/daemon.json
(на десктопе - в настройки docker engine - см.скриншот ниже) надо добавить:
"registry-mirrors": [ "https://dockerhub.timeweb.cloud"]
Вот так выглядит мой полный daemon.json:
{
"registry-mirrors": ["https://dockerhub.timeweb.cloud"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
И перезапустить докер: service docker restart
. После этого можно пуллить образы.
Решение
Чтобы организовать свое приватное зеркало поднадобится виртуалка за границей. Сегодня уже многие российские VPC-провайдеры предоставляют возможность поднимать виртуалки в соседних странах, что очень удобно для обхода блокировок.
На созданной виртуалке я использовал Docker Registry от самого докера. Сейчас он называется Distribution — это программа, которая позволяет создать свой приватный container registry. В ней есть функция проксирования+кэш внешних репозиториев. Она и понадобится.
Создаю папки:
#mkdir /opt/registry
#mkdir /opt/registry/data
Создаю docker-compose.yml:
version: '3.3'
services:
registry:
image: registry:2
ports:
- "0.0.0.0:5000:5000"
volumes:
- "/opt/registry/config.yml:/etc/docker/registry/config.yml"
- "/opt/registry/data:/var/lib/registry"
restart: always
И создаю конфиг /opt/registry/config.yml
:
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: 0.0.0.0:5000
proxy:
remoteurl: https://registry-1.docker.io
ttl: 1d
Что важно:
- проксирование в registry-1.docker.io
- ttl для кэша в 1 день
- если
delete:true
, то будет очищать данные кэша старше 1-го дня, чтобы много места не съедало. Тут можно тюнить, если место на диске позволяет.
Теперь в папке /opt/registry
выполняю:
#docker-compose up -d
Запускается container registry, который уже можно прописывать себе в настройки докер демона /etc/docker/daemon.json
(чтобы демон подхватил настройки придётся его перезапустить):
"registry-mirrors": [
"http://my-private-registry.example.com:5000"
]
И в настройки docker на десктопе:
Опционально
Для секурности можно спрятать это за nginx:
server {
server_name my-private-registry.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
listen 80;
}
Попросить certbot выдать сертификат с редиректом, и получить красивый секурный конфиг:
server {
server_name my-private-registry.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/my-private-registry.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my-private-registry.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}server {
if ($host = my-private-registry.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name my-private-registry.example.com;
return 404; # managed by Certbot
}
И теперь в настройки докера добавить:
"registry-mirrors": [
"https://my-private-registry.example.com"
]
P.S. И не забыть заменить 0.0.0.0 на 127.0.0.1 в docker-compose.yml