使用 Nginx 搭建 Docker 镜像代理

使用 Nginx 搭建 Docker 镜像代理

前提:
1、有一个自己的外网服务器
2、有一个自己的域名,使用 Cloudflare 解析

域名:docker.xxxxxx.com

发现:有基于 Docker Registry 开源的一键脚本

思路

  1. 使用自己的外网服务器和域名(如 docker.xxxxxx.com)。
  2. 域名通过 Cloudflare 解析,证书由 acme.sh 自动申请和续期。
  3. 使用 registry:2 镜像运行本地 Docker Registry,作为 Docker Hub 的缓存代理。
  4. 使用 Nginx 做 HTTPS 反向代理,将请求转发到本地 registry。
  5. Nginx 和 registry 容器通过 Docker 自定义网络连接。
  6. 所有服务使用 Docker 容器部署,运行简单、维护方便。
  7. 客户端配置 Docker 使用该代理,加快镜像拉取速度。
  8. 使用 crontab 定期清理 registry 缓存,释放空间。

文件目录

/app
└── dockerhub
    ├── nginx_443
    │   ├── certs
    │   ├── docker.conf
    │   └── startup_nginx.sh
    └── registry-cache

操作命令

创建网络

docker network create mynet

docker 启动 registry

docker run -d \
  --restart=always \
  --name registry \
  -p 5000:5000 \
  -v /app/dockerhub/registry-cache:/var/lib/registry \
  -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \
  --network mynet \
  registry:2

docker.conf

server {
    server_tokens off;
    listen 443 ssl http2;
    server_name docker.xxxxxx.com;

    ssl_certificate     /etc/nginx/certs/docker.xxxxxx.com.crt;
    ssl_certificate_key /etc/nginx/certs/docker.xxxxxx.com.key;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_session_tickets off;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";

    location /v2/ {
        proxy_pass http://registry:5000;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_read_timeout 300;
        proxy_connect_timeout 60;
        proxy_send_timeout 300;
    }
}

docker 启动 nginx,内容在 startup_nginx.sh

docker run -d \
  --name nginx \
  --restart=unless-stopped \
  -p 443:443 \
  -v /app/dockerhub/nginx_443/certs:/etc/nginx/certs \
  -v /app/dockerhub/nginx_443/docker.conf:/etc/nginx/conf.d/default.conf \
  -v /app/dockerhub/nginx_443/logs:/var/log/nginx \
  --network mynet \
  nginx:1.28.0

安装 acme.sh

# 配置邮箱
# curl https://get.acme.sh | sh -s email=my@example.com
# 不配置邮箱
curl https://get.acme.sh | sh
# 设置别名
alias acme.sh=~/.acme.sh/acme.sh

邮箱用来通知证书是否续期成功,可以不配置邮箱,匿名申请证书。

acme.sh 在宿主机申请证书,并设置自动部署

建议只赋予单个 DNS zone 的编辑权限,避免泄漏导致更大风险。

export CF_Token="你的 Cloudflare API Token"

# 使用 Let’s Encrypt
acme.sh --set-default-ca --server letsencrypt

acme.sh --issue --dns dns_cf -d docker.xxxxxx.com --keylength ec-256

部署证书到 nginx 映射的目录,并设置证书更新后自动重启 nginx:

acme.sh --install-cert -d docker.xxxxxx.com \
  --key-file       /app/dockerhub/nginx_443/certs/docker.xxxxxx.com.key \
  --fullchain-file /app/dockerhub/nginx_443/certs/docker.xxxxxx.com.crt \
  --reloadcmd      "docker restart nginx"

每周清理一次

crontab -e
0 20 * * 2 docker stop registry && rm -rf /app/dockerhub/registry-cache/* && docker start registry

配置

# 创建 Docker 配置目录
sudo mkdir -p /etc/docker

# 使用 tee 命令将 Docker 配置写入 /etc/docker/daemon.json 文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": ["https://docker.xxxxxx.com"]
}
EOF

# 重启 Docker 服务,使新配置生效
sudo systemctl restart docker
posted @ 2025-06-30 17:08  ioufev  阅读(441)  评论(0)    收藏  举报