Repository: DaoCloud/public-image-mirror Branch: main Commit: 2a8b03e4641a Files: 29 Total size: 87.5 KB Directory structure: gitextract_k3b5ogrq/ ├── .gitee/ │ └── ISSUE_TEMPLATE/ │ └── allows-image.yml ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── allows-image.yml │ │ └── sync-image.yml │ └── workflows/ │ ├── ci-bot.yml │ ├── cidn-runner.yml │ ├── sync-image.yml │ ├── update-allows-list.yml │ └── verify-pr.yml ├── LICENSE ├── README.md ├── allows.txt ├── docs/ │ └── local-cache/ │ └── README.md └── hack/ ├── badge.sh ├── correct-image.sh ├── diff-image.sh ├── diff.sh ├── fmt-image-match.sh ├── fmt-image.sh ├── fmt.sh ├── helper.sh ├── merge-mirror.sh ├── stats-not-sync.sh ├── verify-allows.sh ├── verify-docker-prefix.sh ├── verify-fmt-image.sh ├── verify-fmt.sh ├── verify-image-match.sh ├── verify-image.sh └── verify-k8s-prefix.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitee/ISSUE_TEMPLATE/allows-image.yml ================================================ name: Allows Image description: 添加白名单 (人工审核) labels: - allows image body: - type: markdown attributes: value: | - 对于镜像的要求 [#2328](https://github.com/DaoCloud/public-image-mirror/issues/2328) - 一般 5个工作日内 🐢 [查看成功案例](https://github.com/DaoCloud/public-image-mirror/issues?q=is%3Aissue+label%3A%22allows+image%22+is%3Aclosed+linked%3Apr) - 自己提 [PR](https://github.com/DaoCloud/public-image-mirror/blob/main/allows.txt) 修改白名单优先审查 🚀 - 注意在 PR 的内容里描述 Fixed # 这个 issue 的 id [示例](https://github.com/DaoCloud/public-image-mirror/pull/23762) - type: dropdown attributes: label: 白名单级别 options: - 只需要这一个镜像 (如 docker.io/library/busybox) - 需要这个组织下所有镜像 (如 docker.io/library/*) validations: required: true - type: textarea attributes: label: 镜像仓库地址 placeholder: | https://hub.docker.com/r/... validations: required: true - type: dropdown attributes: label: 这是 **镜像仓库** 认证可信的 **验证过的发布者(Verified Publisher)**或者**赞助的项目(Sponsored OSS)** 么? options: - 不是 - 请补充下面的信息 - 是的 - 不需要填下面的信息 - 如果实际上不是将不再继续核查 validations: required: true - type: textarea attributes: label: 项目源码地址 或 组织地址 placeholder: | https://github.com/... - type: textarea attributes: label: 官网 或 文档 或 项目源码 中哪提及对应的镜像的地址 (需要证明这个镜像和源码有实际关联) - type: textarea attributes: label: 补充说明 - type: markdown attributes: value: | 有疑问反馈, 请添加我们的企微群 [#4183](https://github.com/DaoCloud/public-image-mirror/issues/4183) ================================================ FILE: .github/ISSUE_TEMPLATE/allows-image.yml ================================================ name: Allows Image description: 添加白名单 (人工审核) labels: - allows image body: - type: markdown attributes: value: | - 对于镜像的要求 [#2328](https://github.com/DaoCloud/public-image-mirror/issues/2328) - 一般 5个工作日内 🐢 [查看成功案例](https://github.com/DaoCloud/public-image-mirror/issues?q=is%3Aissue+label%3A%22allows+image%22+is%3Aclosed+linked%3Apr) - 自己提 [PR](https://github.com/DaoCloud/public-image-mirror/blob/main/allows.txt) 修改白名单优先审查 🚀 - 注意在 PR 的内容里描述 Fixed # 这个 issue 的 id [示例](https://github.com/DaoCloud/public-image-mirror/pull/23762) - type: dropdown attributes: label: 白名单级别 options: - 只需要这一个镜像 (如 docker.io/library/busybox) - 需要这个组织下所有镜像 (如 docker.io/library/*) validations: required: true - type: textarea attributes: label: 镜像仓库地址 placeholder: | https://hub.docker.com/r/... validations: required: true - type: dropdown attributes: label: 这是 **镜像仓库** 认证可信的 **验证过的发布者(Verified Publisher)**或者**赞助的项目(Sponsored OSS)** 么? options: - 不是 - 请补充下面的信息 - 是的 - 不需要填下面的信息 - 如果实际上不是将不再继续核查 validations: required: true - type: textarea attributes: label: 项目源码地址 或 组织地址 placeholder: | https://github.com/... - type: textarea attributes: label: 官网 或 文档 或 项目源码 中哪提及对应的镜像的地址 (需要证明这个镜像和源码有实际关联) - type: textarea attributes: label: 补充说明 - type: markdown attributes: value: | 有疑问反馈, 请添加我们的企微群 [#4183](https://github.com/DaoCloud/public-image-mirror/issues/4183) ================================================ FILE: .github/ISSUE_TEMPLATE/sync-image.yml ================================================ name: Sync Image description: 同步一个镜像 (需要 Image 已在白名单里) labels: - sync image body: - type: markdown attributes: value: | # ↑↑↑↑↑↑↑↑↑↑↑ 填入你要同步的 Image ## 请包含 域名/路径:标签 - type: dropdown attributes: label: 镜像架构 description: 请选择要同步的目标架构 options: - linux/amd64 - linux/386 - linux/arm64 - linux/arm/v6 - linux/arm/v7 - linux/ppc64le - linux/s390x validations: required: true - type: markdown attributes: value: | 请确保包含域名(domain) - 如 docker.io/ - 如 registry.k8s.io/ - 如果不包含域名, 需要主动添加默认的 docker.io/ - type: markdown attributes: value: | 请确保包含镜像的标签(tag) - 如 :latest - 如 :v1 - type: markdown attributes: value: | 请确保这个镜像真实存在 - 如 docker.io/library/busybox:latest - 如 docker.io/kindest/node:v1.30.0 - 如 registry.k8s.io/kubectl:v1.30.0 - type: markdown attributes: value: | 有疑问反馈, 请添加我们的企微群 [#4183](https://github.com/DaoCloud/public-image-mirror/issues/4183) ================================================ FILE: .github/workflows/ci-bot.yml ================================================ name: CI Bot on: issue_comment: types: - created pull_request_review_comment: types: - created issues: types: - opened # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target pull_request_target: types: - opened env: # This plugins is for anyone who can use it PLUGINS: |- assign auto-cc cc # This plugins is for author of issue or PR AUTHOR_PLUGINS: |- label-bug label-documentation label-enhancement label-question retest # This plugins is for organization member or repository member MEMBERS_PLUGINS: |- label-duplicate label-good-first-issue label-help-wanted label-invalid label-kind label-wontfix label-bug label-documentation label-enhancement label-question lifecycle retest # This plugins is for in the REVIEWERS environment variable REVIEWERS_PLUGINS: |- label-lgtm retitle # This plugins is for in the APPROVERS environment variable APPROVERS_PLUGINS: |- label merge base rebase # This plugins is for in the MAINTAINERS environment variable MAINTAINERS_PLUGINS: |- milestone # This plugins is for organization owner or repository owner OWNERS_PLUGINS: "" REVIEWERS: |- yankay wzshiming APPROVERS: |- yankay wzshiming MAINTAINERS: |- yankay wzshiming GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPOSITORY: ${{ github.repository }} DETAILS: |-
Details Instructions for interacting with me using comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the [gh-ci-bot](https://github.com/wzshiming/gh-ci-bot) repository.
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token permissions: actions: write checks: read contents: write deployments: none id-token: none issues: write discussions: read packages: none pages: none pull-requests: write repository-projects: read security-events: none statuses: read jobs: bot: name: Bot runs-on: ubuntu-latest steps: - name: Issue Opened uses: wzshiming/gh-ci-bot@v1 if: ${{ github.event_name == 'issues' }} env: LOGIN: ${{ github.event.issue.user.login }} AUTHOR: ${{ github.event.issue.user.login }} MESSAGE: ${{ github.event.issue.body }} ISSUE_NUMBER: ${{ github.event.issue.number }} AUTHOR_ASSOCIATION: ${{ github.event.issue.author_association }} ISSUE_KIND: issue TYPE: created GREETING: |- Hi @${{ github.event.issue.user.login }}, 感谢您的反馈! 我们会尽快跟进. - name: PR Opened uses: wzshiming/gh-ci-bot@v1 if: ${{ github.event_name == 'pull_request_target' }} env: LOGIN: ${{ github.event.pull_request.user.login }} AUTHOR: ${{ github.event.pull_request.user.login }} MESSAGE: ${{ github.event.pull_request.body }} ISSUE_NUMBER: ${{ github.event.pull_request.number }} AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }} ISSUE_KIND: pr TYPE: created GREETING: |- Hi @${{ github.event.pull_request.user.login }}, 感谢您的 PR ! 如果 PR 已经准备就绪可以 `/auto-cc` ,我们会尽快跟进. - name: Issue Commented uses: wzshiming/gh-ci-bot@v1 if: ${{ github.event_name == 'issue_comment' && !github.event.issue.pull_request }} env: LOGIN: ${{ github.event.comment.user.login }} AUTHOR: ${{ github.event.issue.user.login }} MESSAGE: ${{ github.event.comment.body }} ISSUE_NUMBER: ${{ github.event.issue.number }} AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association }} ISSUE_KIND: issue TYPE: comment - name: PR Review Commented uses: wzshiming/gh-ci-bot@v1 if: ${{ github.event_name == 'pull_request_review_comment' }} env: LOGIN: ${{ github.event.comment.user.login }} AUTHOR: ${{ github.event.pull_request.user.login }} MESSAGE: ${{ github.event.comment.body }} ISSUE_NUMBER: ${{ github.event.pull_request.number }} AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association }} ISSUE_KIND: pr TYPE: comment - name: PR Commented uses: wzshiming/gh-ci-bot@v1 if: ${{ github.event_name == 'issue_comment' && github.event.issue.pull_request }} env: LOGIN: ${{ github.event.comment.user.login }} AUTHOR: ${{ github.event.issue.user.login }} MESSAGE: ${{ github.event.comment.body }} ISSUE_NUMBER: ${{ github.event.issue.number }} AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association }} ISSUE_KIND: pr TYPE: comment ================================================ FILE: .github/workflows/cidn-runner.yml ================================================ name: CIDN Runner run-name: CIDN Runner ${{ github.run_number }} on: schedule: - cron: "0,30 * * * *" workflow_dispatch: jobs: runner: runs-on: ubuntu-latest if: github.repository == 'DaoCloud/public-image-mirror' container: ghcr.io/opencidn/cidn/runner:v0.0.109 steps: - shell: sh run: runner --handler-name=dc-${{ github.run_number }} --update-duration=10s --duration=4h --concurrency=3 ${{ secrets.ARGS_CIDN }} ================================================ FILE: .github/workflows/sync-image.yml ================================================ name: Target Sync Image run-name: Target Sync ${{ github.event.issue.title }} by @${{ github.actor }} on: issues: types: - opened # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token permissions: issues: write jobs: check: runs-on: ubuntu-latest if: contains(github.event.issue.labels.*.name, 'sync image') env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} outputs: image: ${{ steps.get-image.outputs.image }} link: ${{ steps.get-image.outputs.link }} platforms: ${{ steps.get-image.outputs.platforms }} arch: ${{ steps.get-image.outputs.arch }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Check Issue id: get-image env: IMAGE: "${{ github.event.issue.title }}" ISSUE_BODY: "${{ github.event.issue.body }}" run: | ORIGIN_IMAGE="${IMAGE}" CORRECT_IMAGE="$(./hack/correct-image.sh "${ORIGIN_IMAGE}")" if [[ "${CORRECT_IMAGE}" == "" ]]; then gh issue comment ${{ github.event.issue.number }} -b "镜像 '${ORIGIN_IMAGE}' 不是一个镜像" gh issue close ${{ github.event.issue.number }} --reason "not planned" exit 1 fi if [[ "${CORRECT_IMAGE}" != "${ORIGIN_IMAGE}" ]]; then if ! ./hack/verify-allows.sh ./allows.txt "${CORRECT_IMAGE}"; then gh issue comment ${{ github.event.issue.number }} -b "镜像 '${ORIGIN_IMAGE}' 不存在呢, 也许应该是 '${CORRECT_IMAGE}', 并且不在白名单列表里, 不支持同步和访问
可以将其添加到[白名单](https://github.com/${{ github.repository }}/issues/2328)" else gh issue comment ${{ github.event.issue.number }} -b "镜像 '${ORIGIN_IMAGE}' 不存在呢, 也许应该是 '${CORRECT_IMAGE}'" fi gh issue close ${{ github.event.issue.number }} --reason "not planned" exit 1 fi if ! ./hack/verify-allows.sh ./allows.txt "${ORIGIN_IMAGE}"; then gh issue comment ${{ github.event.issue.number }} -b "镜像 ${ORIGIN_IMAGE} 不在白名单列表里, 不支持同步和访问
可以将其添加到[白名单](https://github.com/${{ github.repository }}/issues/2328)" gh issue close ${{ github.event.issue.number }} --reason "not planned" exit 1 fi IMAGE="${ORIGIN_IMAGE}" echo "image=${IMAGE}" >> $GITHUB_OUTPUT GROUP="${IMAGE%%:*}" GROUP="${GROUP%%@*}" LINK="https://queue.m.daocloud.io/status/#group:${GROUP}" echo "link=${LINK}" >> $GITHUB_OUTPUT BODY="${ISSUE_BODY:-}" ARCH="" if [ -z "${ARCH}" ]; then ARCH=$(printf "%s" "$BODY" | grep -oE 'linux/[a-z0-9/._+-]+' | head -n1 || true) fi if [ -z "${ARCH}" ]; then ARCH="linux/amd64" fi echo "arch=${ARCH}" >> $GITHUB_OUTPUT PLATFORM_FLAG="--platform=${ARCH}" echo "platforms=${PLATFORM_FLAG}" >> $GITHUB_OUTPUT gh issue comment ${{ github.event.issue.number }} -b "镜像 ${IMAGE}, 平台 ${ARCH} 将添加到同步队列...
[同步队列](${LINK})
[详细信息](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" sync: runs-on: ubuntu-latest needs: check if: needs.check.result == 'success' container: ghcr.io/opencidn/ocimirror/sync:v0.0.40 steps: - shell: sh run: sync ${{ needs.check.outputs.image }} ${{ needs.check.outputs.platforms }} ${{ secrets.ARGS_CIDN }} ${{ secrets.ARGS_R2_IMAGE }} runner: runs-on: ubuntu-latest needs: check if: needs.check.result == 'success' container: ghcr.io/opencidn/cidn/runner:v0.0.108 steps: - shell: sh run: runner --handler-name=dc-${{ github.run_number }}-${{ github.event.issue.number }} --update-duration=10s --duration=5m --concurrency=2 ${{ secrets.ARGS_CIDN }} failure: runs-on: ubuntu-latest needs: - sync - check if: always() && needs.sync.result == 'failure' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Sync Failure Status run: | gh -R "${{ github.repository }}" issue edit ${{ github.event.issue.number }} --add-label "sync image failure" -b "镜像同步失败" gh -R "${{ github.repository }}" issue close ${{ github.event.issue.number }} --reason "not planned" --comment "镜像 ${{ needs.check.outputs.image }}, 平台 ${{ needs.check.outputs.arch }} 同步失败
请去同步队列查看详细信息。" success: runs-on: ubuntu-latest needs: - sync - check if: needs.sync.result == 'success' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Sync Success Status run: | gh -R "${{ github.repository }}" issue edit ${{ github.event.issue.number }} --add-label "sync image succeeded" -b "镜像同步完成" gh -R "${{ github.repository }}" issue close ${{ github.event.issue.number }} --reason "completed" --comment "镜像 ${{ needs.check.outputs.image }}, 平台 ${{ needs.check.outputs.arch }} 同步完成
请使用 m.daocloud.io/${{ needs.check.outputs.image }} 进行访问。" ================================================ FILE: .github/workflows/update-allows-list.yml ================================================ name: Update allows list on: push: paths: - allows.txt branches: - main workflow_dispatch: jobs: update-allows-list: if: github.repository == 'DaoCloud/public-image-mirror' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Update list run: | LIST="$(cat ./allows.txt | grep -v 'docker.io/\*' | sed 's/docker.io\/library\/\([^\/]*\)/&\ndocker.io\/\1/' | jq -R -s -c '{"items": split("\n")[:-1], "block_message": "🚫 👀-> https://github.com/DaoCloud/public-image-mirror/issues/2328 🔗 这镜像不在白名单. this image is not in the allowlist."}')" TOKEN="$(curl -X 'POST' \ 'https://queue.m.daocloud.io/apis/auth/users/login' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d ${{ secrets.USER_LOGIN_DATA }} | jq -r .token)" curl -f -X 'PUT' \ 'https://queue.m.daocloud.io/apis/auth/registries/allow_images' \ -H 'Accept: application/json' \ -H "Authorization: Bearer ${TOKEN}" \ -H 'Content-Type: application/json' \ -d "${LIST}" ================================================ FILE: .github/workflows/verify-pr.yml ================================================ name: Verify PR on: pull_request_target: branches: [main] paths: - 'mirror.txt' - 'allows.txt' permissions: issues: write pull-requests: write env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: verify-pr: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Commit PR run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" wget -O pr.patch https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}.patch && \ git am -3 pr.patch && rm -rf pr.patch - name: Verify allows.txt sort run: | ./hack/verify-image-match.sh allows.txt || { echo "Please run './hack/fmt-image-match.sh allows.txt'" gh pr comment "${{ github.event.pull_request.number }}" --body '请运行 `./hack/fmt-image-match.sh allows.txt` 对内容进行排序' exit 1 } ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # public-image-mirror 源仓库 [Github](https://github.com/DaoCloud/public-image-mirror) Mirror 仓库 [Gitee](https://gitee.com/daocloud/public-image-mirror) - 白名单 & 限流 的公开信息 [#2328](https://github.com/DaoCloud/public-image-mirror/issues/2328) - 如有疑问请咨询 [#4183](https://github.com/DaoCloud/public-image-mirror/issues/4183) - 建议将拉取任务放在闲时 凌晨(北京时间 01-07 点), 其他时间段非常拥挤 - 建议使用明确版本号的 tag, 对于 latest 这种变更后响应旧数据, 并且后台重新同步 - [本服务后端代码](https://github.com/OpenCIDN/ocimirror) - [同步队列](https://queue.m.daocloud.io/status/) 仅保留一小时的同步记录 - [服务状态监控](https://status.daocloud.io/status/docker) ## 背景 & 目标 很多镜像都在国外。比如 gcr 。国内下载很慢,需要加速。 * 一个简洁有效的方法能够加速这些包。简洁的名称映射 * 易于添加,添加新的包,不需要去修改代码。 * 稳定可靠,更新实时。每天检查同步情况。 * 此项目仅是源镜像仓库 (Registry) 的 Mirror * 所有 hash(sha256) 均和源保持一致 (懒加载机制)。 * 缓存的内容只保留 90 天, 过期后会需要重新同步。 * Manifest 内存缓存 1 小时, 所以 tag 被更新了 1 小时之后才会同步新的。 * Blob 内存缓存 1 分钟, 在期间如果 blob 到达 90 天期限被删除会报 404。 ## 快速开始 ``` docker run -d -P m.daocloud.io/docker.io/library/nginx ``` ## 使用方法 **增加前缀** (推荐方式)。比如: ``` log docker.io/library/busybox | V m.daocloud.io/docker.io/library/busybox ``` 或者 支持的镜像仓库 的 *前缀替换* 就可以使用。比如: ``` log docker.io/library/busybox | V docker.m.daocloud.io/library/busybox ``` ## 支持前缀替换的 Registry (不推荐) 推荐使用添加前缀的方式. 前缀替换的 Registry 的规则, 这是人工配置的, 有需求提 Issue. 除了 docker.io 这里每一个源站, 内容都是不同的, 不要把 docker.io 之外的站点配置给 registry-mirrors | 源站 | 替换为 | 备注 | | ------------------ | --------------------- | ---------------------------------------------- | | docker.elastic.co | elastic.m.daocloud.io | | | docker.io | docker.m.daocloud.io | | | dhi.io | dhi.m.daocloud.io | | | gcr.io | gcr.m.daocloud.io | | | ghcr.io | ghcr.m.daocloud.io | | | k8s.gcr.io | k8s-gcr.m.daocloud.io | k8s.gcr.io 已被迁移到 registry.k8s.io | | registry.k8s.io | k8s.m.daocloud.io | | | mcr.microsoft.com | mcr.m.daocloud.io | | | nvcr.io | nvcr.m.daocloud.io | | | quay.io | quay.m.daocloud.io | | | registry.ollama.ai | ollama.m.daocloud.io | 实验内测中,[使用方法](#加速-ollama--deepseek) | ## 最佳实践 ### 部署内网缓存 本地缓存部署用于在内网环境中加速镜像拉取,减少对外网的依赖。通过设置一个本地镜像仓库,您可以缓存常用的镜像。 [请参考文档](https://github.com/DaoCloud/public-image-mirror/tree/main/docs/local-cache) ### 加速 Kubneretes #### 加速安装 kubeadm ``` yaml apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration dns: imageRepository: k8s.m.daocloud.io/coredns imageRepository: k8s.m.daocloud.io ... ``` #### 加速安装 kind ``` bash kind create cluster --name kind --image m.daocloud.io/docker.io/kindest/node:v1.22.1 ``` #### 加速所有 Pod https://github.com/wzshiming/repimage 不修改 yaml, helm 等, 仅使用 Webhook, 自动修改所有新建 Pod 的 image 使用本 mirror ``` bash kubectl create -f https://files.m.daocloud.io/github.com/wzshiming/repimage/releases/download/latest/repimage.yaml kubectl rollout status deployment/repimage -n kube-system ``` #### 加速 Containerd * 参考 Containerd 官方文档: [hosts.md](https://github.com/containerd/containerd/blob/main/docs/hosts.md#registry-host-namespace) * 如果您使用 kubespray 安装 containerd, 可以配置 [`containerd_registries_mirrors`](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/CRI/containerd.md#containerd-config) ### 加速 Docker 添加到 `/etc/docker/daemon.json` ``` json { "registry-mirrors": [ "https://docker.m.daocloud.io" ] } ``` ### 加速 Ollama & DeepSeek #### 加速安装 Ollama CPU: ```bash docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama docker.m.daocloud.io/ollama/ollama ``` GPU 版本: 1. 首先安装 Nvidia Container Toolkit 2. 运行以下命令启动 Ollama 容器: ```bash docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama docker.m.daocloud.io/ollama/ollama ``` 更多信息请参考: * [Ollama Docker 官方文档](https://ollama.com/blog/ollama-is-now-available-as-an-official-docker-image) #### 加速使用 Deepseek-R1 模型(实验内测中) 如上述步骤,在启动了ollama容器的前提下,还可以通过加速源,加速启动DeepSeek相关的模型服务 注:目前 Ollama 官方源的下载速度已经很快,您也可以直接使用[官方源](https://ollama.com/library/deepseek-r1:1.5b)。 ```bash # 使用加速源 docker exec -it ollama ollama run ollama.m.daocloud.io/library/deepseek-r1:1.5b # 或直接使用官方源下载模型 # docker exec -it ollama ollama run deepseek-r1:1.5b ``` ## [友情链接]加速二剑客 * 镜像加速:https://github.com/DaoCloud/public-image-mirror * 二进制文件加速:https://github.com/DaoCloud/public-binary-files-mirror ## 贡献者 Made with [contrib.rocks](https://contrib.rocks). ================================================ FILE: allows.txt ================================================ code.forgejo.org/forgejo/forgejo code.forgejo.org/forgejo/runner codeberg.org/forgejo/forgejo container-registry.oracle.com/** cr.kgateway.dev/kgateway-dev/* cr.l5d.io/** cr.weaviate.io/** dhi.io/** docker.com/kyantech/* docker.elastic.co/** docker.getcollate.io/openmetadata/* docker.io/* docker.io/0nlylty/dockercopilot docker.io/1activegeek/airconnect docker.io/1dev/* docker.io/1panel/maxkb docker.io/4pdosc/k8s-vdevice docker.io/569107519/alertsnitch-mysql docker.io/6053537/portainer-ce docker.io/acim/go-reflex docker.io/acore/* docker.io/acryldata/* docker.io/adguard/adguardhome docker.io/adoptopenjdk/* docker.io/adriansegura99/** docker.io/agentaai/* docker.io/ai/* docker.io/alexxit/go2rtc docker.io/alexzhc/* docker.io/allanpk716/chinesesubfinder docker.io/allfunc/speedtest docker.io/almalinux/* docker.io/alpine/* docker.io/alpinelinux/** docker.io/alseambusher/crontab-ui docker.io/altinity/* docker.io/amambadev/* docker.io/amazon/* docker.io/amd64/* docker.io/amir20/* docker.io/amtoaer/bili-sync-rs docker.io/andrejorsula/space_robotics_bench docker.io/andywuwu/coze2openai docker.io/ankane/pgvector docker.io/apache/* docker.io/apachepulsar/* docker.io/apacherocketmq/* docker.io/apecloud/* docker.io/apereo/cas docker.io/apicurio/* docker.io/apipark/apipark docker.io/apitable/* docker.io/apolloconfig/* docker.io/appbaseio/dejavu docker.io/approachingai/* docker.io/appsmith/appsmith-ce docker.io/appsmith/appsmith-ee docker.io/aquasec/* docker.io/arexadmin01/* docker.io/arey/* docker.io/argoproj/rollouts-demo docker.io/arigaio/* docker.io/arizephoenix/phoenix docker.io/arm64v8/* docker.io/artalk/artalk-go docker.io/ascendai/* docker.io/ascentstream/* docker.io/astral/uv docker.io/atlassian/* docker.io/authelia/authelia docker.io/automatischio/automatisch docker.io/autumn27/scopesentry-scan docker.io/b3log/siyuan docker.io/babashka/babashka docker.io/basecamp/* docker.io/bats/* docker.io/bellsoft/* docker.io/benzino77/clamav-rest-api docker.io/bililive/recorder docker.io/binhex/arch-jellyfin docker.io/binwiederhier/ntfy docker.io/bitnami/* docker.io/bitnamicharts/* docker.io/bitnamilegacy/* docker.io/bluenviron/mediamtx docker.io/boky/postfix docker.io/boredazfcuk/icloudpd docker.io/browserless/* docker.io/browsh/browsh docker.io/budibase/budibase docker.io/budtmo/docker-android docker.io/burakince/mlflow docker.io/bvlc/caffe docker.io/bytebase/bytebase docker.io/bytelang/kplayer docker.io/caarlos0/domain_exporter docker.io/calciumion/new-api docker.io/calico/* docker.io/camunda/zeebe docker.io/canal/canal-server docker.io/caronc/apprise docker.io/cars10/elasticvue docker.io/casbin/casdoor docker.io/certbot/* docker.io/chaosbladeio/chaosblade-box docker.io/chaoszhu/easynode docker.io/charlie0129/bupt-net-login docker.io/chat2db/chat2db docker.io/chatimage/chatchat docker.io/chatwoot/chatwoot docker.io/chengshiwen/influx-proxy docker.io/chengshiwen/influxdb docker.io/chenhw2/aliyun-ddns-cli docker.io/chigusa/bililive-go docker.io/chirpstack/* docker.io/chishin/nginx-proxy-manager-zh docker.io/chrishirsch/kuberhealthy-storage-check docker.io/chrislusf/seaweedfs docker.io/chromedp/headless-shell docker.io/chrstnhntschl/gpu_burn docker.io/cimg/go docker.io/clamav/* docker.io/claraverse/clara-ollama docker.io/clickhouse/* docker.io/clidey/whodb docker.io/cloudflare/* docker.io/cloudnas/clouddrive2-unstable docker.io/cloudnativelabs/kube-router docker.io/cloudreve/cloudreve docker.io/codercom/code-server docker.io/codewisdom/* docker.io/collabora/code docker.io/condaforge/miniforge3 docker.io/conduktor/* docker.io/confluentinc/* docker.io/containrrr/watchtower docker.io/continuumio/miniconda3 docker.io/coredns/* docker.io/coturn/coturn docker.io/cozedev/* docker.io/cp2k/cp2k docker.io/csiplugin/* docker.io/cturra/ntp docker.io/curlimages/* docker.io/cvat/server docker.io/cvat/ui docker.io/cym1102/nginxwebui docker.io/czerwonk/ping_exporter docker.io/dadoum/anisette-v3-server docker.io/dani-garcia/vaultwarden docker.io/danielqsj/kafka-exporter docker.io/daprio/* docker.io/darthsim/imgproxy docker.io/dataease/sqlbot docker.io/datastax/* docker.io/dbeaver/cloudbeaver docker.io/debezium/* docker.io/deepflowce/* docker.io/deluan/navidrome docker.io/democraticcsi/csi-grpc-proxy docker.io/democraticcsi/democratic-csi docker.io/denoland/deno docker.io/derailed/k9s docker.io/determinedai/* docker.io/devicefarmer/stf docker.io/dezhao/lanraragi_cn docker.io/difegue/lanraragi docker.io/digitalocean/ceph_exporter docker.io/directus/* docker.io/discourse/* docker.io/diygod/* docker.io/docker/* docker.io/dockurr/* docker.io/dokploy/* docker.io/doocs/* docker.io/dorowu/ubuntu-desktop-lxde-vnc docker.io/dpage/* docker.io/dpanel/base-image docker.io/dpanel/dpanel docker.io/dragonflydb/dragonfly docker.io/dragonflyoss/client docker.io/dragonflyoss/dfdaemon docker.io/dragonflyoss/dfinit docker.io/dragonflyoss/manager docker.io/dragonflyoss/scheduler docker.io/dragonflyoss/trainer docker.io/drakkan/sftpgo docker.io/dreamacro/clash docker.io/dremio/dremio-oss docker.io/drone/drone docker.io/drone/drone-runner-docker docker.io/drumsergio/genieacs docker.io/duckdb/duckdb docker.io/dushixiang/kafka-map docker.io/dustynv/* docker.io/dxflrs/* docker.io/e2bdev/code-interpreter docker.io/easytier/easytier docker.io/elastic/* docker.io/electronuserland/builder docker.io/elestio/neko docker.io/eloqdata/* docker.io/elsaworkflows/* docker.io/emberstack/kubernetes-reflector docker.io/emby/* docker.io/emqx/* docker.io/enable/nessus docker.io/ensemblorg/ensembl-vep docker.io/envoyproxy/* docker.io/eolinker/apinto-gateway docker.io/eosphorosai/* docker.io/esphome/* docker.io/estrellaxd/auto_bangumi docker.io/eucm/limesurvey docker.io/exadel/compreface-core docker.io/exceptionless/* docker.io/eyeblue/tank docker.io/f5networks/* docker.io/falcosecurity/* docker.io/falkordb/falkordb docker.io/fatedier/frps docker.io/feiyu563/prometheus-alert docker.io/feiyuyu/filecodebox docker.io/ffdfgdfg/npc docker.io/ffdfgdfg/nps docker.io/fffaraz/fakessh docker.io/filebrowser/filebrowser docker.io/finab/bark-server docker.io/firecow/gitlab-ci-local-util docker.io/fireflyiii/* docker.io/flannel/* docker.io/flannelcni/* docker.io/flashcatcloud/* docker.io/flexget/flexget docker.io/floryn90/hugo docker.io/flowiseai/flowise docker.io/fluent/* docker.io/flyway/flyway docker.io/forceless/pptagent docker.io/fortio/* docker.io/fosrl/* docker.io/foxdalas/* docker.io/frappe/* docker.io/freeradius/freeradius-server docker.io/freesurfer/synthmorph docker.io/frooodle/s-pdf docker.io/frrouting/* docker.io/funcman/115pc docker.io/gaecfovdocker/pulsar-console docker.io/gchq/hdfs docker.io/geoservercloud/* docker.io/germannewsmaker/myspeed docker.io/gerritcodereview/gerrit docker.io/getmeili/* docker.io/getsentry/* docker.io/getwud/wud docker.io/gitea/* docker.io/gitlab/* docker.io/gitpod/openvscode-server docker.io/gliderlabs/logspout docker.io/goacme/lego docker.io/gocd/* docker.io/gogs/gogs docker.io/goharbor/* docker.io/golangci/golangci-lint docker.io/google/* docker.io/goproxy/goproxy docker.io/goreleaser/goreleaser docker.io/gotenberg/gotenberg docker.io/gotify/* docker.io/gotson/komga docker.io/gpustack/gpustack docker.io/gpustack/runner docker.io/grafana/* docker.io/graphiteapp/graphite-statsd docker.io/gravitl/netmaker docker.io/graylog/graylog docker.io/graylog/graylog-datanode docker.io/greatsql/* docker.io/greenbone/* docker.io/greper/certd docker.io/guacamole/* docker.io/guiji2025/* docker.io/gztime/gzctf docker.io/hacdias/webdav docker.io/hagb/docker-easyconnect docker.io/hakuyyf/tensorrtx docker.io/halohub/halo docker.io/hanxi/xiaomusic docker.io/haproxytech/* docker.io/harness/* docker.io/haroldli/xiaoya-tvbox docker.io/hashicorp/* docker.io/headscale/headscale docker.io/heartexlabs/label-studio docker.io/heartexlabs/label-studio-ml-backend docker.io/hectorqin/reader docker.io/hengyunabc/arthas docker.io/henrygd/beszel docker.io/henrygd/beszel-agent docker.io/heroiclabs/nakama-pluginbuilder docker.io/hewenyulucky/* docker.io/hivemq/* docker.io/hiyouga/llamafactory docker.io/hiyouga/pytorch docker.io/hiyouga/verl docker.io/hkalexling/mango docker.io/homeassistant/* docker.io/hoppscotch/hoppscotch docker.io/hpcaitech/colossalai docker.io/hpcaitech/pytorch-cuda docker.io/hslr/sun-panel docker.io/huggingface/* docker.io/hugomods/hugo docker.io/hummingbot/hummingbot docker.io/hybridnetdev/hybridnet docker.io/hyperf/hyperf docker.io/hyperledger/* docker.io/hystax/error_pages_base docker.io/ianw/quickchart docker.io/ibmcom/* docker.io/idootop/mi-gpt docker.io/ihmily/douyin-live-recorder docker.io/imaegoo/twikoo docker.io/infiniflow/* docker.io/infmonkeys/* docker.io/innei/mx-server docker.io/instrumentisto/coturn docker.io/intel/* docker.io/intelanalytics/* docker.io/islandora/code-server docker.io/istio/* docker.io/itzg/minecraft-server docker.io/iyuucn/iyuuplus docker.io/iyuucn/iyuuplus-dev docker.io/jaegertracing/* docker.io/jasonrivers/nagios docker.io/jboss/* docker.io/jc21/nginx-proxy-manager docker.io/jeessy/ddns-go docker.io/jellyfin/* docker.io/jenkins/* docker.io/jenkinsci/* docker.io/jericx/syncclipboard-server docker.io/jetbrains/* docker.io/jettech/* docker.io/jgraph/drawio docker.io/jimmidyson/* docker.io/jitesoft/lighttpd docker.io/jitsi/* docker.io/jlesage/firefox docker.io/jlesage/handbrake docker.io/jmal/jmalcloud docker.io/john119/vlm docker.io/johngong/calibre-web docker.io/joinsunsoft/docker.ui docker.io/joplin/server docker.io/joseluisq/static-web-server docker.io/joxit/docker-registry-ui docker.io/juicedata/* docker.io/jumpserver/* docker.io/jupyter/* docker.io/jupyterhub/* docker.io/justarchi/archisteamfarm docker.io/justlikemaki/openclaw-docker-cn-im docker.io/justsong/one-api docker.io/jvmilazz0/kavita docker.io/jxxghp/* docker.io/k8scloudprovider/* docker.io/kafbat/kafka-ui docker.io/kalilinux/* docker.io/kanidm/* docker.io/karmada/* docker.io/kasmweb/* docker.io/keelhq/keel docker.io/keking/kkfileview docker.io/kennethreitz/* docker.io/kestra/kestra docker.io/keycloak/keycloak docker.io/kicbase/* docker.io/kindest/* docker.io/kiwigrid/* docker.io/klakegg/hugo docker.io/klausmeyer/docker-registry-browser docker.io/koalaman/shellcheck docker.io/koenkk/zigbee2mqtt docker.io/koide3/direct_visual_lidar_calibration docker.io/koishijs/koishi docker.io/kong/* docker.io/kserve/* docker.io/kspacekelvin/fire-python docker.io/kubeedge/* docker.io/kubeflow/* docker.io/kubeflowkatib/* docker.io/kubeflownotebookswg/* docker.io/kubeovn/kube-ovn docker.io/kuberhealthy/* docker.io/kubernetesui/* docker.io/kubeshark/* docker.io/kubeskoop/* docker.io/kubesphere/* docker.io/kubespheredev/ksv-installer docker.io/kusionstack/* docker.io/labring/kubernetes docker.io/langchain/langgraph-api docker.io/langflowai/langflow docker.io/langflowai/langflow-frontend docker.io/langfuse/* docker.io/langgenius/* docker.io/langhuihui/monibuca docker.io/laradock/* docker.io/letta/letta docker.io/lfedge/ekuiper docker.io/lfnovo/open_notebook docker.io/liangjw/kube-webhook-certgen docker.io/library/adminer docker.io/library/aerospike docker.io/library/almalinux docker.io/library/alpine docker.io/library/alt docker.io/library/amazoncorretto docker.io/library/amazonlinux docker.io/library/api-firewall docker.io/library/arangodb docker.io/library/archlinux docker.io/library/backdrop docker.io/library/bash docker.io/library/bonita docker.io/library/buildpack-deps docker.io/library/busybox docker.io/library/caddy docker.io/library/cassandra docker.io/library/centos docker.io/library/chronograf docker.io/library/cirros docker.io/library/clearlinux docker.io/library/clefos docker.io/library/clickhouse docker.io/library/clojure docker.io/library/composer docker.io/library/consul docker.io/library/convertigo docker.io/library/couchbase docker.io/library/couchdb docker.io/library/crate docker.io/library/dart docker.io/library/debian docker.io/library/docker docker.io/library/drupal docker.io/library/eclipse-mosquitto docker.io/library/eclipse-temurin docker.io/library/eggdrop docker.io/library/elasticsearch docker.io/library/elixir docker.io/library/emqx docker.io/library/erlang docker.io/library/express-gateway docker.io/library/fedora docker.io/library/flink docker.io/library/fluentd docker.io/library/friendica docker.io/library/gazebo docker.io/library/gcc docker.io/library/geonetwork docker.io/library/ghost docker.io/library/golang docker.io/library/gradle docker.io/library/groovy docker.io/library/haproxy docker.io/library/haskell docker.io/library/haxe docker.io/library/hello-world docker.io/library/hitch docker.io/library/httpd docker.io/library/hylang docker.io/library/ibm-semeru-runtimes docker.io/library/ibmjava docker.io/library/influxdb docker.io/library/irssi docker.io/library/java docker.io/library/jetty docker.io/library/jobber docker.io/library/joomla docker.io/library/jruby docker.io/library/julia docker.io/library/kapacitor docker.io/library/kibana docker.io/library/kong docker.io/library/lightstreamer docker.io/library/liquibase docker.io/library/logstash docker.io/library/mageia docker.io/library/mariadb docker.io/library/matomo docker.io/library/maven docker.io/library/mediawiki docker.io/library/memcached docker.io/library/mongo docker.io/library/mongo-express docker.io/library/monica docker.io/library/mono docker.io/library/mysql docker.io/library/nats docker.io/library/nats-streaming docker.io/library/neo4j docker.io/library/neurodebian docker.io/library/nextcloud docker.io/library/nginx docker.io/library/node docker.io/library/notary docker.io/library/odoo docker.io/library/open-liberty docker.io/library/openjdk docker.io/library/oraclelinux docker.io/library/orientdb docker.io/library/owncloud docker.io/library/percona docker.io/library/perl docker.io/library/photon docker.io/library/php docker.io/library/php-zendserver docker.io/library/phpmyadmin docker.io/library/plone docker.io/library/postfixadmin docker.io/library/postgres docker.io/library/pypy docker.io/library/python docker.io/library/r-base docker.io/library/rabbitmq docker.io/library/rakudo-star docker.io/library/redis docker.io/library/redmine docker.io/library/registry docker.io/library/rethinkdb docker.io/library/rocket.chat docker.io/library/rockylinux docker.io/library/ros docker.io/library/ruby docker.io/library/rust docker.io/library/sapmachine docker.io/library/satosa docker.io/library/sentry docker.io/library/silverpeas docker.io/library/sl docker.io/library/solr docker.io/library/sonarqube docker.io/library/spark docker.io/library/spiped docker.io/library/storm docker.io/library/swift docker.io/library/swipl docker.io/library/teamspeak docker.io/library/telegraf docker.io/library/tomcat docker.io/library/tomee docker.io/library/traefik docker.io/library/ubuntu docker.io/library/unit docker.io/library/varnish docker.io/library/vault docker.io/library/websphere-liberty docker.io/library/wordpress docker.io/library/xwiki docker.io/library/yourls docker.io/library/znc docker.io/library/zookeeper docker.io/libretranslate/libretranslate docker.io/lihualiu/sam-6d docker.io/linkease/ddnsto docker.io/linkease/desktop-ubuntu-standard-amd64 docker.io/linkease/desktop-ubuntu-standard-arm64 docker.io/linkease/desktop-ubuntu2-standard-amd64 docker.io/linkease/desktop-ubuntu2-standard-arm64 docker.io/linkease/drawio-image-export docker.io/linkease/drawio-plantuml-server docker.io/linkease/istoreduprk35xx docker.io/linkease/istoredupx86_64 docker.io/linkease/istorepanel docker.io/linkease/kspeeder docker.io/linkease/linkease docker.io/linkease/open-webui docker.io/linkease/pve docker.io/linkease/runmynas docker.io/linkease/webvirtcloud docker.io/linuxserver/* docker.io/linuxsuren/api-testing docker.io/linuxsuren/atest-ext-store-orm docker.io/livekit/* docker.io/liwei2633/gopeed docker.io/lizheming/waline docker.io/lkw199711/smanga docker.io/lldap/lldap docker.io/lmcache/* docker.io/lmsysorg/* docker.io/lobehub/* docker.io/localai/localai docker.io/localstack/localstack docker.io/loggieio/loggie docker.io/longhornio/* docker.io/louislam/* docker.io/luojiecong/index-tts docker.io/m1k1o/* docker.io/mageai/mageai docker.io/maildev/maildev docker.io/mailserver/* docker.io/manjarolinux/* docker.io/manticoresearch/manticore docker.io/maptiler/* docker.io/martialblog/limesurvey docker.io/mattermost/focalboard docker.io/mattermost/mattermost-team-edition docker.io/mauricenino/dashdot docker.io/maxkeytop/* docker.io/mayswind/ezbookkeeping docker.io/mcp/* docker.io/menci/archlinuxarm docker.io/messense/cargo-zigbuild docker.io/metabase/* docker.io/metacontrollerio/metacontroller docker.io/michaelf34/infinity docker.io/mikefarah/yq docker.io/milvusdb/* docker.io/mindsdb/mindsdb docker.io/mineru/sglang docker.io/minio/* docker.io/mintplexlabs/anythingllm docker.io/mirantis/* docker.io/mitmproxy/mitmproxy docker.io/mlikiowa/napcat-docker docker.io/mlocati/php-extension-installer docker.io/mmcauliffe/montreal-forced-aligner docker.io/moby/* docker.io/mohsinonxrm/* docker.io/mongodb/mongodb-community-server docker.io/moonrailgun/tianji docker.io/mpioperator/mpi-operator docker.io/mplatform/manifest-tool docker.io/mpromonet/webrtc-streamer docker.io/mtphotos/mt-photos docker.io/multiarch/* docker.io/mwader/webdav docker.io/myscale/myscaledb docker.io/mysql/* docker.io/n8nio/* docker.io/nacos/* docker.io/nastools/nas-tools docker.io/natsio/* docker.io/ncbi/pgap docker.io/neilpang/acme.sh docker.io/neosmemo/memos docker.io/netbirdio/* docker.io/netbox-community/netbox docker.io/netdata/netdata docker.io/networkstatic/iperf3 docker.io/neuvector/* docker.io/newfuture/ddns docker.io/newsnowlabs/dockside docker.io/nextcloud/all-in-one docker.io/nginx/* docker.io/nginxinc/* docker.io/nickfedor/watchtower docker.io/nicolaka/netshoot docker.io/nobodyiam/apollo-quick-start docker.io/nocobase/nocobase docker.io/nocodb/nocodb docker.io/nodered/node-red docker.io/nriver/trilium-cn docker.io/nsqio/nsq docker.io/nvidia/* docker.io/nyanmisaka/jellyfin docker.io/oamdev/* docker.io/oblakstudio/redisinsight docker.io/obsidiandynamics/kafdrop docker.io/oceanbase/oceanbase-ce docker.io/oceanbase/seekdb docker.io/ogarcia/archlinux docker.io/oguzpastirmaci/gpu-burn docker.io/oliver006/* docker.io/ollama/* docker.io/onlyoffice/* docker.io/openclaw/openclaw docker.io/opencloudeu/opencloud-rolling docker.io/opencoze/* docker.io/openebs/* docker.io/openeuler/* docker.io/openfga/* docker.io/opengeminidb/opengemini-server docker.io/opengrok/docker docker.io/openkruise/* docker.io/openlistteam/openlist docker.io/openmetadata/* docker.io/openmined/syft-backend docker.io/openmmlab/* docker.io/openpolicyagent/gatekeeper docker.io/openpolicyagent/opa docker.io/openresty/openresty docker.io/opensearchproject/* docker.io/opensecurity/mobile-security-framework-mobsf docker.io/openstitching/stitch docker.io/opensuse/* docker.io/openvino/* docker.io/openvpn/openvpn-as docker.io/openwhisk/* docker.io/openzipkin/* docker.io/osixia/* docker.io/osrf/* docker.io/ossrs/srs docker.io/otel/* docker.io/outlinesdev/outlines docker.io/outlinewiki/outline docker.io/oven/bun docker.io/owncloud/server docker.io/p3terx/aria2-pro docker.io/p3terx/ariang docker.io/paddlepaddle/paddle docker.io/paketobuildpacks/* docker.io/pandoc/* docker.io/paradedb/* docker.io/passbolt/passbolt docker.io/penpotapp/* docker.io/pepperlabs/peppermint docker.io/percona/* docker.io/pgautoupgrade/pgautoupgrade docker.io/pgrouting/pgrouting docker.io/pgvector/pgvector docker.io/photoprism/photoprism docker.io/phpmyadmin/* docker.io/phpswoole/swoole docker.io/pierky/bird docker.io/pingcap/* docker.io/plantuml/plantuml-server docker.io/plexinc/pms-docker docker.io/plugins/docker docker.io/podwide/cosyvoice docker.io/pointcloudlibrary/env docker.io/polardbx/polardb-x docker.io/portainer/* docker.io/postgis/postgis docker.io/postgrest/postgrest docker.io/pragkent/alidns-webhook docker.io/privoce/vocechat-server docker.io/prodrigestivill/postgres-backup-local docker.io/projectcontour/contour-authserver docker.io/projecthami/* docker.io/prom/* docker.io/prometheuscommunity/* docker.io/provectuslabs/kafka-ui docker.io/proxysql/proxysql docker.io/pymumu/smartdns docker.io/pytorch/* docker.io/qdrant/* docker.io/qdtoday/qd docker.io/qemux/qemu-docker docker.io/qingpan/rnacos docker.io/qmcgaw/ddns-updater docker.io/questdb/questdb docker.io/quickwit/* docker.io/qwenllm/* docker.io/rabbitmqoperator/cluster-operator docker.io/radondb/* docker.io/ramonvc/freegpt-webui docker.io/rancher/* docker.io/rayproject/* docker.io/rclone/* docker.io/reactivetechio/kubegres docker.io/reallibrephotos/librephotos docker.io/reallibrephotos/librephotos-frontend docker.io/reallibrephotos/librephotos-proxy docker.io/redash/* docker.io/redhat/* docker.io/redis/* docker.io/redislabs/* docker.io/rednotehilab/dots.ocr docker.io/redpandadata/console docker.io/redpandadata/kminion docker.io/redroid/redroid docker.io/reportportal/reportportal docker.io/resmoio/kubernetes-event-exporter docker.io/restatedev/restate docker.io/ribbybibby/ssl-exporter docker.io/riscv64/* docker.io/rockylinux/rockylinux docker.io/rocm/* docker.io/rolebasedgroup/rbgs-controller docker.io/romancin/tinymediamanager docker.io/rommapp/romm docker.io/rook/ceph docker.io/rsyslog/* docker.io/rucio/* docker.io/rustdesk/rustdesk-server docker.io/rustdesk/rustdesk-server-pro docker.io/rustdesk/rustdesk-server-s6 docker.io/rustfs/rustfs docker.io/rustlang/rust docker.io/rzuo/pose docker.io/sameersbn/** docker.io/savatar101/omniparse docker.io/schemahero/* docker.io/schnell18/rocketmq-dashboard docker.io/seafileltd/seafile-mc docker.io/searxng/searxng docker.io/seataio/* docker.io/secoresearch/rsync docker.io/selectdb/* docker.io/selenium/* docker.io/semgrep/* docker.io/semitechnologies/* docker.io/senthilrch/* docker.io/serengil/deepface docker.io/serversideup/* docker.io/shieldsio/shields docker.io/shingarey/foundationpose_custom_cuda121 docker.io/sickcodes/docker-osx docker.io/silkeh/clang docker.io/simonrupf/chronyd docker.io/sinamics/ztnet docker.io/sissbruecker/linkding docker.io/sj26/mailcatcher docker.io/slimerl/slime docker.io/slskd/slskd docker.io/snipe/snipe-it docker.io/snowdreamtech/frpc docker.io/snowdreamtech/frps docker.io/solace/solace-pubsub-standard docker.io/solidnerd/bookstack docker.io/sonatype/* docker.io/sonicorg/sonic-client-web-base docker.io/sonobuoy/* docker.io/soulter/astrbot docker.io/sourcegraph/* docker.io/squidfunk/* docker.io/starrocks/* docker.io/steamcmd/* docker.io/stilleshan/frpc docker.io/stilleshan/frps docker.io/stirlingtools/stirling-pdf docker.io/stnsmith/fossflow docker.io/streamnative/* docker.io/styletang/rocketmq-console-ng docker.io/subfuzion/netcat docker.io/suisuijiang/fiora docker.io/sulinggg/openwrt docker.io/supabase/* docker.io/superbench/superbench docker.io/supermanito/arcadia docker.io/superng6/aria2 docker.io/superng6/qbittorrentee docker.io/svhd/logto docker.io/swaggerapi/* docker.io/syncthing/syncthing docker.io/tabbyml/tabby docker.io/tailscale/* docker.io/taksss/php-epg docker.io/talebook/talebook docker.io/talkincode/toughradius docker.io/tarscloud/framework docker.io/tdengine/* docker.io/techblog/broadlinkmanager docker.io/technitium/dns-server docker.io/temporalio/* docker.io/tensorchord/pgvecto-rs docker.io/tensorflow/* docker.io/tensorfusion/* docker.io/teslamate/* docker.io/testcontainers/* docker.io/texlive/texlive docker.io/thanosio/* docker.io/thingsboard/tb-node docker.io/thingsboard/tb-postgres docker.io/thomassong/gpu-admission docker.io/tiangolo/* docker.io/tianon/postgres-upgrade docker.io/timberio/* docker.io/timescale/timescaledb docker.io/timonwong/prometheus-webhook-dingtalk docker.io/timothyjmiller/cloudflare-ddns docker.io/tinygo/tinygo docker.io/tinymediamanager/tinymediamanager docker.io/tnir/mysqlclient docker.io/tomkellygenetics/universc docker.io/tonistiigi/binfmt docker.io/tonistiigi/xx docker.io/traefik/whoami docker.io/trafficserver/trafficserver docker.io/treeverse/lakefs docker.io/triliumnext/notes docker.io/trinodb/trino docker.io/trustpilot/beat-exporter docker.io/tryretool/backend docker.io/tugraph/* docker.io/tunathu/bandersnatch docker.io/tusproject/tusd docker.io/tutelgroup/* docker.io/twinproduction/gatus docker.io/ubuntu/* docker.io/ultralytics/* docker.io/unclecode/crawl4ai docker.io/unityci/editor docker.io/uozi/nginx-ui docker.io/vaalacat/frp-panel docker.io/valkey/valkey docker.io/vaultwarden/server docker.io/vdsm/virtual-dsm docker.io/velero/* docker.io/verdaccio/* docker.io/verlai/* docker.io/vesoft/* docker.io/victoriametrics/* docker.io/viktorstrate/* docker.io/vllm/* docker.io/volcanosh/* docker.io/vulhub/kkfileview docker.io/wallabag/wallabag docker.io/wandb/* docker.io/weaveworks/* docker.io/webdevops/* docker.io/wechatopenai/* docker.io/wekanteam/wekan docker.io/whyour/qinglong docker.io/willfarrell/autoheal docker.io/wiremock/wiremock docker.io/wiznote/wizserver docker.io/woodpeckerci/* docker.io/wurstmeister/kafka docker.io/wurstmeister/zookeeper docker.io/xhofe/alist docker.io/xhongc/music_tag_web docker.io/xiaojusurvey/xiaoju-survey docker.io/xiaoyaliu/alist docker.io/xixihahaliu01/qanything-linux docker.io/xixihahaliu01/qanything-mac docker.io/xixihahaliu01/qanything-win docker.io/xprobe/xinference docker.io/xukuanhit/air_slam docker.io/xuxueli/xxl-job-admin docker.io/yandex/clickhouse-server docker.io/ydlhero/chatgpt-web-midjourney-proxy docker.io/yedf/dtm docker.io/yidadaa/chatgpt-next-web docker.io/ypptec/nascab docker.io/zabbix/* docker.io/zadam/trilium docker.io/zendesk/maxwell docker.io/zerotier/* docker.io/zhaojun1998/zfile-pro docker.io/zhayujie/chatgpt-on-wechat docker.io/zilliz/* docker.io/zlijingtao/neurobfuscator docker.io/zlmediakit/zlmediakit docker.io/zmisgod/iptvchecker docker.io/zmister/mrdoc docker.io/zulip/docker-zulip docker.osgeo.org/** docker.stirlingpdf.com/stirlingtools/stirling-pdf gcr.io/** ghcr.io/666ghj/bettafish ghcr.io/9001/copyparty-ac ghcr.io/aas-ee/open-web-search ghcr.io/actions/** ghcr.io/advplyr/audiobookshelf ghcr.io/ajnart/homarr ghcr.io/amamba-io/** ghcr.io/analogj/scrutiny ghcr.io/anduin2017/how-to-cook ghcr.io/anomalyco/opencode ghcr.io/apache/** ghcr.io/apple/** ghcr.io/aquasecurity/** ghcr.io/armbian/** ghcr.io/astral-sh/** ghcr.io/authzed/spicedb ghcr.io/authzed/spicedb-operator ghcr.io/autowarefoundation/autoware ghcr.io/baizeai/** ghcr.io/benc-uk/kubeview ghcr.io/berriai/litellm ghcr.io/bigcode-project/evaluation-harness ghcr.io/bigcode-project/evaluation-harness-multiple ghcr.io/biliup/caution ghcr.io/binary-husky/gpt_academic_with_latex ghcr.io/blakeblackshear/** ghcr.io/brenner-tobias/cloudflared/* ghcr.io/canner/* ghcr.io/chaos-mesh/** ghcr.io/chaosblade-io/** ghcr.io/chroma-core/chroma ghcr.io/cinnamon/kotaemon ghcr.io/cirruslabs/** ghcr.io/cloudtty/cloudshell ghcr.io/coder/** ghcr.io/codex-team/codex.docs ghcr.io/containerd/** ghcr.io/coollabsio/coolify-helper ghcr.io/coqui-ai/tts ghcr.io/corentinth/it-tools ghcr.io/cowboysysop/pytest ghcr.io/crazy-max/fail2ban ghcr.io/cross-rs/** ghcr.io/danny-avila/librechat-dev ghcr.io/daocloud/** ghcr.io/dbt-labs/dbt-core ghcr.io/decohererk/decotv ghcr.io/deepflowio/rust-build ghcr.io/dexidp/** ghcr.io/docling-project/* ghcr.io/dtzar/** ghcr.io/easytier/easytier ghcr.io/elastic/opentelemetry-demo ghcr.io/elf-io/* ghcr.io/esphome/esphome ghcr.io/estrellaxd/auto_bangumi ghcr.io/eunomia-bpf/libbpf-template ghcr.io/fatedier/frpc ghcr.io/fief-dev/fief ghcr.io/fish2018/pansou-web ghcr.io/fission/** ghcr.io/flannel-io/* ghcr.io/flexget/flexget ghcr.io/fluent/fluent-operator/* ghcr.io/freecodecamp/devdocs ghcr.io/gethomepage/homepage ghcr.io/getsentry/* ghcr.io/ggerganov/llama.cpp ghcr.io/ggml-org/llama.cpp ghcr.io/gnzsnz/ib-gateway ghcr.io/go-rod/rod ghcr.io/goauthentik/** ghcr.io/gohugoio/hugo ghcr.io/google/** ghcr.io/graalvm/* ghcr.io/grafana-operator/* ghcr.io/grafana/* ghcr.io/hassio-addons/** ghcr.io/headlamp-k8s/headlamp ghcr.io/helm/** ghcr.io/hkuds/lightrag ghcr.io/homarr-labs/homarr ghcr.io/home-assistant/** ghcr.io/home-operations/* ghcr.io/huaweiclouddeveloper/** ghcr.io/huggingface/* ghcr.io/hwameistor/** ghcr.io/imagegenius/immich ghcr.io/immich-app/** ghcr.io/imputnet/cobalt ghcr.io/infrastructure-io/** ghcr.io/inspektor-gadget/gadget/* ghcr.io/jd-opensource/** ghcr.io/jimmidyson/configmap-reload ghcr.io/joeferner/redis-commander ghcr.io/joernio/joern ghcr.io/k3d-io/** ghcr.io/k3s-io/** ghcr.io/k8snetworkplumbingwg/** ghcr.io/karakeep-app/karakeep ghcr.io/kdoctor-io/** ghcr.io/kedacore/* ghcr.io/khoj-ai/** ghcr.io/klts-io/** ghcr.io/komari-monitor/komari ghcr.io/koodo-reader/koodo-reader ghcr.io/koordinator-sh/** ghcr.io/ksmartdata/** ghcr.io/kube-vip/** ghcr.io/kubean-io/** ghcr.io/kubeflow/** ghcr.io/kyverno/** ghcr.io/labring/calico ghcr.io/labring/fastgpt ghcr.io/labring/fastgpt-sandbox ghcr.io/labring/lvscare ghcr.io/lemker/unifi-os-server ghcr.io/librespeed/speedtest ghcr.io/linuxsuren/api-testing ghcr.io/linuxsuren/atest-ext-store-orm ghcr.io/llm-d/** ghcr.io/logseq/logseq-webapp ghcr.io/lunatechlab/moontv ghcr.io/luskits/** ghcr.io/macbre/nginx-http3 ghcr.io/mastodon/mastodon ghcr.io/maybe-finance/** ghcr.io/megacloudcontainer/** ghcr.io/mellanox/** ghcr.io/mendableai/firecrawl ghcr.io/metalbear-co/** ghcr.io/metatool-ai/metamcp ghcr.io/metatube-community/metatube-server ghcr.io/microsoft/** ghcr.io/mlflow/* ghcr.io/modelcontextprotocol/inspector ghcr.io/mosn/** ghcr.io/mostlygeek/llama-swap ghcr.io/music-assistant/server ghcr.io/nicholas-fedor/watchtower ghcr.io/nvidia/** ghcr.io/open-telemetry/** ghcr.io/open-webui/open-webui ghcr.io/open-webui/pipelines ghcr.io/opencidn/** ghcr.io/openclaw/openclaw ghcr.io/openfaas/** ghcr.io/openinsight-proj/** ghcr.io/openlistteam/openlist-git ghcr.io/ot-container-kit/** ghcr.io/parkervcp/yolks ghcr.io/phioranex/openclaw-docker ghcr.io/plankanban/planka ghcr.io/project-zot/** ghcr.io/projectcontour/** ghcr.io/ptbsare/home-assistant-addons/aarch64-addon-sherpa-onnx-tts-stt ghcr.io/puppeteer/puppeteer ghcr.io/rails/** ghcr.io/rancher/** ghcr.io/rjmalagon/ollama-linux-amd-apu ghcr.io/seriousm4x/upsnap ghcr.io/siderolabs/* ghcr.io/siemens/** ghcr.io/sillytavern/sillytavern ghcr.io/songquanpeng/one-api ghcr.io/speaches-ai/speaches ghcr.io/spidernet-io/** ghcr.io/spiffe/** ghcr.io/spring-ai-alibaba/lynxe ghcr.io/sugarforever/peanut-shell ghcr.io/sumologic/** ghcr.io/suwayomi/suwayomi-server ghcr.io/suwayomi/tachidesk ghcr.io/systemed/tilemaker ghcr.io/szemeng76/lunatv ghcr.io/tangly1024/notionnext ghcr.io/timeplus-io/** ghcr.io/tiryoh/ros2-desktop-vnc ghcr.io/toeverything/affine-graphql ghcr.io/umami-software/umami ghcr.io/universaloj/** ghcr.io/vllm-project/guidellm ghcr.io/wg-easy/wg-easy ghcr.io/wzshiming/** ghcr.io/ylianst/meshcentral ghcr.io/zalando/** ghcr.io/zammad/zammad ghcr.io/zitadel/** k8s.gcr.io/** lscr.io/linuxserver/** mcr.microsoft.com/** nvcr.io/** ollama.ai/** public.ecr.aws/amazonlinux/** public.ecr.aws/appmesh/** public.ecr.aws/bitnami/* public.ecr.aws/cloudwatch-agent/** public.ecr.aws/datadog/** public.ecr.aws/docker/** public.ecr.aws/dynatrace/** public.ecr.aws/eks-distro/** public.ecr.aws/karpenter/** public.ecr.aws/lambda/** public.ecr.aws/mackerel/** public.ecr.aws/mountpoint-s3-csi-driver/** public.ecr.aws/nginx/** public.ecr.aws/ubuntu/** quay.io/aipipeline/* quay.io/argoproj/* quay.io/argoprojlabs/* quay.io/ascend/* quay.io/brancz/* quay.io/calico/* quay.io/ceph/ceph quay.io/ceph/cosi quay.io/cephcsi/cephcsi quay.io/cilium/* quay.io/coreos/* quay.io/csiaddons/k8s-sidecar quay.io/external_storage/* quay.io/frrouting/frr quay.io/go-skynet/local-ai quay.io/goswagger/* quay.io/grafana-operator/* quay.io/ibm-spectrum-scale/* quay.io/jaegertracing/* quay.io/jetstack/* quay.io/jetstack/charts/* quay.io/jupyter/* quay.io/jupyterhub/* quay.io/k0sproject/* quay.io/k8scsi/* quay.io/kata-containers/* quay.io/keycloak/keycloak quay.io/kiali/* quay.io/kiwigrid/* quay.io/kuberay/* quay.io/kubernetes-ingress-controller/* quay.io/kubernetes-sigs/* quay.io/kubespray/* quay.io/kubevirt/* quay.io/libpod/skopeo_cidev quay.io/metallb/* quay.io/minio/* quay.io/mongodb/* quay.io/nmstate/* quay.io/nuclio/* quay.io/operator-framework/* quay.io/operatorhubio/minio-operator quay.io/opstree/* quay.io/podman/stable quay.io/prometheus-operator/* quay.io/prometheus/* quay.io/prometheuscommunity/* quay.io/quarkus/* quay.io/redhat-developer/* quay.io/sameersbn/squid quay.io/skopeo/* quay.io/spotahome/* quay.io/strimzi/* quay.io/submariner/* quay.io/tigera/* registry.developers.crunchydata.com/crunchydata/pgo-deployer registry.gitlab.com/gitlab-org/** registry.gitlab.com/purelb/purelb/purelb registry.heroiclabs.com/heroiclabs/nakama registry.jujucharms.com/** registry.k8s.io/** registry.opensource.zalan.do/** registry.rocket.chat/** rocks.canonical.com/** us-central1-docker.pkg.dev/k8s-staging-images/** us-central1-docker.pkg.dev/keephq/keep/keep-api us-central1-docker.pkg.dev/keephq/keep/keep-ui us.gcr.io/k8s-artifacts-prod/** ================================================ FILE: docs/local-cache/README.md ================================================ # 部署内网缓存 ## 简介 本地缓存部署用于在内网环境中加速镜像拉取,减少对外网的依赖。通过设置一个本地镜像仓库,您可以缓存常用的镜像。 ## 部署步骤 1. **准备环境** 确保已安装 Docker 和 Docker Compose。 2. **配置 Docker Compose 文件** 创建一个 `docker-compose.yml` 文件: ```yaml services: registry: image: m.daocloud.io/docker.io/library/registry:3 restart: unless-stopped ports: - 8888:8888 command: - /etc/docker/registry/config.yml volumes: - cache-data:/var/lib/registry configs: - source: registry-config target: /etc/docker/registry/config.yml configs: registry-config: content: | version: 0.1 storage: delete: enabled: true filesystem: rootdirectory: /var/lib/registry http: addr: :8888 proxy: remoteurl: https://m.daocloud.io ttl: 2160h volumes: cache-data: {} ``` 4. **启动服务** ```bash docker compose up -d ``` 5. **配置 Docker 客户端** 在 `/etc/docker/daemon.json` 中添加以下内容: ```json { "insecure-registries": [":"] } ``` 然后重启 Docker 服务: ```bash systemctl restart docker ``` ## 用法 现在您的 `:/` 已经是 `m.daocloud.io/` 的本地缓存代理 后续就像 `m.daocloud.io` 加前缀一样, 只需要在原始镜像地址前加上 `:/` 即可。 例如,拉取 `docker.io/library/nginx:latest` 镜像,可以使用以下命令: ```bash docker pull :/docker.io/library/nginx:latest ``` ================================================ FILE: hack/badge.sh ================================================ #!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail QUICKLY="${QUICKLY:-}" cat *"_sync.log" > "sync.log" sync="$(cat "sync.log" | grep " SYNCHRONIZED: " | wc -l | tr -d ' ' || :)" unsync="$(cat "sync.log" | grep " NOT-SYNCHRONIZED: " | wc -l | tr -d ' ' || :)" sum=$(($sync + $unsync)) if [[ "${sum}" -eq 0 ]]; then echo "No sync" exit 1 fi if [[ "${QUICKLY}" == "true" ]]; then echo "https://img.shields.io/badge/Sync-${sync}%2F${sum}-blue" wget "https://img.shields.io/badge/Sync-${sync}%2F${sum}-blue" -O badge.svg else echo "https://img.shields.io/badge/Deep%20Sync-${sync}%2F${sum}-blue" wget "https://img.shields.io/badge/Deep%20Sync-${sync}%2F${sum}-blue" -O badge.svg fi ================================================ FILE: hack/correct-image.sh ================================================ #!/usr/bin/env bash function guess_image() { local image="${1}" image="${image// /}" image="${image#\/}" image="${image%\/}" if [[ -z "${image}" ]]; then return fi if [[ "${image}" == *"registry.hub.docker.com/r/"* ]]; then image="docker.io/${image##*registry.hub.docker.com\/r\/}" fi if [[ "${image}" == *"hub.docker.com/r/"* ]]; then image="docker.io/${image##*hub.docker.com\/r\/}" fi if [[ "${image}" != *"/"* ]]; then image="library/${image}" fi if [[ "${image%%/*}" != *"."* ]]; then image="docker.io/${image}" fi if [[ "${image}" != *":"* ]]; then image="${image}:latest" fi if [[ "${image}" == *"//"* ]] || [[ "${image}" == *" "* ]]; then return fi echo "${image}" } guess_image "${1}" ================================================ FILE: hack/diff-image.sh ================================================ #!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail # Output more information that is out of synchronize DEBUG="${DEBUG:-}" IMAGE1="${1:-}" IMAGE2="${2:-}" SKOPEO="${SKOPEO:-skopeo}" JQ="${JQ:-jq}" # Allow image2 to have more tags than image1 INCREMENTAL="${INCREMENTAL:-}" # Compare only tags that are in both images QUICKLY="${QUICKLY:-}" # If set, will compare the image tag patterns QUICKLY_PATTERN="${QUICKLY_PATTERN:-}" # Regexp that matches the tags FOCUS="${FOCUS:-}" # Regexp that matches the tags that needs to be skipped SKIP="${SKIP:-}" # Compare the number of tags in parallel PARALLET="${PARALLET:-0}" # Synchronize images from source to destination SYNC="${SYNC:-}" # Retry times RETRY="${RETRY:-5}" SELF="$(basename "${BASH_SOURCE[0]}")" if [[ "${DEBUG}" == "true" ]]; then echo "DEBUG: ${DEBUG}" echo "IMAGE1: ${IMAGE1}" echo "IMAGE2: ${IMAGE2}" echo "SKOPEO: ${SKOPEO}" echo "JQ: ${JQ}" echo "INCREMENTAL: ${INCREMENTAL}" echo "QUICKLY: ${QUICKLY}" echo "QUICKLY_PATTERN: ${QUICKLY_PATTERN}" echo "FOCUS: ${FOCUS}" echo "SKIP: ${SKIP}" echo "PARALLET: ${PARALLET}" echo "SYNC: ${SYNC}" echo "RETRY: ${RETRY}" fi function check() { local image1="${1:-}" local image2="${2:-}" if [[ "${image1}" == "" ]] || [[ "${image2}" == "" ]]; then echo "Compares whether the synchronization of the two images is exactly the same" echo "Need to install jq and skopeo" echo "Usage:" echo " ${SELF}: " echo " ${SELF}: " echo "Env:" echo " DEBUG=true # Output more information that is out of synchronize" echo " INCREMENTAL=true # Allow image2 to have more tags than image1" echo " QUICKLY=true # Compare only tags that are in both images" echo " QUICKLY_PATTERN= # Regexp that matches the tags" echo " FOCUS= # Regexp that matches the tags" echo " SKIP= # Regexp that matches the tags that needs to be skipped" echo " PARALLET= # Compare the number of tags in parallel" echo " SYNC=true # Synchronize images from source to destination" echo " RETRY= # Retry times" return 2 fi if [[ "${image1#*/}" =~ ":" ]]; then if [[ "${image2#*/}" =~ ":" ]]; then return 0 else echo "${SELF}: ERROR: ${image1} and ${image2} must both be full images or not be tag references" >&2 return 2 fi else if [[ "${image2#*/}" =~ ":" ]]; then echo "${SELF}: ERROR: ${image1} and ${image2} must both be full images or not be tag references" >&2 return 2 else return 0 fi fi } emptyLayer="sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" function inspect() { local image="${1:-}" local raw=$(${SKOPEO} inspect --retry-times "${RETRY}" --raw --tls-verify=false "docker://${image}") if [[ "${raw}" == "" ]]; then echo "skopeo inspect --retry-times "${RETRY}" --raw --tls-verify=false docker://${image}" >&2 echo "ERROR: Failed to inspect ${image}" >&2 return 1 fi local schemaVersion=$(echo "${raw}" | ${JQ} -r '.schemaVersion') case "${schemaVersion}" in 1) echo "${raw}" | ${JQ} -r '.fsLayers[].blobSum' | grep -v "${emptyLayer}" | tac ;; 2) local mediaType=$(echo "${raw}" | ${JQ} -r '.mediaType // "" ') if [[ "${mediaType}" == "" ]]; then if [[ "$(echo "${raw}" | ${JQ} -r '.layers | length')" -gt 0 ]]; then mediaType="layers" elif [[ "$(echo "${raw}" | ${JQ} -r '.manifests | length')" -gt 0 ]]; then mediaType="manifests" fi fi case "${mediaType}" in "layers" | "application/vnd.docker.distribution.manifest.v2+json") echo "${raw}" | ${JQ} -r '.layers[].digest' | grep -v "${emptyLayer}" ;; "manifests" | "application/vnd.docker.distribution.manifest.list.v2+json") local line=$(echo "${raw}" | ${JQ} -j '.manifests[] | .platform.architecture , " " , .platform.os , "\n"' | sort) IFS=$'\n' for args in ${line}; do local arch="${args%% *}" local os="${args##* }" echo ${args} ${SKOPEO} --override-arch "${arch}" --override-os "${os}" inspect --retry-times "${RETRY}" --config --tls-verify=false "docker://${image}" | jq -r '.rootfs.diff_ids[]' done unset IFS ;; *) echo "skopeo inspect --retry-times "${RETRY}" --raw --tls-verify=false docker://${image}" >&2 if [[ "${DEBUG}" == "true" ]]; then echo "${raw}" >&2 fi echo "${SELF}: ERROR: Unknown media type: ${mediaType}" >&2 return 2 ;; esac ;; *) echo "skopeo inspect --retry-times "${RETRY}" --raw --tls-verify=false docker://${image}" >&2 if [[ "${DEBUG}" == "true" ]]; then echo "${raw}" >&2 fi echo "${SELF}: ERROR: Unknown schema version: ${schemaVersion}" >&2 return 2 ;; esac } function copy-image() { local image1="${1:-}" local image2="${2:-}" ${SKOPEO} copy --retry-times "${RETRY}" --all --dest-tls-verify=false "docker://${image1}" "docker://${image2}" } function list-tags() { local image="${1:-}" local raw="$(${SKOPEO} list-tags --retry-times "${RETRY}" --tls-verify=false "docker://${image}" | ${JQ} -r '.Tags[]')" # Sort by string length raw=$(echo "${raw}" | awk '{print length, $0}' | sort -n | awk '{print $2}') if [[ "${FOCUS}" != "" ]]; then local skip=$(echo "${raw}" | grep -v -E "${FOCUS}") if [[ "${skip}" != "" ]]; then echo "${SELF}: SKIP: ${image} with focus: ${FOCUS}:" ${skip} >&2 fi raw="$(echo "${raw}" | grep -E "${FOCUS}" || :)" fi if [[ "${SKIP}" != "" ]]; then local skip=$(echo "${raw}" | grep -E "${SKIP}") if [[ "${skip}" != "" ]]; then echo "${SELF}: SKIP: ${image} with skip: ${SKIP}:" ${skip} >&2 fi raw="$(echo "${raw}" | grep -v -E "${SKIP}" || :)" fi echo "${raw}" } function diff-image-with-tag() { local image1="${1:-}" local image2="${2:-}" if [[ "${QUICKLY}" == "true" ]]; then local tag1="${image1##*:}" local tag2="${image2##*:}" if [[ "${tag1}" != "${tag2}" ]]; then echo "${SELF}: NOT-SYNCHRONIZED: ${image1} and ${image2} are not in synchronized" >&2 return 1 fi if [[ "${QUICKLY_PATTERN}" == "" || ("${QUICKLY_PATTERN}" != "" && "${tag1}" =~ ${QUICKLY_PATTERN}) ]]; then echo "${SELF}: SYNCHRONIZED: ${image1} and ${image2} are in synchronized" >&2 return 0 fi fi local inspect2="$(inspect ${image2})" if [[ "${inspect2}" == "" ]]; then echo "${SELF}: NOT-SYNCHRONIZED: ${image1} and ${image2} are not in synchronized, ${image2} content is empty" >&2 return 1 fi local inspect1="$(inspect ${image1})" local diff_raw=$(diff --unified <(echo "${inspect1}") <(echo "${inspect2}")) if [[ "${diff_raw}" != "" ]]; then echo "${SELF}: NOT-SYNCHRONIZED: ${image1} and ${image2} are not in synchronized" >&2 if [[ "${DEBUG}" == "true" ]]; then echo "DEBUG: image1 ${image1}:" >&2 echo "${inspect1}" >&2 echo "DEBUG: image2 ${image2}:" >&2 echo "${inspect2}" >&2 echo "diff:" >&2 echo "${diff_raw}" >&2 fi return 1 fi echo "${SELF}: SYNCHRONIZED: ${image1} and ${image2} are in synchronized" >&2 } function diff-image() { local image1="${1:-}" local image2="${2:-}" local tags1="$(list-tags ${image1})" local tags2="$(list-tags ${image2})" local diff_raw="$(diff --unified <(echo "${tags1}") <(echo "${tags2}") | grep -v -E '^---' | grep -v -E '^\+\+\+' || :)" local increase="$(echo "${diff_raw}" | grep -E '^\+' | sed 's/^\+//' || :)" local reduce="$(echo "${diff_raw}" | grep -E '^-' | sed 's/^-//' || :)" local common="${tags1}" if [[ "${increase}" != "" ]]; then common="$(echo "${common}" | grep -v -f <(echo "${increase}") || :)" fi if [[ "${reduce}" != "" ]]; then common="$(echo "${common}" | grep -v -f <(echo "${reduce}") || :)" fi if [[ "${INCREMENTAL}" == "true" ]]; then increase="" fi if [[ "${QUICKLY}" == "" ]] || [[ "${reduce}" != "" ]] || [[ "${increase}" != "" ]]; then echo "${SELF}: NOT-SYNCHRONIZED-TAGS: ${image1} and ${image2} are not in synchronized" >&2 if [[ "${DEBUG}" == "true" ]]; then echo "DEBUG: image1 ${image1}:" >&2 echo "${tags1}" >&2 echo "DEBUG: image2 ${image2}:" >&2 echo "${tags2}" >&2 echo "DEBUG: diff:" >&2 echo "${diff_raw}" >&2 fi for tag in ${reduce}; do echo "${SELF}: NOT-SYNCHRONIZED: ${image1}:${tag} and ${image2}:${tag} are not in synchronized, ${image2}:${tag} does not exist" >&2 if [[ "${SYNC}" == "true" ]]; then echo "${SELF}: SYNCHRONIZE: synchronize from ${image1}:${tag} to ${image2}:${tag}" >&2 copy-image "${image1}:${tag}" "${image2}:${tag}" >&2 fi done for tag in ${increase}; do echo "${SELF}: NOT-SYNCHRONIZED: ${image1}:${tag} and ${image2}:${tag} are not in synchronized, ${image1}:${tag} does not exist" >&2 done echo "${common}" return 1 fi echo "${SELF}: SYNCHRONIZED-TAGS: ${image1} and ${image2} are in synchronized" >&2 echo "${common}" return 0 } function wait_jobs() { local job_num=${1:-3} local perc=$(jobs -p | wc -l) while [ "${perc}" -gt "${job_num}" ]; do sleep 1 perc=$(jobs -p | wc -l) done } function main() { local image1="${1:-}" local image2="${2:-}" if [[ "${image1#*/}" =~ ":" ]]; then if [[ "${SYNC}" == "true" ]]; then echo "${SELF}: SYNCHRONIZE: synchronize from ${image1} to ${image2}" >&2 copy-image "${image1}" "${image2}" return $? fi diff-image-with-tag "${image1}" "${image2}" >/dev/null return $? fi local list=$(diff-image "${image1}" "${image2}") local notsynced=() if [[ "${PARALLET}" -eq 0 ]]; then for tag in ${list}; do diff-image-with-tag "${image1}:${tag}" "${image2}:${tag}" >/dev/null || { if [[ "${SYNC}" == "true" ]]; then echo "${SELF}: SYNCHRONIZE: synchronize from ${image1}:${tag} to ${image2}:${tag}" >&2 copy-image "${image1}:${tag}" "${image2}:${tag}" fi notsynced+=("${tag}") } done else for tag in ${list}; do wait_jobs "${PARALLET}" diff-image-with-tag "${image1}:${tag}" "${image2}:${tag}" >/dev/null || { if [[ "${SYNC}" == "true" ]]; then echo "${SELF}: SYNCHRONIZE: synchronize from ${image1}:${tag} to ${image2}:${tag}" >&2 copy-image "${image1}:${tag}" "${image2}:${tag}" fi notsynced+=("${tag}") } & done wait fi if [[ "${#notsynced[@]}" -gt 0 ]]; then echo "${SELF}: INFO: ${image1} and ${image2} are not in synchronized, there are not synchronized tags ${#notsynced[@]}: ${notsynced[*]}" >&2 return 1 fi } check "${IMAGE1}" "${IMAGE2}" main "${IMAGE1}" "${IMAGE2}" ================================================ FILE: hack/diff.sh ================================================ #!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail source "$(dirname "${BASH_SOURCE}")/helper.sh" cd "${ROOT}" DEBUG="${DEBUG:-}" INCREMENTAL="${INCREMENTAL:-}" QUICKLY="${QUICKLY:-}" SYNC="${SYNC:-}" PARALLET="${PARALLET:-0}" PARALLET_JOBS="${PARALLET_JOBS:-4}" EXCLUDE="$(helper::exclude)" declare -A DOMAIN_MAP=() function wait_jobs() { local job_num=${1:-3} local perc=$(jobs -p | wc -l) while [ "${perc}" -gt "${job_num}" ]; do sleep 1 perc=$(jobs -p | wc -l) done } function sync_with_domain() { local domain="${1}" local list=$(echo ${DOMAIN_MAP[${domain}]} | tr ' ' '\n' | shuf) for image in ${list}; do regex="${DEFAULT_REGEX}" if [[ "${image#*/}" =~ ":" ]]; then regex="${image##*:}" image="${image%:*}" fi local to="$(helper::replace_domain "${domain}/${image}")" local logfile="${to//\//_}_sync.log" echo >"${logfile}" DEBUG="${DEBUG}" SYNC="${SYNC}" QUICKLY="${QUICKLY}" INCREMENTAL="${INCREMENTAL}" PARALLET="${PARALLET}" FOCUS="${regex}" SKIP="${EXCLUDE}" ./hack/diff-image.sh "${domain}/${image}" "${to}" 2>&1 | tee -a "${logfile}" || { echo "Error: diff image ${domain}/${image} $(helper::replace_domain "${domain}/${image}")" } done } function main() { for image in $(helper::get_source); do key="${image%%/*}" val="${image#*/}" if [[ -v "DOMAIN_MAP[${key}]" ]]; then DOMAIN_MAP["${key}"]+=" ${val}" else DOMAIN_MAP["${key}"]="${val}" fi done for domain in "${!DOMAIN_MAP[@]}"; do if [[ "${PARALLET_JOBS}" -eq 0 ]]; then sync_with_domain "${domain}" else wait_jobs "${PARALLET_JOBS}" sync_with_domain "${domain}" & fi done wait } trap "trap - SIGTERM && kill 0 && echo exit..." SIGTERM SIGINT main ================================================ FILE: hack/fmt-image-match.sh ================================================ #!/usr/bin/env bash function check_match() { local image=$1 local lines=$2 for line in ${lines}; do if [[ "${line}" == *"/**" ]]; then if [[ "${image}" == "${line%\*\*}"* ]]; then return fi elif [[ "${line}" == *"/*" ]]; then if [[ "${image}" == "${line%\*}"* ]]; then if [[ "${image#"${line%\*}"}" != *"/"* ]]; then return fi fi fi done echo "${image}" } function check_match_more() { local image=$1 local lines=$2 for line in ${lines}; do if [[ "${line}" == *"/**" ]]; then if [[ "${image}" == "${line%\*\*}"* ]]; then return fi fi done echo "${image}" } function format() { local file=$1 local lines="$(cat "${file}")" for line in ${lines}; do if [[ "${line}" != *"*" ]]; then check_match "${line}" "${lines}" fi done for line in ${lines}; do if [[ "${line}" == *"/**" ]]; then echo "${line}" elif [[ "${line}" == *"/*" ]]; then check_match_more "${line}" "${lines}" fi done } export LC_ALL=C file=$1 format "${file}" | sort -u | grep -v '^$' >$1.tmp && mv $1.tmp $1 ================================================ FILE: hack/fmt-image.sh ================================================ #!/usr/bin/env bash function filter_docker_library() { while read -r line; do if [[ $line =~ ^docker\.io/[^/]*$ ]]; then echo "docker.io/library/${line#docker.io/}" else echo "${line}" fi done } function filter_k8s_old() { while read -r line; do if [[ $line =~ ^k8s\.gcr\.io/.*$ ]]; then echo "registry.k8s.io/${line#k8s.gcr.io/}" else echo "${line}" fi done } cat $1 | filter_docker_library | filter_k8s_old >$1.tmp && mv $1.tmp $1 ================================================ FILE: hack/fmt.sh ================================================ #!/usr/bin/env bash export LC_ALL=C cat $1 | sort -u | grep -v '^$' >$1.tmp && mv $1.tmp $1 ================================================ FILE: hack/helper.sh ================================================ #!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail ROOT="${ROOT:-$(dirname "${BASH_SOURCE}")/..}" DEFAULT_REGEX='^([a-z]+-)?[a-z]*[0-9]+(\.[0-9]+){1,2}' SKOPEO="${SKOPEO:-skopeo}" ROOT=$(realpath ${ROOT}) DOMAIN="${DOMAIN:-m.daocloud.io}" function helper::replace_domain() { local domain="${1}" echo "${DOMAIN}/${domain}" } function helper::get_source() { local source="${1:-mirror.txt}" cat "${source}" | tr -d ' ' | grep -v -E '^$' | grep -v -E '^#' } function helper::exclude() { local exclude="${1:-exclude.txt}" local tmp=$(cat "${exclude}" | tr -d ' ' | grep -v -E '^$' | grep -v -E '^#' | tr '\n' '|') echo "${tmp%|}" } ================================================ FILE: hack/merge-mirror.sh ================================================ #!/usr/bin/env bash base_list="${1}" used_list="${2}" used_top="${3:-100}" function used_top() { cat "${used_list}" | head -n "${used_top}" } function intersection_used() { sort "${base_list}" "${used_list}" | uniq -d } function fixed_docker() { grep "^docker\.io/library/" "${base_list}" grep "^docker\.io/library/" "${used_list}" } function fixed_k8s() { grep "^registry\.k8s\.io/" "${base_list}" grep "^registry\.k8s\.io/" "${used_list}" } function fixed_istio() { grep "^docker\.io/istio/" "${base_list}" grep "^docker\.io/istio/" "${used_list}" } cat <(used_top) \ <(intersection_used) \ <(fixed_docker) \ <(fixed_k8s) | sort | uniq -u ================================================ FILE: hack/stats-not-sync.sh ================================================ #!/usr/bin/env bash cat $1 | grep NOT-SYNCHRONIZED | awk '{print $3}' | grep ':' | tr ':' ' ' | awk '{print $1}' | uniq -c | sort -nrk 1 ================================================ FILE: hack/verify-allows.sh ================================================ #!/usr/bin/env bash file=$1 image=$2 function check_allows() { local file=$1 local image=$2 if [[ "${image}" == *":" ]]; then return 1 fi while read line; do if [[ "${line}" == *"**" ]]; then if [[ "${image}" == "${line%\*\*}"* ]]; then return 0 fi elif [[ "${line}" == *"*" ]]; then if [[ "${image}" == "${line%\*}"* ]]; then if [[ "${image#"${line%\*}"}" != *"/"* ]]; then return 0 fi fi elif [[ "${line}" == "${image%\:*}" ]]; then return 0 fi done <"${file}" return 1 } check_allows "${file}" "${image}" ================================================ FILE: hack/verify-docker-prefix.sh ================================================ #!/usr/bin/env bash file=$1 cp ${file} ${file}.bak cat ${file} | grep docker.io | grep library | sed 's#docker.io/library/#docker.io/#' >>${file}.bak cat ${file} | grep -e "docker\.io/\w\+:\|docker\.io/\w\+$" | sed 's#docker.io/#docker.io/library/#' >>${file}.bak $(dirname "${BASH_SOURCE}")/fmt.sh ${file}.bak result=$(diff ${file} ${file}.bak) if [[ "${result}" != "" ]]; then echo "Usually docker.io/* and docker.io/library/* appear in pairs " echo "Please run following command to fix the issue:" echo "cat <> ${file}" echo "${result}" | grep "^>" | sed 's/^>\s\+//' echo "EOF" echo "./hack/fmt.sh ${file}" exit 1 fi rm ${file}.bak ================================================ FILE: hack/verify-fmt-image.sh ================================================ #!/usr/bin/env bash export LC_ALL=C cp $1 $1.bak $(dirname "${BASH_SOURCE}")/fmt-image.sh $1.bak diff -c $1 $1.bak && rm $1.bak ================================================ FILE: hack/verify-fmt.sh ================================================ #!/usr/bin/env bash export LC_ALL=C cp $1 $1.bak $(dirname "${BASH_SOURCE}")/fmt.sh $1.bak diff -c $1 $1.bak && rm $1.bak ================================================ FILE: hack/verify-image-match.sh ================================================ #!/usr/bin/env bash export LC_ALL=C cp $1 $1.bak $(dirname "${BASH_SOURCE}")/fmt-image-match.sh $1.bak diff -c $1 $1.bak && rm $1.bak ================================================ FILE: hack/verify-image.sh ================================================ #!/usr/bin/env bash file=$1 patch_url=$2 list="" if [[ "${patch_url}" == "" ]]; then list=$(cat "${file}") else cp "${file}" "${file}.bak" git apply -R <(curl -fsSL "${patch_url}") || : list=$(diff --unified "${file}" "${file}.bak" | grep '^+\w' | sed 's/^+//' || :) fi failed=() for image in ${list}; do image="${image%%\:*}" echo "Checking image: ${image}" raw=$(skopeo list-tags --no-creds --tls-verify=false --retry-times 3 "docker://${image}") if [[ $? -ne 0 ]]; then failed+=("not found ${image}") echo "Not found ${image}" continue fi if [[ $(echo "${raw}" | jq '.Tags | length') -eq 0 ]]; then failed+=("found ${image} but no tags") echo "Found ${image} but no tags" echo "${raw}" continue fi done if [[ ${#failed[@]} -ne 0 ]]; then echo "Failed images:" for image in "${failed[@]}"; do echo " ${image}" done exit 1 fi ================================================ FILE: hack/verify-k8s-prefix.sh ================================================ #!/usr/bin/env bash file=$1 result="$(cat ${file} | grep k8s.gcr.io/)" if [[ "${result}" != "" ]]; then echo "Usually registry.k8s.io/* instead of k8s.gcr.io/*" echo "Please run following command to fix the issue:" echo "cat ${file} | sed 's#k8s.gcr.io/#registry.k8s.io/#' >${file}.bak" echo "mv ${file}.bak ${file}" echo "./hack/fmt.sh ${file}" exit 1 fi