为了团队的其他同学可以方便的更新开发环境到本地,我们决定搭建私有的 Docker Registry。
不使用公共服务的原因:
- Docker Hub 在国外,同步超级慢。
- DaoCloud 的私有 image 需要收费,对于我们小团队来说不太友好。
搭建步骤
环境准备
- Linux 服务器一台。
- 域名。
- 已经安装上 Docker 和 Nginx。
注意:开发环境和服务器的 Docker 都先升级到最新的版本,否则有可能出现未知的失败。
目录结构
配置 LetsEncrypt 证书
由于私有 Docker Registry 的安全机制,需要使用 Https,原因
配置 LetsEncrypt 证书 使用 certbot
wget https://dl.eff.org/certbot-auto chmod a+x certbot-auto $ ./certbot-auto ./path/to/certbot-auto certonly --standalone -d registry.yourdomain.com
安装的时候必须先关闭 Nginx 服务否则无法生成证书
LetsEncrypt 只支持二级域名,而且有域名个数限制,提前想好私有 Docker Registry 的二级域名
安装 Docker Registry
使用 daocloud 上的 docker registry 公共镜像
docker pull daocloud.io/library/registry:2
将 LetsEncrypt 证书复制到 /certs
cp /etc/letsencrypt/live/yourdomain/fullchain.pem certs/ cp /etc/letsencrypt/live/youdomain/privkey.pem certs/
生成认证文件
docker run --entrypoint htpasswd daocloud.io/library/registry:2.4.1 -Bbn username password > auth/htpasswd
配置 docker-compose.yml
# docker-compose.yml registry: restart: always image: daocloud.io/library/registry:2 ports: - 5000:5000 environment: # Example use Lensencrypt cert REGISTRY_HTTP_TLS_CERTIFICATE: /certs/fullchain.pem REGISTRY_HTTP_TLS_KEY: /certs/privkey.pem REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm volumes: # Replace those three path - /path/registry:/var/lib/registry - /path/certs:/certs - /path/auth:/auth
运行
docker-compose up
测试浏览器访问
https://yourdomain.xxx:5000/v2
测试push
docker login yourdomain.xxx:5000 # 输入之前配置好的用户名密码 docker pull redis docker tag redis yourdomain.xxx:5000/redis docker push yourdomain.xxx:5000/redis
成功的效果
配置 Nginx 做反向代理
配置文件 docker_nginx.conf
# this is necessary for us to be able to disable request buffering in all cases proxy_http_version 1.1; server { listen 443 ssl; server_name registry.youdomain.com; # SSL # Replace with your cert ssl_certificate /path/certs/fullchain.pem; ssl_certificate_key /path/certs/privkey.pem; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; location /v1/ { return 404; } location /v2/ { proxy_pass https://127.0.0.1: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; # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; } } server { listen 80; # Replace with your domain server_name yourdomain; rewrite ^/(.*) https://$server_name/$1 permanent; }
重新加载 Nginx 配置
# 软链接 ln -s /path/docker_nginx.conf /etc/nginx/site-enabled # 测试 nginx -t # 重新加载 nginx -s reload
浏览器测试
https://yourdomain.xxx/v2 # 需要输入之前配置好的用户名和密码
push 测试
docker login yourdomain.xxx # 输入之前配置好的用户名密码 docker pull redis docker tag redis yourdomain.xxx/redis docker push yourdomain.xxx/redis
后续工作
由于 LetsEncrypt 证书 3 个月会自动过期,需要使用脚本做自动更新,配合 crontab 两个月更新一次
renew_cert.sh
#!/bin/bash # renew cert /letsencrypt/certbot-auto renew --pre-hook "service nginx stop" --post-hook "service nginx start" # backup cert cp /yourpath/docker-registry/certs/fullchain.pem /yourpath/docker-registry/certs/fullchain.pem.bak cp /yourpath/docker-registry/certs/privkey.pem /yourpath/docker-registry/certs/privkey.pem.bak # change cert cp /etc/letsencrypt/live/yourdomain/fullchain.pem /yourpath/docker-registry/certs/fullchain.pem cp /etc/letsencrypt/live/yourdomain/privkey.pem /yourpath/docker-registry/certs/privkey.pem
运行
sh renew_cert.sh
感谢
https://www.daocloud.io 提供国内的公共镜像服务