分享个人 Full-Stack JavaScript 项目开发经验
本文并不打算详细地解释每部分内容背后的基础知识,而是要按步骤介绍如何使用 Docker Stack 在生产环境部署一个单节点的私有 Docker 镜像仓库服务,并使用 Nginx 作为 SSL 连接器部署 Docker Registry UI 作为一个简单的可视化镜像管理服务。
1、在 Docker 主机恰当位置创建密码文件目录:
mkdir auth
2、拉取 registry:2 镜像:
docker pull registry:2
3、重写 registry:2 镜像入口点,并保存认证账号密码到 auth/htpasswd 文件:
docker run --entrypoint htpasswd registry:2 -Bbn <auth-username> <auth-password> > auth/htpasswd
4、切换 Docker 为 Swarm 模式:
docker swarm init
5、添加节点标签,用于节点约束,使其部署为单节点镜像仓库:
docker node ls
docker node update --label-add registry=yes <node-id>
6、创建域名证书 Docker secret:
docker secret create domain.pem <crt-path>
docker secret create domain.key <key-path>
7、准备 Stack 声明文件 docker-stack-registry.yml(具体的域名端口和卷挂载路径等按照自己实际情况编写):
version: "3.5"
networks:
registry_network:
services:
registry-ui:
image: joxit/docker-registry-ui:static
networks:
- registry_network
ports:
- target: 80
published: 5100
mode: host
environment:
REGISTRY_URL: https://www.leeguangxing.cn:5000
PULL_URL: https://www.leeguangxing.cn:5000
REGISTRY_TITLE: leeguangxing.cn
DELETE_IMAGES: 'true'
deploy:
replicas: 1
update_config:
parallelism: 1
failure_action: rollback
placement:
constraints:
- 'node.labels.registry == yes'
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
registry:
image: registry:2
networks:
- registry_network
ports:
- target: 443
published: 5000
mode: host
environment:
REGISTRY_HTTP_ADDR: 0.0.0.0:443
REGISTRY_HTTP_TLS_CERTIFICATE: /run/secrets/domain.pem
REGISTRY_HTTP_TLS_KEY: /run/secrets/domain.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
secrets:
- domain.pem
- domain.key
volumes:
- /var/docker-registry/registry:/var/lib/registry
- /var/docker-registry/auth:/auth
- /var/docker-registry/garbage:/garbage
deploy:
replicas: 1
update_config:
parallelism: 1
failure_action: rollback
placement:
constraints:
- 'node.labels.registry == yes'
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
secrets:
domain.pem:
external: true
domain.key:
external: true
部署 Stack:
docker stack deploy -c docker-stack-registry.yml <stack-name>
8、添加 Docker Registry UI 的 Nginx SSL 配置(具体的证书、端口等配置按照自己实际情况编写)registry_ui.conf:
upstream registry_ui_website {
server 127.0.0.1:5100;
keepalive 32;
}
server {
listen 5200 ssl;
server_name leeguangxing.cn www.leeguangxing.cn;
ssl_certificate /crt/certificate.pem;
ssl_certificate_key /crt/certificate.key;
ssl_session_cache shared:WEB:10m;
ssl_ciphers RC4:HIGH:!aNULL:!MD5:@STRENGTH;
ssl_prefer_server_ciphers on;
access_log off;
location / {
proxy_pass http://registry_ui_website;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Docker Registry UI 介绍展示。
镜像列表:
标签列表:
镜像构建历史:
下面是一个向私有镜像仓库推送镜像及标签的操作例子。
1、使用设定的账号密码登录私有镜像仓库:
docker login leeguangxing.cn:5000
2、为镜像添加新标签:
docker tag nginx leeguangxing.cn:5000/web-demo:latest
3、推送到新的镜像仓库:
docker push leeguangxing.cn:5000/web-demo:latest
目前没有 HTTP API 可以删除整个镜像,当镜像下的所有标签都被删除后,镜像目录仍然存在。若要删除残留的镜像信息,需要手动删除对应镜像文件夹(具体路径取决与你挂载的卷位置)。但要注意,不要直接删除镜像目录,而是通过 HTTP API 删除所有镜像标签后,执行垃圾回收,最后再删除镜像残留目录。
执行镜像垃圾回收(添加 --dry-run 参数,则不删除任何数据,只打印扫描结果):
docker container exec -it <registry-container-id or name> /bin/registry garbage-collect /garbage/config.yml
其中 config.yml 指定镜像在容器中保存的目录:
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/registry
删除镜像目录:
rm -r docker/registry/v2/repositories/<image-name>
可以根据项目需要,对私有镜像仓库进行集群部署,提高可用性。集群节点间共享高速存储,但程序要考虑读写冲突问题。