🛠️

devcontainerのビルドが失敗する原因がGitHubのレートリミットだった話

2025/02/28に公開

TL;DR

  • 会社や大学でログアウト状態だとGitHubのレートリミットに引っかかってAPIが使用できない
  • 今回の場合、APIに最新バージョンの取得をする際に404を返されてビルドエラー
  • Dockerfileの中でlatest等のバージョン指定した場合、APIを使用してないか確認する
  • Git (from source) (git)にもGitHub APIを使用する部分があるため注意が必要

はじめに

皆さんは会社や大学でdeccontainerを活用していますか? 私はないと作業にならないかもしれません...。そんな中、会社や大学でコンテナのビルドに失敗する現象に遭遇しました。今回は会社や大学といった複数の人間とネットワークを共有している際に、発生したビルドエラーに関しての解決メモとなります。

使用していたコンフィグ

1.下記リポジトリで公開されているコンフィグを一部変更して使用

https://github.com/nafnix/devcontainers-templates

devcontainer.json
{
  "name": "Hugo & pnpm",

  "build": {
    "dockerfile": "Dockerfile"
  },
  "remoteUser": "vscode"
}
Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu
ARG DEBIAN_FRONTEND=noninteractive

ARG VARIANT=hugo_extended
ARG VERSION=latest

RUN case ${VERSION} in \
    latest) \
    export VERSION=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') ;;\
    esac && \
    echo ${VERSION} && \
    case $(uname -m) in \
    aarch64) \
    export ARCH=ARM64 ;; \
    *) \
    export ARCH=64bit ;; \
    esac && \
    echo ${ARCH} && \
    wget -O ${VERSION}.tar.gz https://github.com/gohugoio/hugo/releases/download/v${VERSION}/${VARIANT}_${VERSION}_Linux-${ARCH}.tar.gz && \
    tar xf ${VERSION}.tar.gz && \
    mv hugo /usr/bin/hugo

EXPOSE 1313

2.下記コンフィグが含まれるコンテナ

devontainer.json
"features": {
        "ghcr.io/devcontainers/features/common-utils:2": {
            "installZsh": "true",
            "username": "vscode",
            "userUid": "1000",
            "userGid": "1000",
            "upgradePackages": "true"
        },
        "ghcr.io/devcontainers/features/git:1": {
            "version": "latest",
            "ppa": "false"
        }
  },

起こったこと&思ったこと

  • コンテナのビルドに失敗する
  • 稀(時間帯?)に成功したり、自宅などネットワークを変えるとコンテナのビルドが可能
  • コンフィグが間違っているわけではない
  • 会社と大学で発生するため、複数の人間とネットワークを共有することに問題?

ログを調査する

1.のコンフィグの場合

VSCodeではコンテナのビルドに失敗した際、ログを表示してくれます。(非常に便利ですね)

> [dev_container_auto_added_stage_label 2/2] RUN case latest in     latest)     export VERSION=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') ;;    esac &&     echo latest &&     case $(uname -m) in     aarch64)     export ARCH=ARM64 ;;     *)     export ARCH=64bit ;;     esac &&     echo ${ARCH} &&     wget -O latest.tar.gz https://github.com/gohugoio/hugo/releases/download/vlatest/hugo_extended_latest_Linux-${ARCH}.tar.gz &&     tar xf latest.tar.gz &&     mv hugo /usr/bin/hugo:
0.347 
0.348 64bit
0.352 --2025-02-28 05:35:29--  https://github.com/gohugoio/hugo/releases/download/v/hugo_extended__Linux-64bit.tar.gz
0.354 Resolving github.com (github.com)... 20.27.177.113
0.360 Connecting to github.com (github.com)|20.27.177.113|:443... connected.
[2025-02-28T05:35:30.311Z] 
0.400 HTTP request sent, awaiting response... 404 Not Found
0.887 2025-02-28 05:35:30 ERROR 404: Not Found.
0.887

どうやらGitHubのAPIにバージョンを問い合わせしたけど、404が返ってきているみたいです。
どういう理由で404が返ってきているのか実際にブラウザでアクセスしてみましょう。

{"message":"API rate limit exceeded for 環境のIPアドレス (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)","documentation_url":"https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting"}

レートリミットにより、404が返ってきているようです。

2.のコンフィグの場合

1.同様にビルド時のログから調査しましょう。

 > [dev_containers_target_stage 5/5] RUN --mount=type=bind,from=dev_containers_feature_content_source,source=git_1,target=/tmp/build-features-src/git_1     cp -ar /tmp/build-features-src/git_1 /tmp/dev-container-features  && chmod -R 0755 /tmp/dev-container-features/git_1  && cd /tmp/dev-container-features/git_1  && chmod +x ./devcontainer-features-install.sh  && ./devcontainer-features-install.sh  && rm -rf /tmp/dev-container-features/git_1:
