Docker 레이트 리밋 오류가 발생했습니다

./launcher rebuild app을 실행하면 다음과 같은 오류가 발생합니다:

x86_64 아키텍처 감지됨.

경고: Discourse 기본 이미지를 다운로드하는 과정을 시작합니다.
네트워크 속도에 따라 몇 분에서 1시간까지 소요될 수 있습니다.

잠시만 기다려 주세요.

데몬에서 오류 응답: toomanyrequests: 가져오기(pull) 속도 제한에 도달했습니다. 인증 및 업그레이드를 통해 제한을 높일 수 있습니다: Docker Hub usage and limits | Docker Docs
데몬에서 오류 응답: toomanyrequests: 가져오기(pull) 속도 제한에 도달했습니다. 인증 및 업그레이드를 통해 제한을 높일 수 있습니다: Docker Hub usage and limits | Docker Docs
로컬에서 이미지 'discourse/base:2.0.20241203-0251’을(를) 찾을 수 없음
docker: 데몬에서 오류 응답: toomanyrequests: 가져오기(pull) 속도 제한에 도달했습니다. 인증 및 업그레이드를 통해 제한을 높일 수 있습니다: Docker Hub usage and limits | Docker Docs.
'docker run --help’를 참조하십시오.
Docker 설치가 올바르게 작동하지 않습니다.

참고: Troubleshoot docker installation issues

사이트는 정상적으로 작동하고 있지만, 일부 플러그인을 설치해야 합니다. app.yml 파일에 변경 사항을 가하기 전에 앱을 깨끗하게 재빌드(rebuild)하려고 합니다. 조언이 있을까요?

*** 문제 해결 방법 ***
제 서버는 IPv6를 사용 중이었습니다. DockerHub는 속도 제한을 결정하기 위해 더 큰 블록의 IPv6를 사용합니다. 제 서버가 Digital Ocean에 호스팅되어 있어 더 큰 서버 그룹에 포함되어 속도 제한을 초과하고 있었습니다. IPv6를 끄자 모든 것이 정상으로 돌아왔습니다. Digital Ocean 서버에서 IPv6를 끄는 방법은 다음과 같습니다.

10시간 후에 다시 시도해 보았습니다. 결과는 동일합니다. Docker Hub의 시간 창(time window)은 6시간입니다.

이것은 지난 40일 이내에 설치된 깨끗한(clean) Discourse 설치 환경입니다. 현재 플러그인이나 커스터마이징은 적용되어 있지 않습니다. 따라서…

Discourse Hub는 인증 정보(credential) 측면에서 어떻게 접근됩니까? 익명(Anonymous)으로 접근하는 것입니까? 아니면 Discourse 로그인으로 접근하는 것입니까?

rate limiter를 우회하기 위해 개인용 Discourse Hub 인증 정보를 설정할 수 있는 방법이 있습니까?

감사합니다.

유용할 수 있는 테스트 중 하나는 아주 작은 hello world 이미지입니다:

/var/discourse# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete 
Digest: sha256:5b3cc85e16e3058003c13b7821318369dad01dac3dbb877aac3c28182255c724
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

동일한 결과:

docker run hello-world
Unable to find image ‘hello-world:latest’ locally
docker: Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: Docker Hub usage and limits | Docker Docs.
See ‘docker run --help’.

두 개의 Discourse 포럼(서버/IP가 각각 다름)에서 이 문제를 겪었습니다.

Please be patient

Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Unable to find image 'discourse/base:2.0.20241203-0251' locally
docker: Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit.
See 'docker run --help'.
Your Docker installation is not working correctly

See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam

Docker가 돈을 내도록 강요하려는 갑작스러운 제한 조치가 아니기를 바랍니다.

이것은 Docker의 AI 어시스턴트가 말하는 내용이지만, 새로운 속도 제한은 3월 1일에야 적용될 예정이라고 합니다. (재구축 중에 Discourse가 10회 이상의 pulls를 수행한다면, 이는 사용자에게 영향을 미칠 가능성이 높습니다. 수정: 이미 10회로 제한되어 있는 것으로 보입니다.)

제공된 지식 출처에 따르면, Docker가 최근 속도 제한 정책을 변경한 것으로 보입니다. 제가 알려드릴 수 있는 내용은 다음과 같습니다:

Docker는 2025년 3월 1일부터 시행되는 Docker Hub의 새로운 사용량 및 속도 제한을 발표했습니다. Docker Hub 사용량 및 속도 제한 문서에 따르면:

  1. 인증되지 않은 사용자의 경우, IP 주소당 시간당 10회까지 pulls가 가능합니다.
  2. 인증된 Docker Personal 사용자의 경우, 시간당 40회까지 pulls가 가능합니다.
  3. 인증된 Docker Pro, Team, Business 사용자의 경우, pulls 속도 제한이 없습니다.

또한, Docker는 구독 등급에 기반한 새로운 pulls 한도를 도입했습니다:

  • Docker Personal: 시간당 40회
  • Docker Pro: 월 25,000회
  • Docker Team: 월 100,000회
  • Docker Business: 월 1,000,000회

