ArgumentError: pid=/.../unicorn.pid 디렉토리에 쓰기 권한이 없습니다

참고할 가치가 있다면, unicorn.stderr.log의 끝부분은 다음과 같습니다

I, [2023-08-22T04:18:52.795267 #81]  INFO -- : Refreshing Gem list
fatal: detected dubious ownership in repository at '/var/www/discourse'
To add an exception for this directory, call:

	git config --global --add safe.directory /var/www/discourse
I, [2023-08-22T04:18:57.742262 #81]  INFO -- : listening on addr=127.0.0.1:3000 fd=10
fatal: detected dubious ownership in repository at '/var/www/discourse'
To add an exception for this directory, call:

	git config --global --add safe.directory /var/www/discourse
I, [2023-08-22T04:19:04.916798 #81]  INFO -- : starting 1 supervised sidekiqs
I, [2023-08-22T04:19:04.927971 #81]  INFO -- : starting up EmailSync demon
I, [2023-08-22T04:19:07.993280 #81]  INFO -- : master process ready
I, [2023-08-22T04:19:11.010040 #174]  INFO -- : worker=0 ready
I, [2023-08-22T04:19:11.994849 #188]  INFO -- : worker=1 ready
I, [2023-08-22T04:19:12.524936 #203]  INFO -- : worker=2 ready

Ubuntu 22.04 (Server)

클라우드 호스터에서 새로 설정했습니다. 시스템 업데이트, docker, zsh, nginx 설치 및 discourse 설정 실행만 했는데 실패했습니다.

수정:

클라우드 서버를 Fedora로 재구성하고, docker만 설치한 뒤 새로 설치를 다시 시도했습니다.

또 다른 오류가 발생했습니다.

[Tue 22 Aug 2023 05:51:02 PM UTC] Run reload cmd: sv reload nginx
warning: nginx: unable to open supervise/ok: file does not exist
[Tue 22 Aug 2023 05:51:02 PM UTC] Reload error for :
Started runsvdir, PID is 2941
ok: run: redis: (pid 2953) 0s
ok: run: postgres: (pid 2954) 0s
supervisor pid: 2949 unicorn pid: 2981

내부 nginx가 실행되지 않습니다.

잠깐, 왜 nginx를 설치했나요? 호스트에서 이미 포트 80을 사용하는 것이 있으면 기본 설치가 실패합니다.

새로운 Digital Ocean 드롭렛에서는 공식 설치 가이드에 나와 있지 않은 것을 하지 않았고, 정상적으로 작동했습니다. Discourse 설치 프로그램이 docker를 설치하도록 하고 모든 것을 맡겼습니다.

이 문제를 재현하는 것이 까다롭네요.

네, 그렇게 보입니다. 여러 명이 이 문제를 보고했기 때문에(@DarthLasciel, @Godmar_Back, 그리고 아마도 @kdambekalns) 실제로 존재하는 것 같습니다.

제 설치 환경에서 확인해 보고 싶은 것이 있다면 알려 주세요.

호스트에 추가 패키지를 설치하지 않고, 공식 설치 가이드를 엄격히 따르며 완전히 새로운 서버에서 새로운 서브도메인으로 프로비저닝을 시도해도 문제가 여전히 발생합니까?

또한 [redacted] app.yml 파일을 공유해 주실 수 있을까요?

특히 DISCOURSE_SMTP_PASSWORD 환경 변수와 기타 민감한 정보들은 반드시 마스킹(편집)해 주세요.

그리고:

URL에 ?safe_mode=no_plugins를 추가해 보시겠습니까?

성공한다면 플러그인 오류일 가능성이 있습니다.

서브도메인 부분을 제외하고는 정확히 그렇게 했습니다.
새로운 Fedora 서버를 설치하고, docker를 설치한 후 discourse를 설치했으며, 서버에 nginx를 설치하지 않은 상태로 설정을 진행했습니다. 그 결과 위에 게시된 오류가 발생했습니다.

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "9980:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  #db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

env:
  LC_ALL: de_DE.UTF-8
  LANG: de_DE.UTF-8
  LANGUAGE: de_DE.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  #UNICORN_WORKERS: 3

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'redacted.de'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'me@example.com,you@example.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: none.com
  #DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: user@none.com
  DISCOURSE_SMTP_PASSWORD: none
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (required by some providers)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (address to send notifications from)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
  ## The maxmind geolocation IP address key for IP address lookup
  ## see https://meta.discourse.org/t/-/137387/23 for details
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

unicorn.pid 파일이 쓰기 가능하지 않아 같은 권한 문제를 겪고 있습니다. 공식 설치 가이드로 재현되는지 확인해 더 많은 정보를 드리고 싶었지만, 제 시스템에는 맞지 않았습니다. 먼저 포트 80/443이 이미 사용 중이라는 오류가 발생했고, 이후 실행된 이메일 검사도 실패했습니다. 외부 의존성이 전혀 없는 Docker 이미지만 생성하는 app.yml 파일이 있으신가요? 아마 이 동일한 문제는 그 환경에서도 똑같이 재현될 것 같습니다.

문제를 "해결"했는데, 정말 멍청하다고 느껴집니다.

Docker를 "올바른 방법"으로 설치하는 대신, 그냥 "sudo apt install docker-compose"를 입력하고 그대로 진행했습니다. Docker가 "동작하는 것 같"았죠… 그랬던 것 같…

Docker 가이드에 나와 있는 대로 재설치했습니다. 추가 리포지토리, 키링, 그 모든 걸 다요… 그리고 Discourse가 실행됩니다!

결국 엉망진창인 Docker 설치 때문이었습니다. 최신 버전의 Docker를 설치하는 것이 왜 아직도 이렇게 어려운지 정말 모르겠어요. 그리고 docker-compose를 드디어 Docker에 통합한 것 같네요 (그래서 docker compose ...를 사용할 수 있게 되었습니다). 다만 저는 아직 그 부분에 대해 자세히 살펴보지는 않았습니다.

@rtwfroody님과 @StanD님, 이 방법으로 문제도 해결되나요?

하지만 우리는 도커-컴포즈를 전혀 사용하지 않습니다

좋은 소식이지만, 우리의 가이드에는 그런 것이 전혀 요구되지 않습니다. discourse-setup을 실행하면 도커가 자동으로 설치됩니다.

docker 설치가 정상적인 것 같고, docker compose도 사용하지 않고 있습니다. 솔직히 제가 한 일은 더 이상 필요 없는 플러그인(discourse-checklist)을 제거하고, 수년간 문제없이 운영해 온 최신 상태의 셀프호스팅 인스턴스에 대해 rebuild를 실행한 것뿐입니다.

불행히도 지난 24시간 동안 본업 때문에 이 문제를 조사할 여유가 없었습니다. 오늘 저녁에 다시 확인해 보겠습니다. 더 많은 정보를 제공할 수 있을지 알아볼 예정입니다.

EC2(Ubuntu 22.04.3 LTS)에서 신규 설치를 진행할 때 동일한 문제를 겪었습니다.
이전에도 discourse를 설정해 본 경험이 있었습니다(대략 2~3회 정도).

처음에는 빌드 문제라고 생각하여 ./launcher rebuild app을 여러 번 실행했는데, 그 결과 Let’s Encrypt가 제공하는 주간 SSL 인증서 발급 한도를 소진하게 되어 웹사이트가 site cant be reached error를 표시하게 되었습니다.

이후 ./launcher logs app을 시도해 보았으며, 다음과 같은 오류가 표시되었습니다:

  1. directory for pid=/var/www/discourse/tmp/pids/unicorn.pid not writable (ArgumentError).
  2. "detail": "Error creating new order :: too many certificates (5) already issued for this exact set of domains in the last 168 hours - Let’s Encrypt Rate-limit issue

공식 가이드와 다르게 한 것 중 유일한 것은 docker 설치 방식이었습니다.

sudo apt install docker.io를 사용하여 docker를 설치했습니다. 이 설치를 완전히 제거하고 ./discourse-setup을 통해 docker 설치를 진행하도록 했습니다.

그리고 성공했습니다!!

@pfaffman이 말했듯이 docker 설치 관련 문제였습니다.

PS: discourse 서버를 최우선으로 설정해야 했기 때문에 2번째 설치 시에는 새로운 서브도메인으로 진행했습니다.

@pfaffman님과 @csgeek님이 하신 말씀에 동의하며, 제 경우에는 다음과 같은 방법으로 해결되었습니다:

  1. apt remove docker.io를 실행하여 docker.io (20.10.25-0ubuntu1~22.04.1)를 제거합니다.
  2. ./discourse-setup을 실행하여 docker가 설치될 때까지 기다린 후, 해당 프로세스를 종료합니다.
  3. systemctl start docker
  4. ./launcher rebuild app

이 환경은 Ubuntu 22.04.3 LTS가 설치된 시스템입니다.

안녕하세요, @jeanas. 이 방법이 해결책일 것 같습니다. 아래 내용을 시도해 주시겠어요?

위 방법으로 문제가 해결된다면, 해당 게시물을 해결책으로 표시해 주시겠어요?

[참고: 제 문제는 엄밀히 말하면 #installation 문제가 아니지만, 발생한 오류는 이 주제에서 언급된 것과 동일하며, 아래에 제시한 해결 방법은 다른 분들에게 도움이 될 수 있습니다. 관리자분들(@pfaffman?)께서는 더 적절한 카테고리로 분류해 주셔도 됩니다.]

자신만의 서버를 Docker로 구축한 인스턴스(수년 동안 설치되어 정상 작동 중)에서 ./launcher rebuild app 명령을 실행한 후 ArgumentError 메시지가 나타납니다. 이는 unicorn이 컨테이너 내부의 /var/www/discourse/tmp/pids 디렉토리에 pid 파일을 작성할 수 없기 때문에 발생합니다. 로그에는 해당 파일을 몇 초마다 작성하려는 시도가 반복되며 ArgumentError 메시지가 루프 형태로 출력됩니다.

호스트 머신에서 컨테이너로 로그인하려면 다음을 실행합니다.

docker exec -it app bash

컨테이너 내부에서 다음을 실행합니다.

find /var/www/discourse -printf '%u:%g\n'  | sort -t: -u

이 명령은 해당 디렉토리의 소유자:그룹 목록을 보여줍니다.

root:root
discourse:discourse

이후 /var/www/discourse/tmp/pids 디렉토리를 모든 사용자에게 읽기 가능하도록 설정합니다.

chmod +r /var/www/discourse/tmp/pids

이 시점에서 해당 디렉토리에 unicorn.pid 파일이 생성됩니다. 이 파일의 소유자:그룹은 discourse:www-data입니다.

제 해결 방법은 /var/www/discourse의 소유권을 재귀적으로 discourse:www-data로 변경하는 것이었습니다.

chown -R discourse:www-data /var/www/discourse

파일 수가 100,000개를 초과하기 때문에 이 작업에는 상당한 시간이 소요됩니다. 전체 디렉토리에 대해 수행할 필요는 없지만, 저는 그렇게 했습니다.

마지막으로, /etc/postgres/13/main/pg_hba.conf 파일을 모든 사용자에게 읽기 가능하도록 설정했습니다.

chmod +r /etc/postgres/13/main/pg_hba.conf

컨테이너를 재시작하면 모든 것이 정상 작동합니다.

파일 소유권 설정이 정확하지 않은 것으로 보이지만, 권한 설정에 충분히 정통하지 않아 더 간단한 해결 방법을 찾지 못했습니다. unicorn.pid 파일의 그룹이 www-data인 것이 핵심인 것 같습니다.

rebuild를 수행할 때마다(즉, app.yml 파일을 변경할 때마다) 이 절차를 반복해야 할 것으로 보입니다. 또한 특정 플러그인 문제인 것 같지는 않습니다.

개발자 중 한 분이 이 정보를 보고 "물론이죠! x만 변경하면 됩니다"라고 말해 주시길 바랍니다.

아마도 당신의 문제는 다른 사람들과 다를 수 있습니다. 어떤 버전의 Docker를 사용 중이며, 어떻게 설치하셨나요?

오래동안 정상적으로 작동하던 Docker가 문제일 것이라고 생각하기에는 말이 안 된다는 데 동의합니다.

서버에서 docker --version을 실행하면 다음과 같은 결과가 반환됩니다.

Docker version 20.10.25, build 20.10.25-0ubuntu1~22.04.1

최신 버전이 아닌 것 같습니다?

저는 @StanD 님에게 이 버전의 Docker가 잘 작동했다고 말씀드렸습니다.

Docker version 24.0.5, build ced0996.

이것을 시도해 볼 수 있습니다.

네! 제게도 잘 작동했습니다.

제 경험과 @Stand의 경험을 종합해 보면, Discourse가 구버전 Docker에서는 더 이상 작동하지 않는 것 같습니다.