You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无法登录私有Docker Registry遇502错误,求助HTTP转HTTPS方法

解决Docker Registry HTTP到HTTPS重定向及502登录失败问题

看起来你已经完成了基础的hosts映射和Docker insecure配置,但卡在了HTTP到HTTPS的重定向环节,而且502 Bad Gateway错误也说明请求链路存在问题。我来给你两种实用的解决方案,帮你彻底搞定这个问题:

方案一:用Nginx做反向代理实现HTTP→HTTPS重定向

这是生产环境里最常用的方式,因为Docker Registry本身并不支持直接配置HTTP到HTTPS的重定向,借助Nginx可以轻松实现这个需求,同时还能更好地管理SSL证书:

  1. 生成SSL证书(自签名或正式证书)
    如果没有购买正式SSL证书,用OpenSSL生成自签名证书即可:

    mkdir -p /certs
    openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/domain.key -x509 -days 365 -out /certs/domain.crt
    

    填写信息时,Common Name一定要填你的Registry主机名(也就是你配置的hostname,否则证书会不匹配。

  2. 配置Nginx代理规则
    创建Nginx配置文件(比如/etc/nginx/conf.d/registry.conf),把下面的内容粘贴进去,记得替换掉所有hostname为你的实际主机名:

    # 处理HTTP请求,直接重定向到HTTPS
    server {
        listen 80;
        server_name hostname;
    
        return 301 https://$host$request_uri;
    }
    
    # 处理HTTPS请求,代理到Docker Registry服务
    server {
        listen 443 ssl;
        server_name hostname;
    
        ssl_certificate /certs/domain.crt;
        ssl_certificate_key /certs/domain.key;
    
        location /v2/ {
            proxy_pass http://localhost:5000/v2/;
            proxy_set_header Host $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;
        }
    }
    
  3. 调整Registry的监听方式
    为了安全,让Registry只监听本地端口,避免直接暴露HTTP到外部,重启Registry容器时用这个命令:

    docker run -d -p 127.0.0.1:5000:5000 --restart=always --name registry registry:2
    

    如果之前已经有Registry容器,先停止删除再重新启动:

    docker stop registry && docker rm registry
    
  4. 重启服务并验证
    重启Nginx和Registry,然后验证HTTPS是否正常:

    systemctl restart nginx
    docker restart registry
    # 测试HTTPS地址
    curl https://hostname:443/v2/
    

    如果返回{},说明Registry的HTTPS服务正常。

  5. 更新Docker客户端配置
    因为用了自签名证书,需要在Docker客户端的/etc/docker/daemon.json里更新insecure配置:

    {
        "insecure-registries": ["hostname:443"]
    }
    

    然后重启Docker服务:

    systemctl restart docker
    

    现在尝试登录,应该就能成功了:

    docker login hostname:443
    

方案二:直接让Registry启用HTTPS(无需代理)

如果你不想部署Nginx,也可以让Registry本身直接使用HTTPS,但这种方式无法自动重定向HTTP请求,只能强制客户端使用HTTPS:

  1. 准备SSL证书
    同样用OpenSSL生成自签名证书,放在一个Registry能访问的目录,比如/registry/certs

  2. 启动带HTTPS配置的Registry容器
    用下面的命令启动,替换hostname为你的实际主机名,证书路径根据实际情况调整:

    docker run -d -p 443:443 --restart=always --name registry \
      -v /registry/certs:/certs \
      -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
      -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
      -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
      registry:2
    
  3. 配置Docker客户端并登录
    更新/etc/docker/daemon.json的insecure配置:

    {
        "insecure-registries": ["hostname:443"]
    }
    

    重启Docker后,直接用HTTPS地址登录:

    docker login https://hostname:443
    

额外排查Tips

如果还是遇到502错误,可以检查这些点:

  • 确认Registry容器是否正常运行:docker ps,看状态是不是Up
  • 检查Nginx日志(/var/log/nginx/error.log),看是不是无法连接到本地的5000端口。
  • 测试本地能不能访问Registry的HTTP地址:curl http://localhost:5000/v2/,如果返回{}说明Registry本身没问题。

内容的提问来源于stack exchange,提问作者user3906723

火山引擎 最新活动