이러한 변경 사항은 2020년 5월 14일자 Docker Hub 릴리스 노트에서 발표되었으며, 해당 노트에는 다음과 같이 명시되어 있습니다:

“Docker는 Docker Hub의 다운로드 및 pull 요청에 대한 다운로드 속도 제한을 활성화했습니다. 이는 지정된 시간 내에 사용자가 다운로드할 수 있는 객체 수를 제한합니다.”

이러한 한도에 도달하는 것을 피하려면 다음을 수행할 수 있습니다:

  1. 아직 인증하지 않았다면 pulls를 인증하십시오.
  2. 더 높은 한도가 필요하면 유료 플랜으로 업그레이드하십시오.
  3. 캐싱 사용 및 pull 전략 최적화 등 Docker Hub 사용량 관리 모범 사례를 구현하십시오.

여러 사이트에서 속도 제한을 경험하고 있다면, 서로 다른 서비스의 한도에 도달했거나 IP 주소가 공유되어 누적 속도 제한이 발생한 것일 수 있습니다. 그러나 제공된 정보는 구체적으로 Docker Hub의 속도 제한에 관한 것입니다.

문제가 제 시스템만의 문제가 아니라는 것을 확인해 주셔서 감사합니다.

관리자 화면에서 Docker 매니저와 Discourse 시스템 수준을 모두 문제 없이 업그레이드할 수 있었습니다. 하지만 런처 리빌드를 실행하려고 할 때마다 레이트 리밋 오류가 발생합니다.

레이트 리미트가 적용된 터미널의 포럼에서 대시보드를 통한 업데이트가 정상적으로 작동하는 것으로 보입니다.

어디에 호스팅되어 있나요?

DigitalOcean에 이 문제에 대한 지원 케이스를 열었고, 해당 문제가 확인되었음을 통보받았습니다. 다만 IPv6가 활성화된 Droplet에만 해당됩니다.

Docker Hub는 IPv6의 경우 단일 IP가 아니라 네트워크 범위를 기준으로 속도 제한을 적용합니다(비공개 사용자 경우 6시간당 100회 제한이 대형 VPS 제공업체에서 거의 즉시 소진됩니다).

IPv6를 비활성화하면 다시 빌드할 수 있어야 합니다.

제 사이트는 IPv6가 활성화된 DigitalOcean에 있습니다.

같은 문제라면, 다른 서비스에 IPv6이 필요하지 않다면 DO 웹 관리 콘솔에서 IPv6을 비활성화해 보세요 (드롭릿을 재부팅하지 않고도 설정할 수 있다고 생각합니다) 그리고 다시 시도해 보세요.

Droplet 설정에서 IPv6를 끄는 방법을 찾지 못했지만, 나중에 다시 자세히 살펴보겠습니다.


대시보드에서 업데이트가 정상적으로 작동한다고 생각했지만, 그건 제 착각이었습니다. 하나는 성공했지만, 다른 하나는 중간에 충돌했습니다. 현재 대시보드에서는 업데이트가 필요하다고 표시됩니다:

수정: Droplet을 재부팅한 후 해당 메시지가 사라졌습니다.

discourse-2

하지만 해당 항목을 클릭하면 모든 것이 최신 상태라고 표시되는 페이지로 이동합니다:

다음은 오류 메시지입니다:

...[@embroider/webpack]
...[@embroider/webpack]
...[@embroider/webpack]
...[@embroider/webpack]
undefined
 ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL  Command was killed with SIGKILL (Forced termination): ember build -prod
Docker Manager: FAILED TO UPGRADE
#<RuntimeError: RuntimeError>
/var/www/discourse/plugins/docker_manager/lib/docker_manager/upgrader.rb:211:in `run'
/var/www/discourse/plugins/docker_manager/lib/docker_manager/upgrader.rb:112:in `upgrade'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:19:in `block in <main>'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:6:in `fork'
/var/www/discourse/plugins/docker_manager/scripts/docker_manager_upgrade.rb:6:in `<main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/commands/runner/runner_command.rb:41:in `load'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/commands/runner/runner_command.rb:41:in `block in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.1.5/lib/active_support/execution_wrapper.rb:92:in `wrap'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/commands/runner/runner_command.rb:40:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/thor-1.3.2/lib/thor/command.rb:28:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/thor-1.3.2/lib/thor/invocation.rb:127:in `invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/command/base.rb:178:in `invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/thor-1.3.2/lib/thor.rb:538:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/command/base.rb:73:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/command.rb:71:in `block in invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/command.rb:149:in `with_argv'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/command.rb:69:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.1.5/lib/rails/commands.rb:18:in `<main>'
/usr/local/lib/ruby/3.3.0/bundled_gems.rb:74:in `require'
/usr/local/lib/ruby/3.3.0/bundled_gems.rb:74:in `block (2 levels) in replace_require'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
bin/rails:18:in `<main>'
Spinning up 1 Unicorn worker(s) that were stopped initially

Digital Ocean 서버에서 IPv6를 끄면 문제가 해결되었습니다: IPv6를 끄는 방법에 대한 Digital Ocean의 지침은 다음과 같습니다.