0.356 ===========================================================================
0.356 Feature       : Git (from source)
0.356 Description   : Install an up-to-date version of Git, built from source as needed. Useful for when you want the latest and greatest features. Auto-detects latest stable version and installs needed dependencies.
0.356 Id            : ghcr.io/devcontainers/features/git
0.356 Version       : 1.3.2
0.356 Documentation : https://github.com/devcontainers/features/tree/main/src/git
0.356 Options       :
0.356     VERSION="latest"
0.356     PPA="false"
0.356 ===========================================================================
0.384 find: '/var/lib/apt/lists/*': No such file or directory
0.385 Running apt-get update...
1.184 Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
1.900 Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
2.420 Get:3 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [2649 kB]
2.506 Get:4 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
2.754 Get:5 http://archive.ubuntu.com/ubuntu jammy-backports InRelease [127 kB]
3.008 Get:6 http://archive.ubuntu.com/ubuntu jammy/multiverse amd64 Packages [266 kB]
3.206 Get:7 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 Packages [164 kB]
3.287 Get:8 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages [17.5 MB]
3.636 Get:9 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [1235 kB]
3.721 Get:10 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages [45.2 kB]
3.723 Get:11 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [3688 kB]
4.666 Get:12 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages [1792 kB]
4.713 Get:13 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [2957 kB]
4.791 Get:14 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [1533 kB]
4.830 Get:15 http://archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [53.3 kB]
4.832 Get:16 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [3830 kB]
4.931 Get:17 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [35.2 kB]
4.931 Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [81.4 kB]
5.576 Fetched 36.5 MB in 6s (6395 kB/s)
5.576 Reading package lists...
6.369 Reading package lists...
7.181 Building dependency tree...
7.099 Reading state information...
7.328 build-essential is already the newest version (12.9ubuntu3).
7.328 gettext is already the newest version (0.21-4ubuntu4).
7.328 ca-certificates is already the newest version (20240203~22.04.1).
7.328 curl is already the newest version (7.81.0-1ubuntu1.20).
7.328 libcurl4-openssl-dev is already the newest version (7.81.0-1ubuntu1.20).
7.328 libexpat1-dev is already the newest version (2.4.7-1ubuntu0.5).
7.328 tar is already the newest version (1.34+dfsg-1ubuntu0.1.22.04.2).
7.328 zlib1g-dev is already the newest version (1:1.2.11.dfsg-2ubuntu9.2).
7.328 The following additional packages will be installed:
7.329   libssl3
7.333 Suggested packages:
7.333   libssl-doc
7.356 The following packages will be upgraded:
7.356   libssl-dev libssl3
7.770 2 upgraded, 0 newly installed, 0 to remove and 33 not upgraded.
7.770 Need to get 4281 kB of archives.
7.770 After this operation, 1024 B of additional disk space will be used.
7.770 Get:1 http://archive.ubuntu.com/
[2025-02-28T06:06:57.598Z] ubuntu jammy-updates/main amd64 libssl-dev amd64 3.0.2-0ubuntu1.19 [2376 kB]
9.526 Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 libssl3 amd64 3.0.2-0ubuntu1.19 [1905 kB]
10.67 Preconfiguring packages ...
10.73 Fetched 4281 kB in 2s (1885 kB/s)
10.75 (Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 21916 files and directories currently installed.)

10.82 Preparing to unpack .../libssl-dev_3.0.2-0ubuntu1.19_amd64.deb ...

10.83 Unpacking libssl-dev:amd64 (3.0.2-0ubuntu1.19) over (3.0.2-0ubuntu1.18) ...

11.15 Preparing to unpack .../libssl3_3.0.2-0ubuntu1.19_amd64.deb ...

11.16 Unpacking libssl3:amd64 (3.0.2-0ubuntu1.19) over (3.0.2-0ubuntu1.18) ...

11.24 Setting up libssl3:amd64 (3.0.2-0ubuntu1.19) ...

11.31 Setting up libssl-dev:amd64 (3.0.2-0ubuntu1.19) ...

11.32 Processing triggers for libc-bin (2.35-0ubuntu3.8) ...

11.52 Invalid git version: latest
11.52 ERROR: Feature "Git (from source)" (ghcr.io/devcontainers/features/git) failed to install! Look at the documentation at https://github.com/devcontainers/features/tree/main/src/git for help troubleshooting this error.

どうやらgitのバージョンを取得しようとして失敗したみたいです。
コンテナにgitを追加するfeatureのソースコードは、以下のリポジトリに存在するので実際にソースを見てみましょう。

https://github.com/devcontainers/features/tree/main/src/git

https://github.com/devcontainers/features/blob/13521bc5efd79a1cea7da58df59a523243b3cea6/src/git/install.sh#L283-L297

指定したバージョンがlatestの場合、GitHubのAPIにバージョン一覧を問い合わせる挙動となっていますね。APIの返答を確認しましたが、1.のコンフィグの場合同様、レートリミットによる404でした。

レートリミットに関して

GitHubの公式ドキュメントにもあるように、非ログイン状態でのレートリミットは60リクエスト/時です。 会社や大学などの共有ネットワークでは超過する可能性があります。

https://docs.github.com/ja/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#primary-rate-limit-for-unauthenticated-users

解決方法(回避方法)

latest指定をやめる

主に1.のコンフィグの場合、GitHubのAPIに最新バージョンを取得しに行くのがエラーの原因なのでDockerfileに明示的にバージョンを指定してしまえば問題ありません。

Dockerfile
-ARG VERSION=latest
+ARG VERSION=0.142.0

Git (from source) (git)のfeatureを使う場合、PPAを使用する

基となるコンテナイメージがUbuntu系に限られた方法ですが、PPAからgitの最新版をを入手するようにすることでGitHubのAPIを使用しなくなります。コンテナイメージがUbuntu系でない場合はこの手法は使えません。

devcontainer.json
"ghcr.io/devcontainers/features/git:1": {
    "version": "latest",
-   "ppa": "false"
+   "ppa": "true"
}

参照
https://github.com/devcontainers/features/tree/main/src/git#options

解決方法は以上となります。
今回の解決方法は、Tokenなどを使用して"レートリミットを解消する"といった方法ではなく、GitHubのAPIを使用しないようにする方向での解決を行いました。この方法ではGitHubのTokenを用意できない人がコンテナをビルドしたい場合に非常に有効です。
(私自身、Tokenを使用できない共有PCでコンテナをビルドする際に詰まったため)

Discussion