From 7c7669edb0ad02aa1a4449c782604de3c7efa8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:23:54 +0800 Subject: [PATCH 01/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 40 ++++++++++++++++++++++++++++++++++ images.txt | 2 ++ 2 files changed, 42 insertions(+) create mode 100644 .github/workflows/tencent.yaml diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml new file mode 100644 index 0000000000..9f4292a892 --- /dev/null +++ b/.github/workflows/tencent.yaml @@ -0,0 +1,40 @@ +name: tencent_docker +on: + workflow_dispatch: + push: + branches: [main] + +env: + TENCENT_REGISTRY: "${{ secrets.TENCENT_REGISTRY }}" + TENCENT_NAME_SPACE: "${{ secrets.TENCENT_NAME_SPACE }}" + TENCENT_REGISTRY_USER: "${{ secrets.TENCENT_REGISTRY_USER }}" + TENCENT_REGISTRY_PASSWORD: "${{ secrets.TENCENT_REGISTRY_PASSWORD }}" + +jobs: + build: + name: Pull + runs-on: ubuntu-latest + steps: + - name: Setup Docker buildx + uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + + - name: Check out code + uses: actions/checkout@v2 + + - name: Build and push image TENCENT + run: | + sudo docker login ccr.ccs.tencentyun.com -u $TENCENT_REGISTRY_USER -p $secrets.TENCENT_REGISTRY_PASSWORD + while IFS= read -r line; do + [[ -z "$line" ]] && continue + echo "docker pull $line" + docker pull $line + # 获取镜像的完整名称,例如kasmweb/nginx:1.25.3(命名空间/镜像名:版本号) + image=$(echo "$line" | awk '{print $NF}') + # 获取 镜像名:版本号 例如nginx:1.25.3 + image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') + new_image="$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" + echo "docker tag $image $new_image" + docker tag $image $new_image + echo "docker push $new_image" + docker push $new_image + done < images.txt diff --git a/images.txt b/images.txt index 9d47a4fdb5..57482ef5d5 100644 --- a/images.txt +++ b/images.txt @@ -1,5 +1,7 @@ alpine python:alpine3.19 kasmweb/nginx:1.25.3 +mysql:5.7 +redis --platform linux/arm64 cooderl/wewe-rss-sqlite:latest From 283ec16edecbeb58fb57d8af0085ff71b0f46e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:29:37 +0800 Subject: [PATCH 02/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yaml | 2 +- .github/workflows/tencent.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index e68af8e51f..f317d00acf 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -3,7 +3,7 @@ name: Docker on: workflow_dispatch: push: - branches: [ main ] + branches: [ master ] env: diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 9f4292a892..be8de8ae47 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -23,7 +23,7 @@ jobs: - name: Build and push image TENCENT run: | - sudo docker login ccr.ccs.tencentyun.com -u $TENCENT_REGISTRY_USER -p $secrets.TENCENT_REGISTRY_PASSWORD + docker login https://ccr.ccs.tencentyun.com -u $TENCENT_REGISTRY_USER -p $TENCENT_REGISTRY_PASSWORD while IFS= read -r line; do [[ -z "$line" ]] && continue echo "docker pull $line" From efcfaa5532d35cf77355c38472228f5186c5b3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:41:38 +0800 Subject: [PATCH 03/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index be8de8ae47..4cd16c0d88 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -28,6 +28,8 @@ jobs: [[ -z "$line" ]] && continue echo "docker pull $line" docker pull $line + echo "test_TENCENT_NAME_SPACE: $TENCENT_NAME_SPACE" + echo "test_TENCENT_REGISTRY: $TENCENT_REGISTRY" # 获取镜像的完整名称,例如kasmweb/nginx:1.25.3(命名空间/镜像名:版本号) image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 From 7e770991c9586868a5bba9a6ddd5fa5e4602e174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:45:19 +0800 Subject: [PATCH 04/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 4cd16c0d88..4cdc629c05 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -28,13 +28,11 @@ jobs: [[ -z "$line" ]] && continue echo "docker pull $line" docker pull $line - echo "test_TENCENT_NAME_SPACE: $TENCENT_NAME_SPACE" - echo "test_TENCENT_REGISTRY: $TENCENT_REGISTRY" # 获取镜像的完整名称,例如kasmweb/nginx:1.25.3(命名空间/镜像名:版本号) image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') - new_image="$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" + new_image="https://ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" echo "docker tag $image $new_image" docker tag $image $new_image echo "docker push $new_image" From e2db3fc6d82d8ee8e3d551a4198307128ba13aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:46:53 +0800 Subject: [PATCH 05/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 4cdc629c05..0a716aa497 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -32,7 +32,7 @@ jobs: image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') - new_image="https://ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" + new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" echo "docker tag $image $new_image" docker tag $image $new_image echo "docker push $new_image" From 45fd7f22db2c4065586a2ccdc9702f0e108d23b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:49:07 +0800 Subject: [PATCH 06/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/images.txt b/images.txt index 57482ef5d5..0ffb1fe700 100644 --- a/images.txt +++ b/images.txt @@ -1,7 +1,4 @@ -alpine python:alpine3.19 -kasmweb/nginx:1.25.3 mysql:5.7 redis ---platform linux/arm64 cooderl/wewe-rss-sqlite:latest From aec71dbdc531584b1cfcbd78bb8eaac9f5ba56d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:50:28 +0800 Subject: [PATCH 07/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 0a716aa497..71d6a19126 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -4,6 +4,9 @@ on: push: branches: [main] +permissions: + contents: write + env: TENCENT_REGISTRY: "${{ secrets.TENCENT_REGISTRY }}" TENCENT_NAME_SPACE: "${{ secrets.TENCENT_NAME_SPACE }}" From dae243f3d57d4b91dd5b027da02ca6f8dba87d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 17:59:01 +0800 Subject: [PATCH 08/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 71d6a19126..030dd53830 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -35,7 +35,7 @@ jobs: image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') - new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" + new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY:$image_name_tag" echo "docker tag $image $new_image" docker tag $image $new_image echo "docker push $new_image" From 8868dfcf5697b6be144b8ce44427ff4bfaa71700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 18:01:27 +0800 Subject: [PATCH 09/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 030dd53830..71d6a19126 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -35,7 +35,7 @@ jobs: image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') - new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY:$image_name_tag" + new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" echo "docker tag $image $new_image" docker tag $image $new_image echo "docker push $new_image" From f77b3584304fe6dab8895f61b7ba6e3c6152f60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 11 Jun 2024 18:03:03 +0800 Subject: [PATCH 10/37] =?UTF-8?q?Feat(=E5=88=9B=E5=BB=BA=E9=95=9C=E5=83=8F?= =?UTF-8?q?):=E6=B7=BB=E5=8A=A0=E8=85=BE=E8=AE=AF=E4=BA=91=E9=95=9C?= =?UTF-8?q?=E5=83=8F=E6=9C=8D=E5=8A=A14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 71d6a19126..ed5c7f5555 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -35,7 +35,7 @@ jobs: image=$(echo "$line" | awk '{print $NF}') # 获取 镜像名:版本号 例如nginx:1.25.3 image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}') - new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$TENCENT_REGISTRY/$image_name_tag" + new_image="ccr.ccs.tencentyun.com/$TENCENT_NAME_SPACE/$image_name_tag" echo "docker tag $image $new_image" docker tag $image $new_image echo "docker push $new_image" From 4425e96b5823c7f87f9ed402cd1a90d56743fcff Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 12 Jun 2024 02:39:20 +0800 Subject: [PATCH 11/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images.txt | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/images.txt b/images.txt index 0ffb1fe700..1d2f6b65f7 100644 --- a/images.txt +++ b/images.txt @@ -1,4 +1,45 @@ -python:alpine3.19 -mysql:5.7 -redis +bitnami/kafka +jnovack/autossh +registry.k8s.io/pause:3.9 +registry.k8s.io/coredns/coredns:v1.11.1 +registry.k8s.io/etcd:3.5.10-0 +registry.k8s.io/kube-proxy:v1.29.2 +registry.k8s.io/kube-scheduler:v1.29.2 +registry.k8s.io/kube-controller-manager:v1.29.2 +registry.k8s.io/kube-apiserver:v1.29.2 +docker/desktop-kubernetes:kubernetes-v1.29.2-cni-v1.4.0-critools-v1.29.0-cri-dockerd-v0.3.11-1-debian +nginx +gcr.io/k8s-minikube/kicbase:v0.0.44 +alpine +busybox +httpd +mongo +ubuntu +node +postgres +memcached +golang +centos +php +mariadb +rabbitmq +elasticsearch +ruby +debian +tomcat:8 +tomcat +jenkins +kibana +neo4j +fedora +sentry +solr +rethinkdb +zookeeper +redmine +tomee +ubuntu-debootstra +ros +rust +scratch From 39de6f3d8ca72c9acb36691953198e1259e41997 Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 12 Jun 2024 02:58:10 +0800 Subject: [PATCH 12/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=95=9C=E5=83=8F1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images.txt | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/images.txt b/images.txt index 1d2f6b65f7..b415753ff2 100644 --- a/images.txt +++ b/images.txt @@ -1,29 +1,10 @@ -bitnami/kafka -jnovack/autossh -registry.k8s.io/pause:3.9 -registry.k8s.io/coredns/coredns:v1.11.1 -registry.k8s.io/etcd:3.5.10-0 -registry.k8s.io/kube-proxy:v1.29.2 -registry.k8s.io/kube-scheduler:v1.29.2 -registry.k8s.io/kube-controller-manager:v1.29.2 -registry.k8s.io/kube-apiserver:v1.29.2 -docker/desktop-kubernetes:kubernetes-v1.29.2-cni-v1.4.0-critools-v1.29.0-cri-dockerd-v0.3.11-1-debian -nginx -gcr.io/k8s-minikube/kicbase:v0.0.44 -alpine -busybox -httpd -mongo -ubuntu -node -postgres -memcached -golang -centos -php -mariadb -rabbitmq -elasticsearch +elasticsearch:7.17.21 +elasticsearch:8 +pytorch/pytorch +tensorflow/tensorflow +graylog/graylog:5.2 +graylog/graylog:6.0.0-1 +phpmyadmin/phpmyadmin ruby debian tomcat:8 @@ -41,5 +22,4 @@ tomee ubuntu-debootstra ros rust -scratch - +scratch \ No newline at end of file From 5b7d5dcd1dfb9375abc30086171a44811139d4fb Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 12 Jun 2024 03:02:02 +0800 Subject: [PATCH 13/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=95=9C=E5=83=8F1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/images.txt b/images.txt index b415753ff2..b2999c921d 100644 --- a/images.txt +++ b/images.txt @@ -1,5 +1,5 @@ elasticsearch:7.17.21 -elasticsearch:8 +elasticsearch:8.14.0 pytorch/pytorch tensorflow/tensorflow graylog/graylog:5.2 @@ -22,4 +22,5 @@ tomee ubuntu-debootstra ros rust -scratch \ No newline at end of file +scratch +eipwork/kuboard From 05ee26e5844e4579097da78d29cd3d43a87aa7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Wed, 12 Jun 2024 13:03:37 +0800 Subject: [PATCH 14/37] =?UTF-8?q?Feat(=E6=B7=BB=E5=8A=A0=E9=95=9C=E5=83=8F?= =?UTF-8?q?):?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tencent.yaml | 1 - images.txt | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index ed5c7f5555..18a3090d28 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -8,7 +8,6 @@ permissions: contents: write env: - TENCENT_REGISTRY: "${{ secrets.TENCENT_REGISTRY }}" TENCENT_NAME_SPACE: "${{ secrets.TENCENT_NAME_SPACE }}" TENCENT_REGISTRY_USER: "${{ secrets.TENCENT_REGISTRY_USER }}" TENCENT_REGISTRY_PASSWORD: "${{ secrets.TENCENT_REGISTRY_PASSWORD }}" diff --git a/images.txt b/images.txt index b2999c921d..3d530b9c1d 100644 --- a/images.txt +++ b/images.txt @@ -9,7 +9,7 @@ ruby debian tomcat:8 tomcat -jenkins +jenkins/jenkins:2.346.1-lts kibana neo4j fedora @@ -24,3 +24,5 @@ ros rust scratch eipwork/kuboard +gitlab/gitlab-ce:latest +gitlab/gitlab-runner:latest \ No newline at end of file From 28bfeadfa33dede42c2e400898dc97b550484311 Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 12 Jun 2024 22:33:52 +0800 Subject: [PATCH 15/37] add 1 --- back_images.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ images.txt | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 back_images.txt diff --git a/back_images.txt b/back_images.txt new file mode 100644 index 0000000000..7dd3c12bac --- /dev/null +++ b/back_images.txt @@ -0,0 +1,48 @@ +bitnami/kafka +jnovack/autossh +registry.k8s.io/pause:3.9 +registry.k8s.io/coredns/coredns:v1.11.1 +registry.k8s.io/etcd:3.5.10-0 +registry.k8s.io/kube-proxy:v1.29.2 +registry.k8s.io/kube-scheduler:v1.29.2 +registry.k8s.io/kube-controller-manager:v1.29.2 +registry.k8s.io/kube-apiserver:v1.29.2 +docker/desktop-kubernetes:kubernetes-v1.29.2-cni-v1.4.0-critools-v1.29.0-cri-dockerd-v0.3.11-1-debian +nginx +gcr.io/k8s-minikube/kicbase:v0.0.44 +alpine +busybox +httpd +mongo +ubuntu +node +postgres +memcached +golang +centos +php +mariadb +rabbitmq +elasticsearch +ruby +debian +tomcat:8 +tomcat +jenkins +kibana +neo4j +fedora +sentry +solr +rethinkdb +zookeeper +redmine +tomee +ubuntu-debootstra +ros +rust +scratch +python:alpine3.19 +mysql:5.7 +mysql:8 +redis diff --git a/images.txt b/images.txt index 3d530b9c1d..1a57624b70 100644 --- a/images.txt +++ b/images.txt @@ -10,7 +10,7 @@ debian tomcat:8 tomcat jenkins/jenkins:2.346.1-lts -kibana +kibana:8.2.0 neo4j fedora sentry From 74274356ca1cdabfdcd75443514709f44d55e2cd Mon Sep 17 00:00:00 2001 From: subahua Date: Sat, 15 Jun 2024 01:54:27 +0800 Subject: [PATCH 16/37] add2 --- back_images.txt | 9 +++++++++ images.txt | 21 --------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/back_images.txt b/back_images.txt index 7dd3c12bac..c912de3082 100644 --- a/back_images.txt +++ b/back_images.txt @@ -46,3 +46,12 @@ python:alpine3.19 mysql:5.7 mysql:8 redis +kibana:8.2.0 +neo4j +fedora +sentry +solr +rethinkdb +zookeeper +redmine +tomee \ No newline at end of file diff --git a/images.txt b/images.txt index 1a57624b70..14cae80d9b 100644 --- a/images.txt +++ b/images.txt @@ -1,24 +1,3 @@ -elasticsearch:7.17.21 -elasticsearch:8.14.0 -pytorch/pytorch -tensorflow/tensorflow -graylog/graylog:5.2 -graylog/graylog:6.0.0-1 -phpmyadmin/phpmyadmin -ruby -debian -tomcat:8 -tomcat -jenkins/jenkins:2.346.1-lts -kibana:8.2.0 -neo4j -fedora -sentry -solr -rethinkdb -zookeeper -redmine -tomee ubuntu-debootstra ros rust From 1d786343b67cd0771e56572020738a97edf3fd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 12:03:32 +0800 Subject: [PATCH 17/37] add certbot/certbot --- images.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/images.txt b/images.txt index 14cae80d9b..d2ab9c2f25 100644 --- a/images.txt +++ b/images.txt @@ -4,4 +4,5 @@ rust scratch eipwork/kuboard gitlab/gitlab-ce:latest -gitlab/gitlab-runner:latest \ No newline at end of file +gitlab/gitlab-runner:latest +certbot/certbot \ No newline at end of file From d6f584163ad4086979994cb6f538e23545952be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 12:13:55 +0800 Subject: [PATCH 18/37] add certbot/certbot --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index 18a3090d28..e1926c9ac1 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -25,7 +25,7 @@ jobs: - name: Build and push image TENCENT run: | - docker login https://ccr.ccs.tencentyun.com -u $TENCENT_REGISTRY_USER -p $TENCENT_REGISTRY_PASSWORD + docker login https://ccr.ccs.tencentyun.com --username=$TENCENT_REGISTRY_USER -p $TENCENT_REGISTRY_PASSWORD while IFS= read -r line; do [[ -z "$line" ]] && continue echo "docker pull $line" From b8878be025446d93582674eb11a7dc2a5a026143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 12:16:38 +0800 Subject: [PATCH 19/37] fix certbot/certbot --- .github/workflows/tencent.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tencent.yaml b/.github/workflows/tencent.yaml index e1926c9ac1..73f0828a39 100644 --- a/.github/workflows/tencent.yaml +++ b/.github/workflows/tencent.yaml @@ -25,7 +25,7 @@ jobs: - name: Build and push image TENCENT run: | - docker login https://ccr.ccs.tencentyun.com --username=$TENCENT_REGISTRY_USER -p $TENCENT_REGISTRY_PASSWORD + docker login https://ccr.ccs.tencentyun.com --username=$TENCENT_REGISTRY_USER --password $TENCENT_REGISTRY_PASSWORD while IFS= read -r line; do [[ -z "$line" ]] && continue echo "docker pull $line" From 8935cbf9a3f7cdeb758160646c189e7836672627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 12:20:00 +0800 Subject: [PATCH 20/37] fix certbot/certbot --- images.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/images.txt b/images.txt index d2ab9c2f25..fb28be2274 100644 --- a/images.txt +++ b/images.txt @@ -1,4 +1,3 @@ -ubuntu-debootstra ros rust scratch From fbafab0937a4db647e2bbf79e856b02dc421e5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 14:35:41 +0800 Subject: [PATCH 21/37] fix certbot/certbot --- images.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/images.txt b/images.txt index fb28be2274..d1df12be65 100644 --- a/images.txt +++ b/images.txt @@ -1,6 +1,5 @@ ros rust -scratch eipwork/kuboard gitlab/gitlab-ce:latest gitlab/gitlab-runner:latest From 5161f8b6d37e1d6c53e4775b3345935fe419ba67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 14:36:30 +0800 Subject: [PATCH 22/37] fix certbot/certbot --- images.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/images.txt b/images.txt index d1df12be65..09c04b6cdc 100644 --- a/images.txt +++ b/images.txt @@ -1,5 +1,3 @@ -ros -rust eipwork/kuboard gitlab/gitlab-ce:latest gitlab/gitlab-runner:latest From 1b4fdf6ca6d2213a38b7fb9d51a878f57b9d6d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Tue, 30 Jul 2024 14:37:57 +0800 Subject: [PATCH 23/37] fix certbot/certbot --- back_images.txt | 3 ++- images.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/back_images.txt b/back_images.txt index c912de3082..986b88b486 100644 --- a/back_images.txt +++ b/back_images.txt @@ -54,4 +54,5 @@ solr rethinkdb zookeeper redmine -tomee \ No newline at end of file +tomee +certbot/certbot \ No newline at end of file diff --git a/images.txt b/images.txt index 09c04b6cdc..beeb15901d 100644 --- a/images.txt +++ b/images.txt @@ -1,3 +1,4 @@ + eipwork/kuboard gitlab/gitlab-ce:latest gitlab/gitlab-runner:latest From 67687de5138eb2f78e809e6b92001ea0f5b71749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Wed, 31 Jul 2024 10:52:41 +0800 Subject: [PATCH 24/37] Add(certd) --- back_images.txt | 5 +++++ images.txt | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/back_images.txt b/back_images.txt index 986b88b486..467a7d4d55 100644 --- a/back_images.txt +++ b/back_images.txt @@ -55,4 +55,9 @@ rethinkdb zookeeper redmine tomee +certbot/certbot + +eipwork/kuboard +gitlab/gitlab-ce:latest +gitlab/gitlab-runner:latest certbot/certbot \ No newline at end of file diff --git a/images.txt b/images.txt index beeb15901d..7f7083bcdf 100644 --- a/images.txt +++ b/images.txt @@ -1,5 +1,2 @@ - -eipwork/kuboard -gitlab/gitlab-ce:latest -gitlab/gitlab-runner:latest -certbot/certbot \ No newline at end of file +certd +memcache:1.5.8 From 1074c753f63b86594636d26aa9d5d6608db26f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Wed, 31 Jul 2024 10:57:19 +0800 Subject: [PATCH 25/37] Add(certd) --- images.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images.txt b/images.txt index 7f7083bcdf..cd91bb7fa7 100644 --- a/images.txt +++ b/images.txt @@ -1,2 +1,2 @@ -certd +registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest memcache:1.5.8 From ca27631b5d3e85b13588d8623b9da4167d8012c5 Mon Sep 17 00:00:00 2001 From: subahua Date: Tue, 20 Aug 2024 01:40:59 +0800 Subject: [PATCH 26/37] add2 --- back_images.txt | 10 ++++++++-- images.txt | 16 ++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/back_images.txt b/back_images.txt index c912de3082..1a2fe6c978 100644 --- a/back_images.txt +++ b/back_images.txt @@ -9,7 +9,7 @@ registry.k8s.io/kube-controller-manager:v1.29.2 registry.k8s.io/kube-apiserver:v1.29.2 docker/desktop-kubernetes:kubernetes-v1.29.2-cni-v1.4.0-critools-v1.29.0-cri-dockerd-v0.3.11-1-debian nginx -gcr.io/k8s-minikube/kicbase:v0.0.44 +gcr.io/k8s-minikube/kicbase:v0.0.44 alpine busybox httpd @@ -54,4 +54,10 @@ solr rethinkdb zookeeper redmine -tomee \ No newline at end of file +tomee +ros +rust +eipwork/kuboard +gitlab/gitlab-ce:latest +gitlab/gitlab-runner:latest +certbot/certbot diff --git a/images.txt b/images.txt index d1df12be65..1a463fbbaf 100644 --- a/images.txt +++ b/images.txt @@ -1,6 +1,10 @@ -ros -rust -eipwork/kuboard -gitlab/gitlab-ce:latest -gitlab/gitlab-runner:latest -certbot/certbot \ No newline at end of file +grafana/grafana:main-ubuntu +grafana/grafana:main +grafana/grafana:latest-ubuntu +grafana/grafana:latest +grafana/grafana:11.1.4-ubuntu +grafana/grafana:11.1.1-ubuntu +grafana/grafana:11.1.4 +grafana/grafana:11.0.3 +grafana/grafana:10.4.7-ubuntu +grafana/grafana:9.5.17 From 3cdb8d47e0d3fe5c57ca59241f3757ffb888721b Mon Sep 17 00:00:00 2001 From: subahua Date: Thu, 22 Aug 2024 01:32:59 +0800 Subject: [PATCH 27/37] add2 --- images.txt | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/images.txt b/images.txt index 1a463fbbaf..cf280f3bb6 100644 --- a/images.txt +++ b/images.txt @@ -1,10 +1,21 @@ -grafana/grafana:main-ubuntu -grafana/grafana:main -grafana/grafana:latest-ubuntu -grafana/grafana:latest -grafana/grafana:11.1.4-ubuntu -grafana/grafana:11.1.1-ubuntu -grafana/grafana:11.1.4 -grafana/grafana:11.0.3 -grafana/grafana:10.4.7-ubuntu -grafana/grafana:9.5.17 +golang:1.23.0 +golang:1.22.6 +golang:1.21.13 +golang:1 +node:22.6 +node:lts +node:20 +node:18.20 +memcached:1.6.29 +memcached:1.6.28 +memcached:1 +redis:7.4.0 +redis:7.2.5 +redis:7.2.4 +redis:7.0 +redis:6.2.14 +redis:6.0 +bitnami/kafka:3.5 +bitnami/kafka:3.8 +bitnami/kafka:3.2 + From ce9e15bd0c6680ca19b7478214f137b4246029c7 Mon Sep 17 00:00:00 2001 From: subahua <38020412+subahua@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:49:42 +0800 Subject: [PATCH 28/37] Update images.txt --- images.txt | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/images.txt b/images.txt index cf280f3bb6..f87601209b 100644 --- a/images.txt +++ b/images.txt @@ -1,21 +1 @@ -golang:1.23.0 -golang:1.22.6 -golang:1.21.13 -golang:1 -node:22.6 -node:lts -node:20 -node:18.20 -memcached:1.6.29 -memcached:1.6.28 -memcached:1 -redis:7.4.0 -redis:7.2.5 -redis:7.2.4 -redis:7.0 -redis:6.2.14 -redis:6.0 -bitnami/kafka:3.5 -bitnami/kafka:3.8 -bitnami/kafka:3.2 - +python:3.7-stretch From 030283870f746f325791b605ccf870481a758eab Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 28 Aug 2024 00:00:02 +0800 Subject: [PATCH 29/37] add2 --- images.txt | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/images.txt b/images.txt index cf280f3bb6..ffcb163234 100644 --- a/images.txt +++ b/images.txt @@ -1,21 +1,3 @@ -golang:1.23.0 -golang:1.22.6 -golang:1.21.13 -golang:1 -node:22.6 -node:lts -node:20 -node:18.20 -memcached:1.6.29 -memcached:1.6.28 -memcached:1 -redis:7.4.0 -redis:7.2.5 -redis:7.2.4 -redis:7.0 -redis:6.2.14 -redis:6.0 -bitnami/kafka:3.5 -bitnami/kafka:3.8 -bitnami/kafka:3.2 - +rapidfort/etcd:3.5 +rapidfort/etcd:3.5.12 +rapidfort/etcd:3.5.9 From afd6c4597ccadc861ab4599f18ef65908b1c910b Mon Sep 17 00:00:00 2001 From: subahua <38020412+subahua@users.noreply.github.com> Date: Wed, 28 Aug 2024 00:00:44 +0800 Subject: [PATCH 30/37] Update images.txt --- images.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/images.txt b/images.txt index f87601209b..ffcb163234 100644 --- a/images.txt +++ b/images.txt @@ -1 +1,3 @@ -python:3.7-stretch +rapidfort/etcd:3.5 +rapidfort/etcd:3.5.12 +rapidfort/etcd:3.5.9 From 1fea74acc755c5ae6af3105d208f20eb7cb0629b Mon Sep 17 00:00:00 2001 From: subahua <38020412+subahua@users.noreply.github.com> Date: Wed, 28 Aug 2024 01:07:47 +0800 Subject: [PATCH 31/37] Update images.txt --- images.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/images.txt b/images.txt index ffcb163234..a6da2f1f3d 100644 --- a/images.txt +++ b/images.txt @@ -1,3 +1 @@ -rapidfort/etcd:3.5 -rapidfort/etcd:3.5.12 -rapidfort/etcd:3.5.9 +registry.k8s.io/e2e-test-images/agnhost:2.39 From cdeac27d3e52711b3d728f1511947a3406b30612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Mon, 23 Sep 2024 13:10:00 +0800 Subject: [PATCH 32/37] save --- images.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/images.txt b/images.txt index cd91bb7fa7..a1f70c435a 100644 --- a/images.txt +++ b/images.txt @@ -1,2 +1,5 @@ -registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest -memcache:1.5.8 +grafana/grafana:11.2.0 +prom/prometheus:v2.54.1 +prom/node-exporter:v1.8.2 +nginx/nginx-ingress:3.6.2 +nginx/nginx-prometheus-exporter:1.3 From 715b8e9b0dd74417af226b2230c79c87f218c537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= Date: Thu, 19 Dec 2024 17:14:24 +0800 Subject: [PATCH 33/37] jupyter --- .vscode/settings.json | 7 +++++++ back_images.txt | 8 +++++--- images.txt | 6 +----- 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..df548f984a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "workbench.colorCustomizations": { + "activityBar.background": "#1F3316", + "titleBar.activeBackground": "#2C471F", + "titleBar.activeForeground": "#F8FBF7" + } +} \ No newline at end of file diff --git a/back_images.txt b/back_images.txt index a12c707a77..1276452d5d 100644 --- a/back_images.txt +++ b/back_images.txt @@ -55,18 +55,20 @@ rethinkdb zookeeper redmine tomee -<<<<<<< HEAD certbot/certbot eipwork/kuboard gitlab/gitlab-ce:latest gitlab/gitlab-runner:latest certbot/certbot -======= ros rust eipwork/kuboard gitlab/gitlab-ce:latest gitlab/gitlab-runner:latest certbot/certbot ->>>>>>> 1fea74acc755c5ae6af3105d208f20eb7cb0629b +grafana/grafana:11.2.0 +prom/prometheus:v2.54.1 +prom/node-exporter:v1.8.2 +nginx/nginx-ingress:3.6.2 +nginx/nginx-prometheus-exporter:1.3 diff --git a/images.txt b/images.txt index a1f70c435a..6d17575d38 100644 --- a/images.txt +++ b/images.txt @@ -1,5 +1 @@ -grafana/grafana:11.2.0 -prom/prometheus:v2.54.1 -prom/node-exporter:v1.8.2 -nginx/nginx-ingress:3.6.2 -nginx/nginx-prometheus-exporter:1.3 +jupyter/base-notebook:x86_64-ubuntu-22.04 \ No newline at end of file From b77279c97e0b0f60ba854ca714a8a70f4be29159 Mon Sep 17 00:00:00 2001 From: subahua Date: Wed, 12 Mar 2025 23:29:32 +0800 Subject: [PATCH 34/37] add test --- main.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000000..2e483ad631 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +from aiohttp import ClientSession +import asyncio +image_urls = [ + "https://hub.docker.com/_/nginx/tags" +] + + + +async def get_tags_data(image_url): + async with ClientSession() as session: # 使用 ClientSession 来发送请求 + async with session.get(image_url) as response: # 发起 GET 请求 + html = await response.text() # 获取响应的 HTML 内容 + print(html) # 打印 HTML 内容 + + +async def main(): + await asyncio.gather(get_tags_data(image_urls[0])) + + +if __name__ == "__main__": + asyncio.run(main()) From 2d3b813295d4d363249c8301eb2e45bd4878517d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:59:04 +0000 Subject: [PATCH 35/37] feat: Enhanced main.py to implement image backup and recording functionality Key updates include: 1. **Image Information Retrieval:** * `get_tags_data`: Asynchronously retrieves the latest n tags for a specified image from the Docker Hub API (`/v2/repositories/.../tags/`). * `parse_dockerhub_url`: Parses Docker Hub page URLs to extract namespace and repository names. 2. **Docker Operation Encapsulation:** * `pull_image`: Executes `docker pull`. * `tag_image`: Executes `docker tag` to mark the image for the target private repository. * `docker_login`: Executes `docker login`, using credentials obtained from environment variables to log in to the target repository. * `push_image`: Executes `docker push`. 3. **Backup Recording:** * `is_image_backed_up`: Checks if the image is already in the record file. * `record_backup`: Writes the successfully backed-up image version to the record file. 4. **Main Logic (`main` function):** * Loads the target repository URL, namespace, and authentication credentials via environment variables. * Configures the number of tags to retrieve, the record file path, and the list of image URLs to process via command-line arguments. * Coordinates the entire flow: login -> get tags -> (check record -> pull -> tag -> push -> update record). * Uses `aiohttp` for asynchronous API requests. 5. **Logging and Error Handling:** * Comprehensive use of the `logging` module instead of `print` to provide structured log output. * Error capturing and handling for Docker command execution, API requests, and file operations. 6. **Documentation:** * Updated `README.md` with detailed instructions on script configuration (environment variables, command-line arguments), dependency installation, and execution methods. This script can now automatically pull multiple versions of specified images from Docker Hub based on your configuration, push them to a configured private repository (such as Tencent Cloud or Alibaba Cloud), and locally record backed-up images to avoid redundant operations. --- README.md | 101 ++++++++++++++++++++ main.py | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 373 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 400d316a96..9afe753fb2 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,104 @@ docker pull registry.cn-hangzhou.aliyuncs.com/shrimp-images/alpine registry.cn-hangzhou.aliyuncs.com 即 ALIYUN_REGISTRY
shrimp-images 即 ALIYUN_NAME_SPACE
alpine 即images.txt里面填的镜像
+ +## Command-Line Script: `main.py` + +This script provides a command-line interface to back up Docker images from Docker Hub to a specified private registry. It fetches image tags, pulls the images, re-tags them for the target registry, pushes them, and keeps a record of backed-up images to avoid redundant operations. + +### Prerequisites + +* Python 3.7+ (due to `asyncio` and `aiohttp`). +* Docker installed and running on the machine where the script is executed. +* Network access to Docker Hub (for fetching public images). +* Credentials and access to a target private Docker registry (e.g., Tencent Cloud CCR, Alibaba Cloud ACR, Docker Hub private repos, etc.). + +### Dependencies + +The script requires the following Python package: +* `aiohttp` + +You can install it using pip: +```bash +pip install aiohttp +``` + +### Configuration + +Configuration is managed via environment variables for credentials and target registry details, and command-line arguments for operational parameters. + +#### Environment Variables (Mandatory) + +These environment variables **must** be set before running the script. The script will exit if any of them are missing. + +* `TARGET_REGISTRY_URL`: The URL of your target private registry. + * Example: `ccr.ccs.tencentyun.com` or `registry.aliyuncs.com` or `docker.io` (for Docker Hub). +* `TARGET_NAMESPACE`: The namespace within your target private registry where images will be stored. + * Example: `my-docker-backups` or `myusername` (if using Docker Hub as the target). +* `DOCKER_USERNAME`: Your username for authenticating with the `TARGET_REGISTRY_URL`. +* `DOCKER_PASSWORD`: Your password for authenticating with the `TARGET_REGISTRY_URL`. + +#### Command-line Arguments + +These arguments are optional and provide control over the script's execution: + +* `--num-tags` (`-n`): The number of latest tags to fetch and process for each image. + * Default: `5` +* `--record-file` (`-r`): Path to the file used for recording backed-up images to prevent re-processing. + * Default: `backed_up_images.txt` +* `--image-urls` (`-u`): A comma-separated string of Docker Hub image URLs to process. This allows you to specify which images to back up. + * Example: `"https://hub.docker.com/_/nginx/tags,https://hub.docker.com/r/prom/prometheus/tags"` + * If not provided, the script uses a default list of image URLs hardcoded in `main.py`. + +### Running the Script + +1. **Set Environment Variables:** + ```bash + export TARGET_REGISTRY_URL="your-registry.example.com" + export TARGET_NAMESPACE="your-namespace" + export DOCKER_USERNAME="your-registry-username" + export DOCKER_PASSWORD="your-registry-password" + ``` + +2. **Execute `main.py`:** + ```bash + python main.py [OPTIONS] + ``` + For example, to back up the 3 latest tags for `alpine` and `redis`: + ```bash + python main.py -n 3 -u "https://hub.docker.com/_/alpine/tags,https://hub.docker.com/_/redis/tags" + ``` + To use the default image list and fetch 5 tags per image: + ```bash + python main.py + ``` + + The script will log its progress to the standard output, including information about fetching tags, pulling, tagging, pushing images, and any errors encountered. + +### How it Works + +The script performs the following steps: + +1. **Configuration Loading:** Reads environment variables and parses command-line arguments. +2. **Docker Login:** Logs into the target Docker registry using the provided credentials. Exits if login fails. +3. **Image Processing Loop:** For each source image URL specified: + a. **Fetch Tags:** Retrieves the specified number of latest tags from Docker Hub using its API. + b. **Tag Processing Loop:** For each fetched tag: + i. **Check Backup Record:** Consults the record file (e.g., `backed_up_images.txt`) to see if the specific image and tag combination has already been backed up. If yes, skips to the next tag. + ii. **Pull:** If not backed up, pulls the image from Docker Hub (e.g., `nginx:latest`). + iii. **Tag:** Re-tags the pulled image for the target private registry (e.g., `your-registry.example.com/your-namespace/nginx:latest`). + iv. **Push:** Pushes the newly tagged image to the target private registry. + v. **Record Backup:** If all previous steps (pull, tag, push) are successful, adds an entry for the image and tag to the record file. + +### Record File + +* The record file (default: `backed_up_images.txt`) stores a list of image and tag combinations that have been successfully backed up. +* Each line in the file has the format: `image_name_on_hub:tag` + * Example: `nginx:1.25` or `prom/prometheus:v2.40.0` +* This file ensures that the script does not re-process images and tags that have already been backed up, saving time and resources. + +### Error Handling + +* The script logs all operations, including errors, to the console using Python's `logging` module. +* It will exit immediately if critical configuration (environment variables) is missing or if the initial login to the target Docker registry fails. +* For errors encountered during the processing of a specific image or tag (e.g., pull failure, push failure), the script will log the error and attempt to continue with the next tag or image URL. diff --git a/main.py b/main.py index 2e483ad631..e79195499b 100644 --- a/main.py +++ b/main.py @@ -1,21 +1,285 @@ -from aiohttp import ClientSession import asyncio +from aiohttp import ClientSession +import json # 用于解析 JSON +from urllib.parse import urlparse # 用于解析 URL +import subprocess +import os +import argparse +import sys +import logging + +# Global list of image URLs, can be overridden by command-line argument image_urls = [ - "https://hub.docker.com/_/nginx/tags" + "https://hub.docker.com/_/nginx/tags", + "https://hub.docker.com/r/prom/prometheus/tags" ] +def parse_dockerhub_url(image_url): + path_parts = [part for part in urlparse(image_url).path.split('/') if part] + if len(path_parts) >= 3 and path_parts[-1] == 'tags': + if path_parts[0] == '_': + namespace = "library" + repository = path_parts[1] + return namespace, repository + elif path_parts[0] == 'r' and len(path_parts) >= 4: + namespace = path_parts[1] + repository = path_parts[2] + return namespace, repository + logging.warning(f"Could not parse Docker Hub URL: {image_url}") + return None, None + + +def pull_image(image_name: str, tag: str) -> bool: + pull_command = f"docker pull {image_name}:{tag}" + logging.info(f"Pulling image: {image_name}:{tag} with command: '{pull_command}'") + try: + result = subprocess.run(pull_command, shell=True, check=True, capture_output=True, text=True) + logging.info(f"Successfully pulled {image_name}:{tag}") + # Stderr might contain useful info even on success (e.g. image up to date) + if result.stdout and result.stdout.strip(): + logging.debug(f"Pull stdout: {result.stdout.strip()}") + if result.stderr and result.stderr.strip(): + logging.debug(f"Pull stderr: {result.stderr.strip()}") + return True + except subprocess.CalledProcessError as e: + logging.error(f"Failed to pull {image_name}:{tag}. Command: '{e.cmd}' exited with code {e.returncode}") + if e.stderr: + logging.error(f"Stderr: {e.stderr.strip()}") + if e.stdout: + logging.error(f"Stdout: {e.stdout.strip()}") # Error because it might contain error messages + return False + except FileNotFoundError: + logging.error("Docker command not found. Please ensure Docker is installed and in PATH.") + return False + except Exception as e: + logging.exception(f"An unexpected error occurred while pulling {image_name}:{tag}: {e}") + return False + +def tag_image(original_image_name: str, original_tag: str, target_repo_url: str, new_tag: str) -> bool: + source_image_ref = f"{original_image_name}:{original_tag}" + target_image_ref = f"{target_repo_url}/{original_image_name}:{new_tag}" + tag_command = f"docker tag {source_image_ref} {target_image_ref}" + logging.info(f"Tagging image {source_image_ref} as {target_image_ref} with command: '{tag_command}'") + try: + result = subprocess.run(tag_command, shell=True, check=True, capture_output=True, text=True) + logging.info(f"Successfully tagged {source_image_ref} as {target_image_ref}") + if result.stdout and result.stdout.strip(): # Docker tag usually doesn't produce stdout + logging.debug(f"Tag stdout: {result.stdout.strip()}") + return True + except subprocess.CalledProcessError as e: + logging.error(f"Error tagging image. Command: '{e.cmd}' failed with exit code {e.returncode}") + if e.stderr: + logging.error(f"Stderr: {e.stderr.strip()}") + if e.stdout: + logging.error(f"Stdout: {e.stdout.strip()}") + return False + except FileNotFoundError: + logging.error("Docker command not found. Please ensure Docker is installed and in PATH.") + return False + except Exception as e: + logging.exception(f"An unexpected error occurred while tagging {source_image_ref}: {e}") + return False + +def docker_login(registry_url: str, username: str, password: str) -> bool: + login_command = f"docker login {registry_url} -u {username} --password-stdin" + logging.info(f"Attempting to login to {registry_url} as {username}...") + try: + result = subprocess.run(login_command, input=password, text=True, shell=True, check=True, capture_output=True) + # Docker login success message is often on stderr, or stdout depending on version/registry + # Checking result.stdout and result.stderr for "Login Succeeded" or similar messages is more robust + # For now, just log the attempt as successful if no error is raised. + logging.info(f"Docker login command to {registry_url} as {username} executed successfully.") + if result.stdout and result.stdout.strip(): + logging.info(f"Login stdout: {result.stdout.strip()}") + if result.stderr and result.stderr.strip(): # Often "Login Succeeded" is here + logging.info(f"Login stderr: {result.stderr.strip()}") + return True + except subprocess.CalledProcessError as e: + logging.error(f"Error during Docker login to {registry_url}. Command: '{e.cmd}' failed with exit code {e.returncode}") + if e.stderr: + logging.error(f"Stderr: {e.stderr.strip()}") + if e.stdout: + logging.error(f"Stdout: {e.stdout.strip()}") + return False + except FileNotFoundError: + logging.error("Docker command not found. Please ensure Docker is installed and in PATH.") + return False + except Exception as e: + logging.exception(f"An unexpected error occurred during Docker login to {registry_url}: {e}") + return False + +def push_image(full_image_reference: str) -> bool: + push_command = f"docker push {full_image_reference}" + logging.info(f"Pushing image: {full_image_reference} with command: '{push_command}'") + try: + result = subprocess.run(push_command, shell=True, check=True, capture_output=True, text=True) + logging.info(f"Successfully pushed {full_image_reference}") + if result.stdout and result.stdout.strip(): + logging.debug(f"Push stdout: {result.stdout.strip()}") + if result.stderr and result.stderr.strip(): # Push progress might also be on stderr + logging.debug(f"Push stderr: {result.stderr.strip()}") + return True + except subprocess.CalledProcessError as e: + logging.error(f"Error pushing image {full_image_reference}. Command: '{e.cmd}' failed with exit code {e.returncode}") + if e.stderr: + logging.error(f"Stderr: {e.stderr.strip()}") + if e.stdout: + logging.error(f"Stdout: {e.stdout.strip()}") + return False + except FileNotFoundError: + logging.error("Docker command not found. Please ensure Docker is installed and in PATH.") + return False + except Exception as e: + logging.exception(f"An unexpected error occurred while pushing {full_image_reference}: {e}") + return False +def is_image_backed_up(image_name: str, tag: str, record_file: str = "backed_up_images.txt") -> bool: + record_to_check = f"{image_name}:{tag}" + try: + if not os.path.exists(record_file): + logging.debug(f"Record file {record_file} does not exist. Image {record_to_check} is not backed up.") + return False + with open(record_file, "r") as f: + for line in f: + if line.strip() == record_to_check: + logging.info(f"Image {record_to_check} already recorded as backed up in {record_file}.") + return True + logging.debug(f"Image {record_to_check} not found in {record_file}.") + return False + except IOError as e: + logging.error(f"Error reading record file {record_file}: {e}. Assuming not backed up.") + return False -async def get_tags_data(image_url): - async with ClientSession() as session: # 使用 ClientSession 来发送请求 - async with session.get(image_url) as response: # 发起 GET 请求 - html = await response.text() # 获取响应的 HTML 内容 - print(html) # 打印 HTML 内容 +def record_backup(image_name: str, tag: str, record_file: str = "backed_up_images.txt") -> None: + record_to_add = f"{image_name}:{tag}" + try: + with open(record_file, "a") as f: + f.write(record_to_add + "\n") + logging.info(f"Successfully recorded {record_to_add} as backed up in {record_file}.") + except IOError as e: + logging.error(f"Error writing to record file {record_file}: {e}") +async def get_tags_data(session, image_url, n=5): + namespace, repository = parse_dockerhub_url(image_url) + if not namespace or not repository: + # Error already logged by parse_dockerhub_url if it fails + return [] + + api_url = f"https://hub.docker.com/v2/repositories/{namespace}/{repository}/tags/?page_size={n}" + logging.debug(f"Fetching tags from: {api_url}") + + try: + async with session.get(api_url) as response: + response.raise_for_status() + data = await response.json() + tags = [] + if "results" in data and isinstance(data["results"], list): + for item in data["results"]: + if "name" in item: + tags.append({"repository": repository, "tag": item["name"]}) + return tags + except Exception as e: + logging.error(f"Error fetching or parsing tags for {image_url}: {e}", exc_info=True) + return [] async def main(): - await asyncio.gather(get_tags_data(image_urls[0])) + logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(module)s - %(funcName)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + + parser = argparse.ArgumentParser(description="Backup Docker images from Docker Hub to a target registry.") + parser.add_argument("-n", "--num-tags", type=int, default=5, help="Number of latest tags to fetch per image. Default: 5") + parser.add_argument("-r", "--record-file", type=str, default="backed_up_images.txt", help="Path to the backup record file. Default: backed_up_images.txt") + parser.add_argument("-u", "--image-urls", type=str, help="Comma-separated string of Docker Hub URLs to process. Overrides the hardcoded list.") + + args = parser.parse_args() + + logging.info("--- Configuration Loading ---") + target_registry_url = os.getenv("TARGET_REGISTRY_URL") + target_namespace = os.getenv("TARGET_NAMESPACE") + docker_username = os.getenv("DOCKER_USERNAME") + docker_password = os.getenv("DOCKER_PASSWORD") + + if not all([target_registry_url, target_namespace, docker_username, docker_password]): + logging.error("Error: Missing one or more required environment variables: TARGET_REGISTRY_URL, TARGET_NAMESPACE, DOCKER_USERNAME, DOCKER_PASSWORD") + sys.exit(1) + + logging.info(f"Target Registry URL: {target_registry_url}") + logging.info(f"Target Namespace: {target_namespace}") + logging.info(f"Record File: {args.record_file}") + logging.info(f"Number of tags to fetch per image: {args.num_tags}") + + current_image_urls_to_process = image_urls + if args.image_urls: + current_image_urls_to_process = [url.strip() for url in args.image_urls.split(',')] + logging.info(f"Using provided image URLs: {current_image_urls_to_process}") + else: + logging.info(f"Using hardcoded image URLs: {current_image_urls_to_process}") + + logging.info("--- Docker Login ---") + if not docker_login(target_registry_url, docker_username, docker_password): + logging.error("Docker login failed. Exiting.") + sys.exit(1) + # Success message logged by docker_login or here if preferred + logging.info("Docker login process completed.") + + + logging.info("--- Starting Image Backup Process ---") + async with ClientSession() as session: + for source_image_url in current_image_urls_to_process: + logging.info(f"Processing URL: {source_image_url}") + source_hub_namespace, source_hub_repo_name = parse_dockerhub_url(source_image_url) + + if not source_hub_repo_name: + logging.warning(f"Failed to parse Docker Hub URL: {source_image_url}. Skipping.") + continue + + if source_hub_namespace == "library": + image_name_on_hub = source_hub_repo_name + else: + image_name_on_hub = f"{source_hub_namespace}/{source_hub_repo_name}" + + logging.info(f"Fetching tags for {image_name_on_hub} (up to {args.num_tags} tags)...") + tags_data = await get_tags_data(session, source_image_url, n=args.num_tags) + + if not tags_data: + logging.warning(f"No tags found or error fetching tags for {image_name_on_hub}. Skipping.") + continue + + logging.info(f"Found {len(tags_data)} tags for {image_name_on_hub}. Processing...") + + for image_info in tags_data: + current_tag = image_info["tag"] + logging.info(f"Processing tag: {image_name_on_hub}:{current_tag}") + + if is_image_backed_up(image_name_on_hub, current_tag, args.record_file): + # Message already logged by is_image_backed_up + continue + + logging.info(f"Attempting to pull {image_name_on_hub}:{current_tag}...") + if not pull_image(image_name_on_hub, current_tag): + logging.error(f"Pull failed for {image_name_on_hub}:{current_tag}. Skipping this tag.") + continue + + target_repo_base_for_tagging = f"{target_registry_url}/{target_namespace}" + logging.info(f"Attempting to tag {image_name_on_hub}:{current_tag} for {target_repo_base_for_tagging}...") + if not tag_image(original_image_name=image_name_on_hub, + original_tag=current_tag, + target_repo_url=target_repo_base_for_tagging, + new_tag=current_tag): + logging.error(f"Tagging failed for {image_name_on_hub}:{current_tag}. Skipping this tag.") + continue + + full_image_ref_for_push = f"{target_repo_base_for_tagging}/{image_name_on_hub}:{current_tag}" + logging.info(f"Attempting to push {full_image_ref_for_push}...") + if not push_image(full_image_ref_for_push): + logging.error(f"Push failed for {full_image_ref_for_push}. Skipping this tag.") + continue + + logging.info(f"Successfully pulled, tagged, and pushed {image_name_on_hub}:{current_tag} to {full_image_ref_for_push}") + record_backup(image_name_on_hub, current_tag, args.record_file) + logging.info("--- Image Backup Process Completed ---") if __name__ == "__main__": asyncio.run(main()) From 435dcc9bd7cfcde2066c14778f67cfc8dfc5da54 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:21:57 +0000 Subject: [PATCH 36/37] feat: Add GitHub Actions Workflow for daily image backup I've added a new GitHub Actions Workflow (`.github/workflows/daily_image_backup.yml`) that will automatically run the `main.py` script every day. Key features: - Scheduled to run daily at 02:00 UTC. - You can also trigger it manually. - The target repository URL, namespace, and authentication details are securely configured using GitHub Actions Secrets. - The Workflow steps include checking out the code, setting up the Python environment, installing dependencies, and running the `main.py` script. I've also updated the `README.md` file with instructions on how to configure and use this new Workflow, including the required GitHub Secrets. --- .github/workflows/daily_image_backup.yml | 29 +++++++++++++++++++++++ README.md | 30 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 .github/workflows/daily_image_backup.yml diff --git a/.github/workflows/daily_image_backup.yml b/.github/workflows/daily_image_backup.yml new file mode 100644 index 0000000000..82f33b303b --- /dev/null +++ b/.github/workflows/daily_image_backup.yml @@ -0,0 +1,29 @@ +name: Daily Docker Image Backup + +on: + schedule: + - cron: '0 2 * * *' # Daily at 02:00 UTC + workflow_dispatch: # Allows manual triggering + +jobs: + backup_images: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install dependencies + run: pip install aiohttp + + - name: Run image backup script + run: python main.py + env: + TARGET_REGISTRY_URL: ${{ secrets.TARGET_REGISTRY_URL_SECRET }} + TARGET_NAMESPACE: ${{ secrets.TARGET_NAMESPACE_SECRET }} + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME_SECRET }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD_SECRET }} diff --git a/README.md b/README.md index 9afe753fb2..1668d59fff 100644 --- a/README.md +++ b/README.md @@ -151,3 +151,33 @@ The script performs the following steps: * The script logs all operations, including errors, to the console using Python's `logging` module. * It will exit immediately if critical configuration (environment variables) is missing or if the initial login to the target Docker registry fails. * For errors encountered during the processing of a specific image or tag (e.g., pull failure, push failure), the script will log the error and attempt to continue with the next tag or image URL. + +## Automated Daily Backup Workflow (`.github/workflows/daily_image_backup.yml`) + +This repository includes a GitHub Actions workflow that automates the daily execution of the `main.py` script to back up Docker images. + +### Features + +- **Scheduled Execution:** Runs automatically every day at 02:00 UTC. +- **Manual Trigger:** Can also be triggered manually from the GitHub Actions tab. +- **Secure Configuration:** Uses GitHub Actions Secrets to store sensitive information like registry credentials. + +### Workflow Configuration + +To use this workflow, you need to configure the following secrets in your GitHub repository settings (`Settings > Secrets and variables > Actions > New repository secret`): + +- **`TARGET_REGISTRY_URL_SECRET`**: The URL of your target private registry (e.g., `ccr.ccs.tencentyun.com` or `registry.aliyuncs.com`). +- **`TARGET_NAMESPACE_SECRET`**: The namespace within your target private registry where images will be stored (e.g., `my-docker-images` or `my-project`). +- **`DOCKER_USERNAME_SECRET`**: The username for authenticating with your target private registry. +- **`DOCKER_PASSWORD_SECRET`**: The password for authenticating with your target private registry. + +### How it Works + +The workflow performs the following steps: + +1. **Checks out** the repository code. +2. **Sets up** a Python 3.9 environment. +3. **Installs** the required Python dependency (`aiohttp`). +4. **Executes** the `main.py` script, passing the configured secrets as environment variables to the script. The script then handles the image backup logic as described in the "Command-Line Script: `main.py`" section. + +Logs from the script execution can be viewed in the GitHub Actions run history for this workflow. From d2cf920e5f5cdff55cbce132ee763bfea39c4ac3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 05:37:01 +0000 Subject: [PATCH 37/37] docs: Update the script and Workflow instructions in README.md to Chinese Translate the usage instructions for the `main.py` command-line script and the `daily_image_backup.yml` GitHub Actions workflow into Chinese to improve readability for Chinese users. --- README.md | 152 +++++++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 1668d59fff..b00a300d59 100644 --- a/README.md +++ b/README.md @@ -51,57 +51,57 @@ registry.cn-hangzhou.aliyuncs.com 即 ALIYUN_REGISTRY
shrimp-images 即 ALIYUN_NAME_SPACE
alpine 即images.txt里面填的镜像
-## Command-Line Script: `main.py` +## 命令行脚本: `main.py` -This script provides a command-line interface to back up Docker images from Docker Hub to a specified private registry. It fetches image tags, pulls the images, re-tags them for the target registry, pushes them, and keeps a record of backed-up images to avoid redundant operations. +该脚本提供了一个命令行界面,用于将 Docker Hub 上的 Docker 镜像备份到指定的私有仓库。它会获取镜像标签,拉取镜像,为目标仓库重新标记镜像,推送它们,并记录已备份的镜像以避免重复操作。 -### Prerequisites +### 先决条件 -* Python 3.7+ (due to `asyncio` and `aiohttp`). -* Docker installed and running on the machine where the script is executed. -* Network access to Docker Hub (for fetching public images). -* Credentials and access to a target private Docker registry (e.g., Tencent Cloud CCR, Alibaba Cloud ACR, Docker Hub private repos, etc.). +* Python 3.7+ (由于使用了 `asyncio` 和 `aiohttp`)。 +* 在脚本执行的机器上已安装并正在运行 Docker。 +* 可以访问 Docker Hub 的网络 (用于获取公共镜像)。 +* 拥有目标私有 Docker 仓库的凭据和访问权限 (例如,腾讯云 CCR、阿里云 ACR、Docker Hub 私有仓库等)。 -### Dependencies +### 依赖项 -The script requires the following Python package: +该脚本需要以下 Python 包: * `aiohttp` -You can install it using pip: +您可以使用 pip 安装它: ```bash pip install aiohttp ``` -### Configuration +### 配置 -Configuration is managed via environment variables for credentials and target registry details, and command-line arguments for operational parameters. +配置通过环境变量管理凭据和目标仓库详细信息,通过命令行参数管理操作参数。 -#### Environment Variables (Mandatory) +#### 环境变量 (必需) -These environment variables **must** be set before running the script. The script will exit if any of them are missing. +在运行脚本之前 **必须** 设置这些环境变量。如果缺少任何一个,脚本将退出。 -* `TARGET_REGISTRY_URL`: The URL of your target private registry. - * Example: `ccr.ccs.tencentyun.com` or `registry.aliyuncs.com` or `docker.io` (for Docker Hub). -* `TARGET_NAMESPACE`: The namespace within your target private registry where images will be stored. - * Example: `my-docker-backups` or `myusername` (if using Docker Hub as the target). -* `DOCKER_USERNAME`: Your username for authenticating with the `TARGET_REGISTRY_URL`. -* `DOCKER_PASSWORD`: Your password for authenticating with the `TARGET_REGISTRY_URL`. +* `TARGET_REGISTRY_URL`: 您的目标私有仓库的 URL。 + * 示例: `ccr.ccs.tencentyun.com` 或 `registry.aliyuncs.com` 或 `docker.io` (用于 Docker Hub)。 +* `TARGET_NAMESPACE`: 您的目标私有仓库中用于存储镜像的命名空间。 + * 示例: `my-docker-backups` 或 `myusername` (如果使用 Docker Hub 作为目标)。 +* `DOCKER_USERNAME`: 用于向 `TARGET_REGISTRY_URL` 进行身份验证的用户名。 +* `DOCKER_PASSWORD`: 用于向 `TARGET_REGISTRY_URL` 进行身份验证的密码。 -#### Command-line Arguments +#### 命令行参数 -These arguments are optional and provide control over the script's execution: +这些参数是可选的,用于控制脚本的执行: -* `--num-tags` (`-n`): The number of latest tags to fetch and process for each image. - * Default: `5` -* `--record-file` (`-r`): Path to the file used for recording backed-up images to prevent re-processing. - * Default: `backed_up_images.txt` -* `--image-urls` (`-u`): A comma-separated string of Docker Hub image URLs to process. This allows you to specify which images to back up. - * Example: `"https://hub.docker.com/_/nginx/tags,https://hub.docker.com/r/prom/prometheus/tags"` - * If not provided, the script uses a default list of image URLs hardcoded in `main.py`. +* `--num-tags` (`-n`): 为每个镜像获取和处理的最新标签数量。 + * 默认值: `5` +* `--record-file` (`-r`): 用于记录已备份镜像以防止重复处理的文件路径。 + * 默认值: `backed_up_images.txt` +* `--image-urls` (`-u`): 以逗号分隔的 Docker Hub 镜像 URL 字符串,用于指定要处理的镜像。 + * 示例: `"https://hub.docker.com/_/nginx/tags,https://hub.docker.com/r/prom/prometheus/tags"` + * 如果未提供,脚本将使用 `main.py` 中硬编码的默认镜像 URL 列表。 -### Running the Script +### 运行脚本 -1. **Set Environment Variables:** +1. **设置环境变量:** ```bash export TARGET_REGISTRY_URL="your-registry.example.com" export TARGET_NAMESPACE="your-namespace" @@ -109,75 +109,75 @@ These arguments are optional and provide control over the script's execution: export DOCKER_PASSWORD="your-registry-password" ``` -2. **Execute `main.py`:** +2. **执行 `main.py`:** ```bash - python main.py [OPTIONS] + python main.py [选项] ``` - For example, to back up the 3 latest tags for `alpine` and `redis`: + 例如,备份 `alpine` 和 `redis` 的最新3个标签: ```bash python main.py -n 3 -u "https://hub.docker.com/_/alpine/tags,https://hub.docker.com/_/redis/tags" ``` - To use the default image list and fetch 5 tags per image: + 使用默认镜像列表并为每个镜像获取5个标签: ```bash python main.py ``` - The script will log its progress to the standard output, including information about fetching tags, pulling, tagging, pushing images, and any errors encountered. + 脚本会将其进度记录到标准输出,包括获取标签、拉取、标记、推送镜像以及遇到的任何错误的信息。 -### How it Works +### 工作原理 -The script performs the following steps: +脚本执行以下步骤: -1. **Configuration Loading:** Reads environment variables and parses command-line arguments. -2. **Docker Login:** Logs into the target Docker registry using the provided credentials. Exits if login fails. -3. **Image Processing Loop:** For each source image URL specified: - a. **Fetch Tags:** Retrieves the specified number of latest tags from Docker Hub using its API. - b. **Tag Processing Loop:** For each fetched tag: - i. **Check Backup Record:** Consults the record file (e.g., `backed_up_images.txt`) to see if the specific image and tag combination has already been backed up. If yes, skips to the next tag. - ii. **Pull:** If not backed up, pulls the image from Docker Hub (e.g., `nginx:latest`). - iii. **Tag:** Re-tags the pulled image for the target private registry (e.g., `your-registry.example.com/your-namespace/nginx:latest`). - iv. **Push:** Pushes the newly tagged image to the target private registry. - v. **Record Backup:** If all previous steps (pull, tag, push) are successful, adds an entry for the image and tag to the record file. +1. **加载配置:** 读取环境变量并解析命令行参数。 +2. **Docker 登录:** 使用提供的凭据登录到目标 Docker 仓库。如果登录失败则退出。 +3. **镜像处理循环:** 对于指定的每个源镜像 URL: + a. **获取标签:** 使用其 API 从 Docker Hub 检索指定数量的最新标签。 + b. **标签处理循环:** 对于获取的每个标签: + i. **检查备份记录:** 查询记录文件 (例如 `backed_up_images.txt`),看是否已备份特定的镜像和标签组合。如果是,则跳到下一个标签。 + ii. **拉取 (Pull):** 如果未备份,则从 Docker Hub 拉取镜像 (例如 `nginx:latest`)。 + iii. **标记 (Tag):** 为目标私有仓库重新标记拉取的镜像 (例如 `your-registry.example.com/your-namespace/nginx:latest`)。 + iv. **推送 (Push):** 将新标记的镜像推送到目标私有仓库。 + v. **记录备份:** 如果所有先前的步骤 (拉取、标记、推送) 都成功,则将镜像和标签的条目添加到记录文件。 -### Record File +### 记录文件 -* The record file (default: `backed_up_images.txt`) stores a list of image and tag combinations that have been successfully backed up. -* Each line in the file has the format: `image_name_on_hub:tag` - * Example: `nginx:1.25` or `prom/prometheus:v2.40.0` -* This file ensures that the script does not re-process images and tags that have already been backed up, saving time and resources. +* 记录文件 (默认: `backed_up_images.txt`) 存储已成功备份的镜像和标签组合的列表。 +* 文件中的每一行格式为: `镜像在Hub上的名称:标签` + * 示例: `nginx:1.25` 或 `prom/prometheus:v2.40.0` +* 该文件确保脚本不会重复处理已备份的镜像和标签,从而节省时间和资源。 -### Error Handling +### 错误处理 -* The script logs all operations, including errors, to the console using Python's `logging` module. -* It will exit immediately if critical configuration (environment variables) is missing or if the initial login to the target Docker registry fails. -* For errors encountered during the processing of a specific image or tag (e.g., pull failure, push failure), the script will log the error and attempt to continue with the next tag or image URL. +* 脚本使用 Python 的 `logging` 模块将所有操作 (包括错误) 记录到控制台。 +* 如果缺少关键配置 (环境变量) 或初始登录到目标 Docker 仓库失败,脚本将立即退出。 +* 对于在处理特定镜像或标签期间遇到的错误 (例如,拉取失败、推送失败),脚本将记录错误并尝试继续处理下一个标签或镜像 URL。 -## Automated Daily Backup Workflow (`.github/workflows/daily_image_backup.yml`) +## 自动化每日备份工作流 (`.github/workflows/daily_image_backup.yml`) -This repository includes a GitHub Actions workflow that automates the daily execution of the `main.py` script to back up Docker images. +该仓库包含一个 GitHub Actions 工作流,可自动每日执行 `main.py` 脚本以备份 Docker 镜像。 -### Features +### 特性 -- **Scheduled Execution:** Runs automatically every day at 02:00 UTC. -- **Manual Trigger:** Can also be triggered manually from the GitHub Actions tab. -- **Secure Configuration:** Uses GitHub Actions Secrets to store sensitive information like registry credentials. +- **定时执行:** 每天 UTC 时间 02:00 自动运行。 +- **手动触发:** 也可以从 GitHub Actions 选项卡手动触发。 +- **安全配置:** 使用 GitHub Actions Secrets 存储敏感信息,如仓库凭据。 -### Workflow Configuration +### 工作流配置 -To use this workflow, you need to configure the following secrets in your GitHub repository settings (`Settings > Secrets and variables > Actions > New repository secret`): +要使用此工作流,您需要在您的 GitHub 仓库设置中配置以下 Secrets (`Settings > Secrets and variables > Actions > New repository secret`): -- **`TARGET_REGISTRY_URL_SECRET`**: The URL of your target private registry (e.g., `ccr.ccs.tencentyun.com` or `registry.aliyuncs.com`). -- **`TARGET_NAMESPACE_SECRET`**: The namespace within your target private registry where images will be stored (e.g., `my-docker-images` or `my-project`). -- **`DOCKER_USERNAME_SECRET`**: The username for authenticating with your target private registry. -- **`DOCKER_PASSWORD_SECRET`**: The password for authenticating with your target private registry. +- **`TARGET_REGISTRY_URL_SECRET`**: 您的目标私有仓库的 URL (例如, `ccr.ccs.tencentyun.com` 或 `registry.aliyuncs.com`)。 +- **`TARGET_NAMESPACE_SECRET`**: 您的目标私有仓库中用于存储镜像的命名空间 (例如, `my-docker-images` 或 `my-project`)。 +- **`DOCKER_USERNAME_SECRET`**: 用于向您的目标私有仓库进行身份验证的用户名。 +- **`DOCKER_PASSWORD_SECRET`**: 用于向您的目标私有仓库进行身份验证的密码。 -### How it Works +### 工作原理 -The workflow performs the following steps: +该工作流执行以下步骤: -1. **Checks out** the repository code. -2. **Sets up** a Python 3.9 environment. -3. **Installs** the required Python dependency (`aiohttp`). -4. **Executes** the `main.py` script, passing the configured secrets as environment variables to the script. The script then handles the image backup logic as described in the "Command-Line Script: `main.py`" section. +1. **检出 (Checks out)** 仓库代码。 +2. **设置 (Sets up)** Python 3.9 环境。 +3. **安装 (Installs)** 所需的 Python 依赖 (`aiohttp`)。 +4. **执行 (Executes)** `main.py` 脚本,并将配置的 Secrets作为环境变量传递给脚本。然后,脚本按照 "命令行脚本: `main.py`" 部分所述处理镜像备份逻辑。 -Logs from the script execution can be viewed in the GitHub Actions run history for this workflow. +脚本执行的日志可以在此工作流的 GitHub Actions 运行历史中查看。