Discourse 자산 누락

안녕하세요,
권장 설치 가이드를 따라 Fedora 31 서버에 Discourse를 설치했습니다. 다만 컨테이너 실행에는 docker 대신 podman을 사용했습니다. 오늘 아침 처음 설정했을 때는 모든 것이 완벽하게 잘 진행되었지만, 호스트의 Nginx로 일반 HTTP를 연결하는 데 문제가 생겨 nginx 인스턴스 양쪽에 SSL 인증서를 사용해야 했습니다. Discourse를 구성한 후에는 모든 것이 정상적으로 작동했습니다.

이후 SSL을 끄고 비루트(non-root) 사용자 계정으로 Discourse를 다시 빌드하기로 결정했습니다. 호스트로의 일반 HTTP는 정상적으로 작동했지만, 흰색 화면이 표시되었습니다(제목은 정상, 파비콘은 작동).


컨테이너 내의 디렉토리를 확인해 보았습니다:

root@xena-app:/var/www/discourse# ls public/assets -al
total 15640
drwxr-xr-x. 2 discourse discourse      10 Jan 11 13:54 .
drwxr-xr-x. 3 discourse discourse      29 Jan 11 13:57 ..
-rw-r--r--. 1 discourse discourse     595 Jan 11 13:49 _activate-account-7a1f8d46287194007ee607f79af56217e6e6238e4ca159c5da6974005a1254c5.js
-rw-r--r--. 1 discourse discourse     250 Jan 11 13:54 activate-account-7a1f8d46287194007ee607f79af56217e6e6238e4ca159c5da6974005a1254c5.js.br
-rw-r--r--. 1 discourse discourse     420 Jan 11 13:54 activate-account-7a1f8d46287194007ee607f79af56217e6e6238e4ca159c5da6974005a1254c5.js.gz
-rw-r--r--. 1 discourse discourse     695 Jan 11 13:54 activate-account-7a1f8d46287194007ee607f79af56217e6e6238e4ca159c5da6974005a1254c5.js.map
-rw-r--r--. 1 discourse discourse  990519 Jan 11 13:50 _admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js
-rw-r--r--. 1 discourse discourse   83903 Jan 11 13:54 admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js.br
-rw-r--r--. 1 discourse discourse  106465 Jan 11 13:54 admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js.gz
-rw-r--r--. 1 discourse discourse  366446 Jan 11 13:54 admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js.map
drwxr-xr-x. 2 discourse discourse    4096 Jan 11 13:54 admin-login
...

요청된 파일들은 실제로 존재하지 않으며, Nginx 로그에도 그렇게 표시되고 있습니다:

2020/01/11 13:59:49 [error] 60#60: *20 open() "/var/www/discourse/public/assets/plugins/poll-57c9059384e3daeaee3d974c985d85a2b8462bb2629eb0b1834451056d1e1459.js" failed (2: No such file or directory), client: 10.0.2.2, server: _, request: "GET /assets/plugins/poll-57c9059384e3daeaee3d974c985d85a2b8462bb2629eb0b1834451056d1e1459.js HTTP/1.0", host: "idlerpg.xyz", referrer: "https://idlerpg.xyz/"

이것은 제 설치 환경의 문제일 것이라고 생각했습니다. 왜냐하면 오늘 아침 호스트의 루트 계정으로 실행하던 이전 설치에서는 해당 파일들이 존재했기 때문입니다. 공유 폴더를 지우고 비루트 계정으로 다시 빌드했지만, 동일한 결과가 반복되었습니다. 그 후 이번에는 오늘 아침과 동일한 설정으로 루트 계정을 사용해 다시 시도해 보았지만, 동일한 문제가 발생했습니다.
비루트 설치에서는 항상 “Congratulations, you have installed Discourse!”(축하합니다, Discourse를 설치했습니다!) 페이지가 표시되지만, 설치를 완료한 후에는 에셋 파일이 없어 빈 화면이 나타납니다.

누락된 에셋 파일을 수정할 방법이 있을까요?

혹시 오늘 아침에 정말로 작동했는지 궁금해하는 분이 있을까 봐, 내 모바일에서 찍은 스크린샷을 첨부합니다.


아직 Discourse에서는 한 게시물에 이미지 2개를 올릴 수 없네요 :slight_smile:

이 문제를 버그로 변경했습니다. tests-passed 빌드 시 모든 에셋이 포함된 버전을 생성하지 못했습니다. 컨테이너에 진입하여 rake assets:precompile을 실행해 보았지만, 여전히 동일한 에셋들이 누락되어 있습니다.

