저는 자체 호스팅(self-hosted)된 Discourse(2026.5.0-latest)를 운영하고 있습니다. 오늘 YJIT를 활성화하려고 시도했습니다. containers/app.yml 파일에 "templates/enable-ruby-yjit.yml"를 추가하고 앱을 다시 빌드했습니다.
재빌드가 완료된 후 흥미로운 일이 발생했습니다. Docker 컨테이너 내에서 env | grep RUBY_YJIT_ENABLE을 실행하니 RUBY_YJIT_ENABLE=1이 반환되었습니다. 여기까지는 좋았습니다. 하지만 이어서 sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION'을 실행해 보니 다음과 같은 결과가 나왔습니다:
enable-ruby-yjit.yml 템플릿을 추가했음에도 불구하고 YJIT가 활성화되지 않은 것이었습니다. 그런 다음 sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"'을 실행해 보니 GlobalSetting.yjit_enabled=가 반환되었습니다 — 즉, nil 값이었죠!
어쨌든, 조금 더 이리저리 시도해 본 끝에 containers/app.yml에 다음 내용을 추가하여 마침내 YJIT를 활성화할 수 있었습니다:
env:
DISCOURSE_YJIT_ENABLED: true
어딘가에 버그가 있다고 확신합니다(GlobalSetting.yjit_enabled는 절대 nil을 반환해서는 안 됩니다). 하지만 환경 변수를 설정하는 방식으로 작동했고, 이 문제를 검색하는 분들이 이 주제를 찾기를 바랍니다.
환경 변수의 존재 여부만으로는 Ruby가 현재 YJIT가 활성화된 상태로 실행 중인지 알 수 없습니다. 이 특정 경우에서는 환경 변수가 설정되어 있었지만, Rails가 시작 시 YJIT를 활성화(또는 비활성화)하는 데 사용하는 변수를 다른 요소가 덮어쓰고 있었습니다! (아마도… 제 추측입니다.)
새로운 Rails 인스턴스에서조차 GlobalSetting.yjit_enabled=가 nil을 반환하는 이유에 대한 다른 설명은 없습니다. 또한 새로운 Rails 인스턴스에서 YJIT가 꺼져 있을 이유도 없습니다.
컨테이너의 app.yml에 DISCOURSE_YJIT_ENABLED 환경 변수를 추가한 후,
이것은 잘못되었습니다. Ruby 레벨에서 ENV 변수는 공식적인 토글 중 하나입니다. 이에 대한 Ruby 공식 문서를 여기서 확인해 보세요.
이것도 잘못되었습니다. DISCOURSE_YJIT_ENABLED는 오직 GlobalSetting.yjit_enabled → config/application.rb의 config.yjit에만 공급됩니다. Rails는 YJIT를 활성화하기 위해 이를 사용하며, 이미 활성화되어 있지 않은 경우에만 해당합니다. 이미 활성화된 YJIT를 비활성화하지는 않습니다. 따라서 환경 변수가 설정된 경우, DISCOURSE_YJIT_ENABLED는 아무런 역할도 하지 않습니다.
제 주장을 더욱 입증하기 위해, 제 웹 프로세스에서 YJIT가 활성화되어 있는지 여부를 반환하는 플러그인을 작성했습니다:
아니, 정말! 환경 변수를 사용해 YJIT가 활성화되어 있는지 신뢰할 수 있게 감지할 수 있다는 뜻인가요? 몰랐습니다. Ruby 문서에 대한 링크를 주셔서 감사합니다.
다만 한 가지 조금 궁금한 점이 있습니다. env | grep RUBY_YJIT_ENABLE를 실행하면 RUBY_YJIT_ENABLE=1이 반환되는데, 같은 컨테이너에서 새로 실행한 Rails 인스턴스에서 #{RubyVM::YJIT.enabled?}를 출력하라고 하면 false가 나오는 것이 어떻게 가능한가요? — 당신이 언급했듯이 이 환경 변수는 Ruby 레벨에서 작동하므로 true가 출력되어야 하지 않나요?
당신이 정말 바쁘실 테고 이 문제는 중요하지 않을 수 있으니 답변할 필요가 없습니다. 제 서버에서 직접 해결할 수 있을 것 같습니다. 혹시 당신의 플러그인을 받을 수 있을까요? 제 Discourse 서버가 YJIT가 활성화된 Ruby로 실행되고 있는지 확실히 확인할 방법을 원합니다.
sudo -u discourse는 환경 변수를 초기화합니다. -E 플래그를 사용하면 기존 환경 변수가 유지되며, 이 경우 sudo -E -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION'을 실행하면 다음과 같은 결과가 반환됩니다.