신규 설치에서 "./launcher rebuild app" 실행 시 권한 오류 발생

다음과 같이 진행했습니다:

git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers

그 후 기존 app.ymlcontainers 디렉토리로 복사하고 앱을 다시 빌드하려 했습니다:


[root@two discourse]# ./launcher rebuild app
x86_64 아키텍처 감지됨.
launcher가 최신 상태인지 확인 중
launcher는 최신 상태입니다
기존 컨테이너 중지 중
+ /usr/bin/docker stop -t 600 app
app
2.0.20250722-0020: discourse/base에서 가져오는 중
Digest: sha256:3b975c30ef85e9742e2d7f6093450867e67dae204c93d22cc38d043dcbf530b3
Status: discourse/base:2.0.20250722-0020 이미지가 최신 상태입니다
docker.io/discourse/base:2.0.20250722-0020
/usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups.rb
/usr/local/bin/pups --stdin
I, [2025-09-12T19:05:09.283821 #1]  INFO -- : stdin에서 읽는 중
I, [2025-09-12T19:05:09.296585 #1]  INFO -- : File > /etc/service/postgres/run  chmod: +x  chown: 
I, [2025-09-12T19:05:09.301579 #1]  INFO -- : File > /etc/service/postgres/log/run  chmod: +x  chown: 
I, [2025-09-12T19:05:09.307391 #1]  INFO -- : File > /etc/runit/3.d/99-postgres  chmod: +x  chown: 
I, [2025-09-12T19:05:09.313597 #1]  INFO -- : File > /root/install_postgres  chmod: +x  chown: 
I, [2025-09-12T19:05:09.319914 #1]  INFO -- : File > /root/upgrade_postgres  chmod: +x  chown: 
I, [2025-09-12T19:05:09.320255 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 data_directory = '/var/lib/postgresql/15/main'을 data_directory = '/shared/postgres_data'로 대체
I, [2025-09-12T19:05:09.323526 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?listen_addresses *=.*)을 listen_addresses = '*'로 대체
I, [2025-09-12T19:05:09.324153 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?synchronous_commit *=.*)을 synchronous_commit = $db_synchronous_commit로 대체
I, [2025-09-12T19:05:09.324577 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?shared_buffers *=.*)을 shared_buffers = $db_shared_buffers로 대체
I, [2025-09-12T19:05:09.324945 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?work_mem *=.*)을 work_mem = $db_work_mem으로 대체
I, [2025-09-12T19:05:09.325369 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?default_text_search_config *=.*)을 default_text_search_config = '$db_default_text_search_config'로 대체
I, [2025-09-12T19:05:09.325759 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?checkpoint_segments *=.*)을 checkpoint_segments = $db_checkpoint_segments로 대체
I, [2025-09-12T19:05:09.329467 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?logging_collector *=.*)을 logging_collector = $db_logging_collector로 대체
I, [2025-09-12T19:05:09.330304 #1]  INFO -- : /etc/postgresql/15/main/postgresql.conf에서 (?-mix:#?log_min_duration_statement *=.*)을 log_min_duration_statement = $db_log_min_duration_statement로 대체
I, [2025-09-12T19:05:09.330761 #1]  INFO -- : /etc/postgresql/15/main/pg_hba.conf에서 (?-mix:^#local +replication +postgres +peer$)을 local replication postgres  peer로 대체
I, [2025-09-12T19:05:09.331823 #1]  INFO -- : /etc/postgresql/15/main/pg_hba.conf에서 (?-mix:^host.*all.*all.*127.*$)을 host all all 0.0.0.0/0 md5로 대체
I, [2025-09-12T19:05:09.332230 #1]  INFO -- : /etc/postgresql/15/main/pg_hba.conf에서 (?-mix:^host.*all.*all.*::1\/128.*$)을 host all all ::/0 md5로 대체
I, [2025-09-12T19:05:09.332621 #1]  INFO -- : > if [ -f /root/install_postgres ]; then
  /root/install_postgres && rm -f /root/install_postgres
elif [ -e /shared/postgres_run/.s.PGSQL.5432 ]; then
  socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres already running stop container ; exit 1
fi

mkdir: 디렉터리 ‘/shared/postgres_run’ 생성 불가: 권한 거부
chown: '/shared/postgres_run' 접근 불가: 그런 파일 또는 디렉터리가 없습니다
chmod: '/shared/postgres_run' 접근 불가: 그런 파일 또는 디렉터리가 없습니다
mkdir: 디렉터리 ‘/shared/postgres_run’ 생성 불가: 권한 거부
chown: '/shared/postgres_run/15-main.pg_stat_tmp' 접근 불가: 그런 파일 또는 디렉터리가 없습니다
install: ‘/shared/postgres_data’의 소유자와 권한 변경 불가: 그런 파일 또는 디렉터리가 없습니다
initdb: 오류: 디렉터리 "/shared/postgres_data" 생성 불가: 권한 거부
find: ‘/shared/postgres_data’: 그런 파일 또는 디렉터리가 없습니다
chown: '/var/run/postgresql' 참조 해제 불가: 그런 파일 또는 디렉터리가 없습니다
cat: /shared/postgres_data/PG_VERSION: 그런 파일 또는 디렉터리가 없습니다
du: '/shared/postgres_data' 접근 불가: 그런 파일 또는 디렉터리가 없습니다
/root/upgrade_postgres: 7번째 줄: * 2: 구문 오류: 피연산자 예상됨 (오류 토큰은 "* 2")
I, [2025-09-12T19:05:12.122891 #1]  INFO -- : 로케일 생성 중 (시간이 좀 걸릴 수 있습니다)...
  en_US.UTF-8... 완료
생성 완료.
이 데이터베이스 시스템에 속하는 파일들은 "postgres" 사용자가 소유합니다.
이 사용자는 서버 프로세스도 소유해야 합니다.

데이터베이스 클러스터는 로케일 "en_US.UTF-8"로 초기화됩니다.
기본 데이터베이스 인코딩은 이에 따라 "UTF8"으로 설정되었습니다.
기본 텍스트 검색 구성은 "english"로 설정됩니다.

데이터 페이지 체크섬은 비활성화됩니다.

디렉터리 /shared/postgres_data 생성 중 ... PostgreSQL을 버전에서 15로 업그레이드


실패(FAILED)
--------------------
Pups::ExecError: if [ -f /root/install_postgres ]; then
  /root/install_postgres && rm -f /root/install_postgres
elif [ -e /shared/postgres_run/.s.PGSQL.5432 ]; then
  socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres already running stop container ; exit 1
fi
 실행 결과 #<Process::Status: pid 18 exit 1>로 실패
실패 위치: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec가 파라미터 {"tag"=>"db", "cmd"=>"if [ -f /root/install_postgres ]; then\n  /root/install_postgres && rm -f /root/install_postgres\nelif [ -e /shared/postgres_run/.s.PGSQL.5432 ]; then\n  socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres already running stop container ; exit 1\nfi\n"}와 함께 실패
bootstrap이 종료 코드 1로 실패
** BOOTSTRAP 실패 ** 이전의 오류 메시지를 확인하려면 위로 스크롤하세요. 하나 이상일 수 있습니다.
./discourse-doctor가 문제를 진단하는 데 도움이 될 수 있습니다.
c9c7badf83b119a15b40255ae48a05182f72663cc870ca85e867c1f9a218bb83

컨테이너 내부에서 처음부터 권한 문제가 있는 것 같습니다:

mkdir: cannot create directory ‘/shared/postgres_run’: Permission denied

이것의 원인은 무엇일 수 있을까요?

아마도 --privileged 플래그를 사용하여 docker를 실행해야 하는 것 같습니다. 이 방법으로 문제가 해결되거든요:

./launcher rebuild app --docker-args '--privileged'

이렇게 해야 하는 이유는 명확하지 않습니다. (Fedora 42 환경입니다.) 여기서 어떤 일이 일어나고 있는지 이해하고 싶습니다.

Discourse에서는 해당 파일이 root에게 소유되어 있기 때문입니다(또는 상위 디렉터리가?).

아마도 Ubuntu에서는 기본적으로 그렇게 설정되어 있을 것입니다. Ubuntu에서 무엇이 다른지 알 수 없습니다.

/var/discourse/shared를 모든 사용자에게 쓰기 가능하도록 설정해 보고 작동하는지 확인해 볼 수 있습니다? 아니면 이제 --privileged 옵션 없이 작동하는지 확인해 볼 수도 있습니다.

권장되는 운영체제는 Ubuntu이고, 컨테이너 내부에는 Debian이 설치되어 있습니다(이제 CDCK가 호스트 OS로 사용하는 것이 Debian일 수도?). Fedora는 Ubuntu에 비해 많은 부분이 잠겨 있습니다. 이해하고 싶다면 대부분 혼자 해결해야 할 것입니다. 다만, 여기에서 꽤 자주 Fedora CentOS(Fedora가 Ubuntu보다 CentOS에 더 가깝습니다!)를 사용하는 사람이 한 명 이상 있다는 기억이 납니다. 다음 링크에 힌트가 있을 수 있습니다: MKJ's Opinionated Discourse Deployment Configuration

부트스트랩 스크립트가 /var/discourse/shared 안에 하위 디렉터리를 생성하려고 할 때 유효한 uid가 무엇인지 궁금합니다. Docker가 root로 실행되고 있으므로 root일 것이라고 생각했는데, apparently 그렇지 않은 것 같습니다?

안타깝게도 --privileged 옵션에 대한 내용은 찾을 수 없었지만, Docker 대신 Podman으로 이 모든 작업을 처리하고 싶은 그의 바람에는 공감합니다.

네, Fedora에서 프로덕션 Discourse를 실행해 본 적은 없고, Fedora에서 Discourse 개발만 해 봤으며 그것도 42 버전은 아니었습니다. 현재 제 Discourse 서버들은 AlmaLinux 9를 사용 중이며, 거기서는 --privileged 옵션이 필요하지 않습니다. 제 Fedora 시스템 중 어느 곳에도 Docker가 설치되어 있지 않습니다.

시간이 날 때, --privileged 없이 해당 디렉토리의 소유자가 무엇이어야 하는지 결정하는 것을 시도해 볼 생각입니다.

--privileged 옵션을 살펴보니 SELinux 프로세스 라벨을 비활성화한다는 것을 확인할 수 있습니다.

저는 Discourse 서버에서 SELinux를 비활성화하지 않고 있으며, 실제로 제 가이드에는 외부 nginx를 사용하면서 SELinux를 활성화된 상태로 유지하는 방법에 대한 지침도 포함되어 있습니다. 또한 관련 거부 사항을 확인하기 위해 avc 로그를 확인하고, audit2allow를 사용하여 로컬 정책을 작성할 수도 있습니다. 하지만 이는 시간이 오래 걸리는 반복적인 과정이 될 수 있습니다. 처음부터 다시 시작하여(/var/discourse를 지우고) 유효한 테스트인지 확인하고, SELinux를 비활성화한 상태에서(예: setenforce 0) 여전히 --permissive가 필요한지 살펴보는 것이 좋습니다. 그렇게 하면 setenforce 0은 avc 항목을 여전히 기록하지만 첫 번째 게이트에서 더 이상 차단되지 않으므로, audit2allow를 사용하여 작동하는 정책에 더 빠르게 도달할 수 있습니다.

가능하다면 프로덕션 시스템에서 --privileged를 계속 사용하길 원하지는 않을 것입니다.