解決docker buildx「找不到本地鏡像」的核心問題

docker-container 模式的 Builder 是一個獨立容器,它抓不到你主機 docker images 裡的 redis-base:1.0

解決方案 A:將基礎鏡像導入 Builder (推薦)
先將 redis-base:1.0 存成 tar 包,再讓 Builder 讀取它(或在同一個 Buildx 任務中完成):
redis-base:1.0 是你自己剛編譯出來的,請確保它是用同一個 Builder 編譯且存在於該 Builder 的 cache 中。

解決方案 B:重建 Builder 並強制使用主機網路 (解決 DNS/Timeout)
# 1. 刪除舊的
docker buildx rm mybuilder

# 2. 創建一個能穿透防火牆、支持跨平台的 Builder
docker buildx create --use --name mybuilder \
  --driver-opt network=host \
  --buildkitd-flags '--allow-insecure-entitlement network.host'

# 3. 初始化
docker buildx inspect --bootstrap

正確執行跨平台編譯

在執行時,加上 --build-arg 或確保 FROM 鏡像在遠端倉庫存在。如果 redis-base:1.0 只在本地,請先將其推送到一個私有倉庫(如 Registry 或 Harbor),否則 Builder 永遠找不到它。
如果你現在手頭只有本地的 redis-base:1.0 鏡像,請執行以下操作:
  1. 啟動一個本地臨時倉庫
    docker run -d -p 5000:5000 --name registry registry:2
    docker tag redis-base:1.0 localhost:5000/redis-base:1.0
    docker push localhost:5000/redis-base:1.0
    
  2. 修改 Dockerfile 第一行
    FROM localhost:5000/redis-base:1.0
  3. 次編譯(使用 --network=host 讓 Builder 能連到 localhost:5000):
    docker buildx build --platform linux/arm64 -t redis-custom:arm64 --network=host --load .

    因為 coturn-custom 是基於 rockylinux:9 構建的,要解決這個問題,必須確保基礎鏡像編譯過程都支援多平台。

    請按照以下步驟修正:

    1. 確保基礎鏡像支援 ARM64

    如果你的 Dockerfile 第一行是 FROM rockylinux:9,請先在主機確認是否能拉取到 ARM64 版本:
    docker pull --platform linux/arm64 rockylinux:9
    

    2. 使用 Buildx 一次性完成多平台構建並推送到本地庫

    不要先 buildtag,直接讓 Buildx 同時處理兩個平台並推送到你的 registry
    # 在 coturn 的目錄執行
    docker buildx build \
      --platform linux/amd64,linux/arm64 \
      -t localhost:5000/coturn-custom:1.0 \
      --push \
      --network=host \
      --provenance=false --sbom=false \
      .
    
    這步會解決 InvalidBaseImagePlatform,因為它會同時產生兩個平台的鏡像並存入倉庫。

    3. 驗證倉庫中的多平台支持

    推送完成後,檢查是否真的有兩個平台:
    docker buildx imagetools inspect localhost:5000/coturn-custom:1.0
    
    預期結果: 你應該會在 Platforms 看到 linux/amd64linux/arm64

    如果你想讓 Manifest 乾淨一點,或者想清理舊的數據,可以從以下兩個方向處理:

    1. 重新構建時關閉 Attestations(讓 Manifest 變簡潔)

    如果你不需要這些元數據,可以在 build 指令中加入 --provenance=false --sbom=false,這樣 imagetools inspect 就只會看到 amd64arm64 兩個平台。

    docker buildx build \

      --platform linux/amd64,linux/arm64 \
      -t localhost:5000/redis-base:1.0 \
      --push --network=host \
      --provenance=false --sbom=false .
    
    2. 清理本地 Registry 中的舊數據
    Docker 自帶的 registry:2 默認不支援自動刪除,它只會不斷堆積。要徹底清理 localhost:5000 裡的舊數據,最快的方式是:
      1. 直接刪除並重建 Registry 容器(最簡單,但會清空裡面所有鏡像):
        docker rm -f registry
        docker run -d -p 5000:5000 --name registry registry:2
        
      2. 或者清理 Buildx 本地的緩存(這可以釋放編譯機器的空間):
        docker buildx prune -f
        
    目前狀態確認
    你的 imagetools inspect 結果顯示 linux/arm64 已經正確存在了(digest d281cdb2...)。
    現在你可以直接回到你的 redis-custom 目錄執行最終編譯了:
    docker buildx build \
      --platform linux/arm64 \
      -t redis-custom:arm64 \
      --network=host \
      --load .
    

 

版权声明:
作者:yxbinghe
链接:https://www.zhanhao.ch/?p=673
来源:ice.99
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>