수많은 재빌드 끝에 갑자기 정상 작동하네요. 기묘하네요.

안녕하세요 Adriany, 포럼에 오신 것을 환영합니다.

제가 아는 한, docker는 선택 사항이 아니라 필수 요건입니다. 이 새로운 설치 가이드를 어디서 보셨나요?

방금 docker를 podman으로 교체했는데, 잘 작동합니다. 두 도구의 명령어 구문이 호환됩니다.

음, 테스트를 좀 해본 결과, 재빌드할 때마다 항상 빈 페이지가 표시되는 걸 확인했습니다. RAILS_ENV=production bin/rake assets:precompile을 실행하면 그 후에는 항상 정상적으로 작동합니다. 왜 그런지 모르겠는데, 재빌드 시에도 애셋을 컴파일해야 하는 거 아닌가요?

이 주제, 특히 Docker와의 Podman 호환성 문제와 관련된 이 게시물을 보셨나요?

네, 실제로 작동합니다. Podman은 초기 에셋 프리컴파일 결과물로 어떤 파일이 생성될지에 영향을 주어서는 안 됩니다.

재구축의 에셋 컴파일 단계에서 출력에 백트레이스가 표시됩니까?

무언가 작동하지 않기 때문에 여기 있습니다. *해야 한다(Should)*와 *실제로 한다(Does)*는 서로 다른 상태입니다.

Podman이 관련이 없다고 자신 있게 주장하고 계시지만, 이를 명확히 입증하여 Podman을 원인으로 배제하는 것이 좋습니다. 제 생각에는 Docker를 사용한 공식 설치 방법을 완료하여 문제가 사라지는지 확인하지 않으신 것 같습니다.

네, 맞아요.

