여러분 안녕하세요. Docker로 최신 버전의 Discourse를 설치했습니다.
문제는 컨테이너를 재빌드한 후 컨테이너는 실행 중이고 앱 페이지에도 접근할 수 있지만, 응답으로 502 오류가 발생한다는 것입니다. 로그를 확인하거나 컨테이너 내부에서 rails c를 실행하려고 해도 다음 오류만 표시됩니다:
`permission_error’: bootsnap doesn’t have permission to write cache entries in ‘tmp/cache/bootsnap/compile-cache’ (or, less likely, doesn’t have permission to read ‘/usr/local/lib/ruby/2.7.0/set.rb’) (Bootsnap::CompileCache::PermissionError)
이 문제를 해결하려면 컨테이너 내부에서 chown -R discourse:discourse /var/www/discourse/tmp (정확히 말하면 /var/www/discourse/tmp/cache/bootsnap) 명령을 실행해야 하며, 이 작업을 즉시 수행하면 재시작 없이도 앱이 정상적으로 작동합니다. 매번 재빌드 후 수동으로 이 작업을 수행하는 것은 매우 번거롭습니다.
app.yml의 커스텀 명령 섹션에 위에서 언급한 chown -R discourse:discourse /var/www/discourse/tmp 명령을 사용하여 이 문제를 해결할 수 있을 것 같았지만, unfortunately 작동하지 않습니다. 명령이 실행되는 것 같기는 합니다(확인하기 위해 mkdir을 시도해 봤습니다) 하지만 파일 권한에는 영향을 미치지 않습니다.
여기서 문제가 무엇일 수 있으며 어떻게 해결할 수 있을까요? 파일 권한을 올바르게 변경하는 다른 방법이 있을까요?
## 이 파일은 올인원, 독립형 Discourse Docker 컨테이너 템플릿입니다
##
## 이 파일을 수정한 후에는 반드시 재빌드해야 합니다
## /var/discourse/launcher rebuild app
##
## 편집 시 *매우* 주의하세요!
## YAML 파일은 공백이나 정렬 실수에 *매우* 민감합니다!
## 필요 시 http://www.yamllint.com/에서 이 파일을 검증하세요
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## Lets Encrypt(https)를 추가하려면 아래 두 줄의 주석을 해제하세요
- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
## 이 컨테이너가 어떤 TCP/IP 포트를 노출해야 하는가?
## Discourse가 Apache나 nginx 같은 다른 웹서버와 포트를 공유하려면
## 자세한 내용은 https://meta.discourse.org/t/17247을 참조하세요
expose:
- "80:80" # http
- "443:443" # https
params:
db_default_text_search_config: "pg_catalog.english"
## db_shared_buffers는 총 메모리의 최대 25%로 설정하세요.
## 감지된 RAM 기반으로 bootstrap이 자동으로 설정하거나, 직접 덮어쓸 수 있습니다
#db_shared_buffers: "256MB"
## 정렬 성능을 향상시킬 수 있지만, 연결당 메모리 사용량이 증가합니다
#db_work_mem: "40MB"
## 이 컨테이너가 어떤 Git 리비전을 사용해야 하는가? (기본값: tests-passed)
#version: tests-passed
env:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LANGUAGE: en_US.UTF-8
# DISCOURSE_DEFAULT_LOCALE: en
## 동시에 처리할 수 있는 웹 요청 수는 얼마인가? 메모리와 CPU 코어 수에 따라 달라집니다.
## 감지된 CPU 기반으로 bootstrap이 자동으로 설정하거나, 직접 덮어쓸 수 있습니다
#UNICORN_WORKERS: 3
## TODO: 이 Discourse 인스턴스가 응답할 도메인 이름
## 필수 항목입니다. Discourse는 IP 주소만으로는 작동하지 않습니다.
DISCOURSE_HOSTNAME: 'example.com'
## 컨테이너가 위에서 지정된 호스트 이름(-h 옵션)과 동일한 이름으로 시작되도록 하려면
## 주석을 해제하세요 (기본값 "$hostname-$config")
#DOCKER_USE_HOSTNAME: true
## TODO: 초기 가입 시 관리자 및 개발자로 지정할 쉼표로 구분된 이메일 목록
## 예: 'user1@example.com,user2@example.com'
DISCOURSE_DEVELOPER_EMAILS: 'test@mail.com'
## TODO: 새 계정을 검증하고 알림을 보내는 데 사용되는 SMTP 메일 서버
# SMTP 주소, 사용자 이름, 비밀번호는 필수입니다
# 경고: SMTP 비밀번호에 '#' 문자가 있으면 문제가 발생할 수 있습니다!
DISCOURSE_SMTP_ADDRESS: smtp.mail.io
#DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: 111
DISCOURSE_SMTP_PASSWORD: 111
#DISCOURSE_SMTP_ENABLE_START_TLS: true # (선택 사항, 기본값 true)
#DISCOURSE_SMTP_DOMAIN: discourse.example.com # (일부 제공업체에서 필수)
#DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com # (알림을 보내는 주소)
## Lets Encrypt 템플릿을 추가했다면, 무료 SSL 인증서를 얻으려면 아래 주석을 해제하세요
#LETSENCRYPT_ACCOUNT_EMAIL: me@example.com
## 이 Discourse 인스턴스의 http 또는 https CDN 주소 (pull로 구성됨)
## 자세한 내용은 https://meta.discourse.org/t/14857을 참조하세요
#DISCOURSE_CDN_URL: https://discourse-cdn.example.com
## IP 주소 조회를 위한 maxmind 지리 정보 IP 주소 키
## 자세한 내용은 https://meta.discourse.org/t/-/137387/23을 참조하세요
#DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456
## Docker 컨테이너는 상태가 없으며(stateless), 모든 데이터는 /shared에 저장됩니다
volumes:
- volume:
host: /var/discourse/shared/standalone
guest: /shared
- volume:
host: /var/discourse/shared/standalone/log/var-log
guest: /var/log
## 플러그인은 여기에 설치합니다
## 자세한 내용은 https://meta.discourse.org/t/19157을 참조하세요
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
## 빌드 후 실행할 사용자 지정 명령
run:
- exec: echo "Beginning of custom commands"
## 첫 번째 가입 시 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
## 첫 가입 이메일을 받은 후, 해당 줄의 주석을 다시 활성화하세요. 한 번만 실행하면 됩니다.
#- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
#- exec: chown -R discourse:discourse /var/www/discourse/tmp/cache/bootsnap # 파일 권한을 수정하기 위해 시도했던 명령 예시
- exec: echo "End of custom commands"
우선, 애플리케이션은 discourse-setup을 사용하여 구축되었습니다. 재구축을 몇 번 시도해 보았지만 긍정적인 결과를 얻지 못하자, /samples 디렉터리에서 사전 정의된 .yml 설정 파일 중 하나를 가져와 내 인증 정보로 수정했습니다.
왜 Let’s Encrypt를 사용하지 않느냐고 물었더니, 클라이언트 인증서를 사용하라고 했습니다. 하지만 제 이해로는 인증서는 이 문제와 무관한 것 같습니다. 인증서는 유효하며 이로 인한 문제가 없기 때문입니다.
문제는 프로젝트 레벨에 있는 것으로 보이며, 이는 구체적으로 bootsnap 캐시 파일 권한(아마도 Bootsnap 측의 문제일 수 있음)과 관련이 있는 것 같습니다.
컨테이너를 실행한 후 /var/www/discourse/tmp 디렉터리의 소유자 사용자 및 그룹은 discourse:www-data였습니다. 이를 discourse:discourse로 재할당하면 문제가 해결되었습니다. 이전에 이런 현상은 발생하지 않았으며, 저는 이미 수개월간 discourse를 사용해 왔습니다. 어쨌든 간단한 해결책이었으며 우연히 발생한 것일 수 있으므로 더 이상 귀찮게 하지 않겠습니다. @gerhard 님, 정말 감사합니다!