재구축 중 오류: registry.yarnpkg.com ESOCKETTIMEDOUT

저는 https://forum.embeetle.com에서 자체 호스팅된 Discourse 인스턴스를 운영하고 있습니다.

어제 원클릭 브라우저 업그레이드가 실패하여 서버에 로그인한 후 ./launcher rebuild app을 시도했습니다.

이것도 실패했으며, 다음과 같은 오류가 발생했습니다:

I, [2024-08-01T20:46:09.837292 #1]  INFO -- : 
I, [2024-08-01T20:46:09.837631 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'yarn install --frozen-lockfile && yarn cache clean'
warning Resolution field "unset-value@2.0.1" is incompatible with requested version "unset-value@^1.0.0"
error Error: https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz: ESOCKETTIMEDOUT
    at ClientRequest.<anonymous> (/usr/share/yarn/lib/cli.js:142037:19)
    at Object.onceWrapper (node:events:631:28)
    at ClientRequest.emit (node:events:517:28)
    at TLSSocket.emitRequestTimeout (node:_http_client:847:9)
    at Object.onceWrapper (node:events:631:28)
    at TLSSocket.emit (node:events:529:35)
    at Socket._onTimeout (node:net:598:8)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7)

이후 명령어가 멈추는 것 같습니다(최소 10분 이상 아무 반응이 없음) 그래서 프로세스를 종료하고 다시 시도했습니다. 결과는 동일했습니다.

네트워크 문제는 없습니다: 도커 컨테이너 내부(./launcher enter app)에서 wget https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz를 실행하면 0.1초 이내에 성공적으로 반환됩니다.

유사한 문제를 확인해 보았습니다: Error during the update ESOCKETTIMEDOUT registry.yarnpkg.com - #4 by jericson 거기에 제시된 해결책은 /var/discourse/templates/web.template.yml을 편집하여 타임아웃을 늘리는 것입니다.

불행히도 제 설치 환경에는 해당 경로가 없습니다(도커 컨테이너 내부에서 /var/discourse가 없습니다. 앱에 진입했을 때 기본 작업 디렉터리인 var/www/discourse 폴더는 있지만, 여기에는 templates 하위 폴더가 없습니다. web.template.yml을 검색해 보았지만 어디에서도 찾을 수 없었습니다.)

또한 https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz의 다운로드 속도가 매우 빠른 점을 고려할 때, 타임아웃을 늘리는 것이 문제를 해결할 수 있을지 확신이 서지 않습니다.

결국 며칠 전의 백업(구버전의 discourse)을 복원하고, 최신 버전의 discourse/shared를 해당 백업으로 복사하여 진행했습니다. 이 방법은 작동하므로 포럼이 다시 정상적으로 운영되고 있습니다.

메인 브랜치의 최신 버전에 문제가 있는 건가요? 실제로 ./launcher rebuild app을 다시 실행해 보았는데, 동일한 방식으로 다시 실패하여 포럼을 백업에서 다시 복원해야 했습니다.

문제가 개별 패키지를 가져오는 데 있는 것이 아니라, 모든 패키지를 설치하는 데 걸리는 총 시간이 아닐까 싶습니다. 메모리가 충분하지 않으면 네트워크 속도가 정상이어도 문제가 발생할 수 있습니다. 제가 문제를 겪었던 E2.Micro 인스턴스는 메모리가 겨우 1GB뿐이었거든요.

참고로, 저는 방금 4GB 드롭렛에서 Discourse를 업데이트했는데 특별한 문제는 보이지 않았습니다.

저는 32GB RAM을 갖춘 VPS를 사용 중이며, 현재 24GB가 비어 있습니다. 따라서 메모리는 문제가 되지 않을 것입니다.

아래 명령어를 실행하여 기존 컨테이너를 다시 실행해 볼 수 있습니다.

 ./launcher start app

이것은 문제를 근본적으로 해결하지는 않지만, 사이트는 다시 올라갈 것입니다. 백업에서 복원할 필요는 없을 것입니다.

/var/discourse는 컨테이너 내부가 아닌 외부에 위치합니다. 해당 템플릿은 컨테이너 내부의 구성 요소를 빌드하는 데 사용되므로, 시도해 볼 가치가 있습니다.

또한, 보유하고 있는 RAM 용량이 많으므로 사이트 다운타임 없이 부트스트랩을 수행할 수 있도록 2-컨테이너 구성으로 전환하는 것을 권장합니다.

불행히도 단순히

./launcher start app

을 실행해도 포럼이 다시 시작되지 않습니다.

그래서 저는 추가 실험을 진행했습니다. 구체적으로, 도커 이미지 내에서 실패하는 yarn 명령어를 수동으로 실행해 보았습니다:

./launcher enter app
cd /var/www/discourse
su discourse
yarn install --frozen-lockfile
... 동일한 타임아웃 오류로 실패 ...
yarn config set network-timeout 600000 -g
yarn install --frozen-lockfile
... 성공 ...

이는 타임아웃을 늘리면 문제가 해결됨을 확인해 줍니다.

남은 질문은 ./launcher rebuild app 실행 시에도 타임아웃을 늘리는 방법을 찾는 것입니다.

web.template.yml 파일은 실제로 도커 이미지 밖의 discourse/containers 디렉터리에 위치해 있습니다. 처음에는 찾지 못했는데, 제 Discourse 설치 위치가 표준 경로인 /var/discourse가 아닌 비표준 위치였기 때문입니다.

위에서 언급된 게시글에서 제시된 수정 방법은 159번 줄을 가리키고 있지만, 업데이트로 인해 더 이상 정확하지 않은 것 같습니다. 대신 188번 줄 근처에 다음과 같은 줄들이 있습니다:

  - exec:
      cd: $home
      hook: yarn
      cmd:
        - |-
          if [ "$version" != "tests-passed" ]; then
            rm -rf app/assets/javascripts/node_modules
          fi
        - su discourse -c 'yarn install --frozen-lockfile && yarn cache clean'

해당 게시글은 타임아웃을 설정하기 위해 새로운 섹션을 삽입하라고 제안하지만, 이를 수행하는 구체적인 지침은 제공하지 않습니다. 저는 yaml, pups, yarn이 Discourse에서 어떻게 사용되는지에 대해 매우 익숙하지 않아 추측하고 싶지 않았습니다. 대신, 기존 섹션에 다음과 같은 변경을 시도했습니다:

  - exec:
      cd: $home
      hook: yarn
      cmd:
        - |-
          if [ "$version" != "tests-passed" ]; then
            rm -rf app/assets/javascripts/node_modules
          fi
        - su discourse -c 'yarn config set network-timeout 600000 -g && yarn install --frozen-lockfile && yarn cache clean'

이제 ./launcher rebuild app 명령어가 매우 오래 걸립니다(2시간 이상! 이전보다 훨씬 더 오래 걸립니다). 좋은 소식은 포럼이 다시 온라인에 복귀했다는 것입니다. 훌륭합니다, 도움 주셔서 감사합니다.

containers/app.yml에 명령어를 추가하여 타임아웃을 늘리는 방법이 있을까요? 모든 커스터마이징을 단일 파일에 모을 수 있어 편리할 것 같습니다.

2-컨테이너 구성을 사용하는 것은 좋은 아이디어인 것 같습니다. 이것이 가능한지 몰랐습니다. 아마도 이 링크를 말씀하시는 것 같습니다: Move from standalone container to separate web and data containers; 시도해 볼 것입니다. 추가 조언이 있다면 환영합니다.

브라우저에서 Discourse 인스턴스의 업데이트를 실행할 때 ./launcher rebuild app도 실행되나요? 포럼을 일시적으로 오프라인으로 만들까요? 지금까지는 프로세스의 대부분 동안 포럼이 온라인 상태를 유지한다고 생각했지만, 확신은 없습니다. 이러한 사항들은 저에게 항상 명확하지 않았고, 실제로 파악할 시간도 없었습니다. 답변이나 더 자세한 정보를 찾을 수 있는 방향을 제시해 주시면 감사하겠습니다.