I, [2020-01-12T20:58:31.800117 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake assets:precompile'
임시 파일 삭제 중
에셋 번들링 중
I, [2020-01-12T20:58:38.208107 #758]  INFO -- : /var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js 파일 작성 중
I, [2020-01-12T20:59:02.428630 #758]  INFO -- : /var/www/discourse/public/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js 파일 작성 중
I, [2020-01-12T20:59:02.447192 #758]  INFO -- : /var/www/discourse/public/assets/preload-store-d32dcf974dddcac742f8a7a6aa7fcd686185920b201029d0ecb2b85527ef9034.js 파일 작성 중
I, [2020-01-12T20:59:02.707559 #758]  INFO -- : /var/www/discourse/public/assets/browser-update-1741a2ed67a367faeb0a582af064457e8b1b1354e52e6efcf8bf26301166dec8.js 파일 작성 중
I, [2020-01-12T20:59:02.753632 #758]  INFO -- : /var/www/discourse/public/assets/break_string-cc617154cd957804f2f6a1f3bc68258c9cdca3d4b9a322bf777d145fed04790e.js 파일 작성 중
I, [2020-01-12T20:59:04.073148 #758]  INFO -- : /var/www/discourse/public/assets/ember_jquery-c2cca4a19fd4c70eabc95b010a6d7643955ec2a2251aeb1d70f625773eebea21.js 파일 작성 중
I, [2020-01-12T20:59:06.303026 #758]  INFO -- : /var/www/discourse/public/assets/pretty-text-bundle-fa6ea00e2000bf2f9ed3f069be9253477fed5e7290b5d109a3e2d9498ac70e81.js 파일 작성 중
... [생략]
108798.339928812 압축 중: vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js
uglifyjs '/var/www/discourse/public/assets/_vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js' -m -c -o '/var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js' --source-map "root='/assets',url='/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js.map'" --output '/var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js'
gzip -f -c -9 /var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js > /var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js.gz

brotli -f --quality=11 /var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js --output=/var/www/discourse/public/assets/vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js.br


vendor-3b0a3ac5e0bc628422d6e99d3563fad4c474398644f70683eff0893b7a241513.js 압축 완료 : 3.33초

108801.669283898 압축 중: admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js
uglifyjs '/var/www/discourse/public/assets/_admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js' -m -c -o '/var/www/discourse/public/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js' --source-map "root='/assets',url='/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js.map'" --output '/var/www/discourse/public/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js'
gzip -f -c -9 /var/www/discourse/public/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js > /var/www/discourse/public/assets/admin-91c2a24a61c0ecd0200db1e808dbadafb9f0f1bb5179acea5b2b7dbd4b4cc5f9.js.gz
[...]

컴파일은 되지만, 누락된 파일이 나타나도록 하려면 빌드 후 항상 다시 실행해야 합니다

흥미롭네요. 파일은 정상적으로 생성되는데, 영속성(persistence)만 실패하는 건가요?

podman 볼륨이 어떻게 작동하는지, 그리고 그 볼륨을 뒷받침하는 드라이버가 무엇인지 살펴보는 것이 좋습니다. Docker 환경에서는 지난 몇 년간 스토리지 드라이버와 관련된 수많은 이상한 문제가 발생하여, 저희도 런처 스크립트에서 “권장(blessed)” 드라이버 목록을 따로 유지하고 있을 정도입니다.

정리하자면, 제 podman 실험은 실제로 launcher를 테스트한 것이었고 discourse를 테스트한 것이 아닙니다. 제가 테스트했을 당시에는, podman이 모방하려 하지 않는 docker의 출력 세부 사항에 의존하고 있었습니다.

@Adriany, 아마도 기본 저장소 드라이버를 사용 중이실 것 같은데, 이는 discourse에 권장되는 것과 동일한 드라이버입니다. docker에서는 "overlay2*"가 해당되지만, 그것이 실제로 그런지는 확신할 수 없습니다.

저는 overlay2와 동일한 overlayfs를 사용 중입니다.
재미있는 점은, 플러그인을 추가하려고 시도했을 때 몇 번의 빌드에서 에셋 누락 문제가 발생하다가, 이후 다시 빌드했을 때 에셋 누락 없이 정상적으로 빌드가 완료되었다는 것입니다. 플러그인 없이 다시 빌드했을 때는 매우 원활하게 작동했습니다. 이게 무슨 일일까요?

수정: 제 환경에서는 잘 작동했고, 이제 에셋이 여기에 캐시되었습니다. 하지만 실행 중 다른 사용자들에게는 작동을 멈췄습니다.

수정 2: 다시 빌드하자 이전처럼 에셋이 깨지는 문제가 발생했고, 해결책은 이전과 동일한 방식으로 다시 빌드하는 것이었습니다.

자산 파이프라인에 의해 파일이 성공적으로 생성되고 OS에서 오류가 없다고 보고하지만, 리빌드(실제로는 컨테이너를 재시작하는 것) 후에 파일이 사라진다면, 저는 podman 스토리지 드라이버에 원인이 있을 것이라고 단정 짓겠습니다.

Docker를 사용하여 동일한 동작을 재현할 수 있는 사람이 없는 한(이런 경우라면 여러 토픽이 생겼을 것입니다), Podman 프로젝트에 이 문제에 대해 티켓을 열어야 할 것 같습니다.

안녕하세요,

조사를 더 해본 결과, 파일 저장 위치나 파일 찾기에 대해 제가 잘못 추측했거나 단순히 제대로 찾지 못한 것 같습니다.

파일들이 모두 404 에러를 반환하고 있지만, 아래를 예시로 보시면 됩니다:

root@idlerpg:/var/www/discourse# find . -type f -name "*discourse-solved*"
./tmp/stylesheet-cache/discourse-solved_9_cb2984706f4402e95fd787160a5588ed0972ccc3.css
./tmp/stylesheet-cache/discourse-solved_9_cb2984706f4402e95fd787160a5588ed0972ccc3.css.map
./public/assets/plugins/_discourse-solved-5b7312e4207059eb2654a46e804b4c899cfc1e2a362d0d60e580943f9eb9d419.js
./public/assets/plugins/discourse-solved-5b7312e4207059eb2654a46e804b4c899cfc1e2a362d0d60e580943f9eb9d419.js.gz
./public/assets/plugins/discourse-solved-5b7312e4207059eb2654a46e804b4c899cfc1e2a362d0d60e580943f9eb9d419.js.br
./public/assets/plugins/discourse-solved-5b7312e4207059eb2654a46e804b4c899cfc1e2a362d0d60e580943f9eb9d419.js.map
./app/assets/javascripts/plugins/discourse-solved.js.erb
./plugins/discourse-solved/test/javascripts/acceptance/discourse-solved-test.js.es6

파일들은 존재하므로, 이는 podman 문제가 아니라 Discourse 자체의 문제인 것 같습니다. 단순히 파일을 제대로 검색하지 못했던 것이었네요.

Cloudflare 관련 문제일 수도 있다고 생각했지만, 서버에서 로컬호스트로 빠른 curl 요청을 해보았을 때 역시 404가 반환되었습니다.

Docker에서 이 문제가 발생하는 재현 방법을 공유해 주실 수 있나요?