ArgumentError: каталог для pid=/.../unicorn.pid не доступен для записи

Вот конец моего файла unicorn.stderr.log, если это имеет значение

I, [2023-08-22T04:18:52.795267 #81]  INFO -- : Обновление списка Gem
fatal: обнаружена ненадёжная принадлежность репозитория в '/var/www/discourse'
Чтобы добавить исключение для этой директории, выполните:

	git config --global --add safe.directory /var/www/discourse
I, [2023-08-22T04:18:57.742262 #81]  INFO -- : прослушивание addr=127.0.0.1:3000 fd=10
fatal: обнаружена ненадёжная принадлежность репозитория в '/var/www/discourse'
Чтобы добавить исключение для этой директории, выполните:

	git config --global --add safe.directory /var/www/discourse
I, [2023-08-22T04:19:04.916798 #81]  INFO -- : запуск 1 управляемого sidekiq
I, [2023-08-22T04:19:04.927971 #81]  INFO -- : запуск демона EmailSync
I, [2023-08-22T04:19:07.993280 #81]  INFO -- : главный процесс готов
I, [2023-08-22T04:19:11.010040 #174]  INFO -- : worker=0 готов
I, [2023-08-22T04:19:11.994849 #188]  INFO -- : worker=1 готов
I, [2023-08-22T04:19:12.524936 #203]  INFO -- : worker=2 готов

Ubuntu 22.04 (сервер)

Свежая установка от облачного хостера. Я ничего не делал, кроме обновления системы, установки Docker, zsh, nginx и запуска настройки Discourse, которая завершилась ошибкой.

Редактирование:

Я пересоздал облачный сервер с Fedora, только что установил Docker и снова попытался выполнить чистую установку.

Другая ошибка:

[Tue 22 Aug 2023 05:51:02 PM UTC] Выполнение команды reload: sv reload nginx
warning: nginx: не удалось открыть supervise/ok: файл не существует
[Tue 22 Aug 2023 05:51:02 PM UTC] Ошибка перезагрузки для :
Запущен runsvdir, PID = 2941
ok: run: redis: (pid 2953) 0s
ok: run: postgres: (pid 2954) 0s
pid супервизора: 2949 pid unicorn: 2981

Внутренний nginx не хочет запускаться.

Подождите, зачем вы установили nginx? При стандартной установке возникнет ошибка, если порт 80 уже занят на хосте.

На новом сервере Digital Ocean я ничего не делал, кроме того, что указано в официальной инструкции по установке, и всё сработало отлично. Я позволил установщику Discourse самостоятельно установить Docker и всё остальное.

Попытки воспроизвести эту проблему оказываются сложными.

Да, похоже на то. Это точно имеет место, так как я видел, как несколько человек сообщали об этом (@DarthLasciel, @Godmar_Back и, возможно, @kdambekalns).

Дайте знать, если вам нужно что-то увидеть с моей установки.

Проблема всё ещё возникает, если вы попытаетесь выполнить развёртывание на новом поддомене на совершенно новом сервере, строго следуя нашему официальному руководству по установке, и воздержитесь от установки каких-либо дополнительных пакетов на хосте?

Также, пожалуйста, поделитесь вашим [redacted] app.yml?

В частности, пожалуйста, убедитесь, что вы скрыли переменную окружения DISCOURSE_SMTP_PASSWORD и любые другие конфиденциальные данные.

Также:

Попробуйте добавить к URL следующее: ?safe_mode=no_plugins

Если это сработает, это может указывать на ошибки в плагинах.

За исключением части с поддоменом, я сделал именно это.
Новый Fedora Server, установка Docker, установка Discourse, настройка без Nginx на сервере. Результат — ошибка, описанная выше.

## это шаблон контейнера Docker Discourse all-in-one, standalone
##
## После внесения изменений в этот файл вы ОБЯЗАНЫ выполнить пересборку
## /var/discourse/launcher rebuild app
##
## БУДЬТЕ *ОЧЕНЬ* ОСТОРОЖНЫ ПРИ РЕДАКТИРОВАНИИ!
## YAML-ФАЙЛЫ ЧРЕЗВЫЧАЙНО ЧУВСТВИТЕЛЬНЫ К ОШИБКАМ В ПРОБЕЛАХ И ВЫРАВНИВАНИИ!
## для проверки файла используйте http://www.yamllint.com/

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Раскомментируйте следующую строку, чтобы включить слушатель IPv6
  #- "templates/web.ipv6.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:
  - "9980:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Установите db_shared_buffers максимум на 25% от общего объёма памяти.
  ## будет установлено автоматически при загрузке на основе обнаруженной RAM, или вы можете переопределить
  #db_shared_buffers: "256MB"

  ## может улучшить производительность сортировки, но увеличивает использование памяти на подключение
  #db_work_mem: "40MB"

  ## Какую ревизию Git должен использовать этот контейнер? (по умолчанию: 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

  ## Сколько одновременных веб-запросов поддерживается? Зависит от памяти и ядер CPU.
  ## будет установлено автоматически при загрузке на основе обнаруженных CPU, или вы можете переопределить
  #UNICORN_WORKERS: 3

  ## TODO: Доменное имя, на которое будет отвечать этот экземпляр Discourse
  ## Обязательно. Discourse не будет работать с чистым IP-адресом.
  DISCOURSE_HOSTNAME: 'redacted.de'

  ## Раскомментируйте, если хотите, чтобы контейнер запускался с тем же
  ## именем хоста (опция -h), как указано выше (по умолчанию "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Список email-адресов через запятую, которые станут администраторами и разработчиками
  ## при первой регистрации, например 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'me@example.com,you@example.com'

  ## TODO: SMTP-сервер для проверки новых аккаунтов и отправки уведомлений
  ## Адрес SMTP, имя пользователя и пароль обязательны
  # ВНИМАНИЕ: символ '#' в пароле SMTP может вызвать проблемы!
  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           # (опционально, по умолчанию true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (требуется некоторыми провайдерами)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (адрес для отправки уведомлений)

  ## Если вы добавили шаблон Lets Encrypt, раскомментируйте ниже, чтобы получить бесплатный SSL-сертификат
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## Адрес CDN http или https для этого экземпляра Discourse (настроен на получение)
  ## см. https://meta.discourse.org/t/14857 для деталей
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
  ## Ключ IP-адреса MaxMind для геолокации
  ## см. https://meta.discourse.org/t/-/137387/23 для деталей
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## Контейнер Docker не хранит состояние; все данные сохраняются в /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 "Начало пользовательских команд"
  ## Если вы хотите установить адрес электронной почты 'From' для первой регистрации, раскомментируйте и измените:
  ## После получения первого письма о регистрации закомментируйте строку обратно. Она нужна только один раз.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Конец пользовательских команд"

У меня та же проблема с правами доступа: файл unicorn.pid не записывается. Я хотел предоставить вам дополнительную информацию, проверив, воспроизводится ли проблема с официальным руководством по установке, но оно не подходит для моей системы. Сначала возникла ошибка, потому что порты 80/443 уже заняты, а затем не прошли проверки электронной почты. У вас есть файл app.yml, который создаёт Docker-образ, не требующий никаких внешних зависимостей? Предполагаю, что с его помощью та же проблема должна воспроизводиться так же легко.

Я «исправил» проблему, и мне невероятно стыдно.

Вместо того чтобы установить Docker «правильным» способом, я просто ввёл «sudo apt install docker-compose» и пошёл дальше. Docker «казался» рабочим… казался…

Я переустановил его так, как указано в руководстве по Docker, добавив дополнительный репозиторий, ключи и всё остальное… И Discourse запустился!

Итак, виновата неудачная установка Docker. Я действительно не понимаю, почему до сих пор так сложно установить актуальный и функциональный Docker. И, похоже, они наконец объединили docker-compose с docker (так что теперь можно использовать docker compose ...), хотя я пока не уделял этому особого внимания.

@rtwfroody и @StanD, это тоже решает вашу проблему?

Но мы вообще не используем docker-compose.

Хорошо, что у вас получилось, но в нашем руководстве ничего подобного не требуется. Достаточно запустить discourse-setup, и он сам установит Docker.

Я почти уверен, что установка Docker у меня в порядке, и я не использую Docker Compose. Честно говоря, я просто удалил плагин (плагин discourse-checklist, который больше не нужен) и запустил пересборку на самохостинговой, актуальной версии, которая годами работала без проблем.

К сожалению, моя основная работа не давала мне возможности разобраться в этом в последние 24 часа. Я должен вернуться к этому сегодня вечером. Посмотрю, смогу ли я предоставить больше информации.

У меня возникла та же проблема при чистой установке на EC2 (Ubuntu 22.04.3 LTS).
У меня уже был опыт настройки Discourse (примерно 2–3 раза).

Сначала я подумал, что проблема в сборке, и несколько раз запускал ./launcher rebuild app, из-за чего исчерпал недельный лимит сертификатов SSL, предоставляемый Let’s Encrypt. Именно поэтому сайт выдавал ошибку site can't be reached.

Позже я попробовал выполнить ./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

Единственное, чем я отличался от официального руководства, — это установка Docker.

Я установил Docker с помощью sudo apt install docker.io. Затем полностью удалил его и позволил ./discourse-setup выполнить установку Docker самостоятельно.

И всё заработало!!

Как и сказал @pfaffman, проблема была в установке Docker.

PS: Во второй раз при установке я перешёл на новое поддоменное имя, так как настройка сервера Discourse требовала срочности.

Поддерживаю сказанное @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. Похоже, это именно то, что нужно попробовать. Не могли бы вы сделать следующее:

Если это сработает у вас, не могли бы вы пометить его пост как решение?

[Примечание: Мой случай не совсем относится к проблеме #установки, но ошибка, которую я получаю, совпадает с той, что описана в этой теме, и моё решение (ниже) может помочь другим. Модераторы (@pfaffman?), пожалуйста, перенесите эту тему в более подходящий раздел, если это необходимо.]

Сообщение об ошибке ArgumentError появляется после выполнения команды ./launcher rebuild app на моём собственном сервере с Docker (установлен и работает уже много лет). Проблема возникает из-за того, что unicorn не может записать pid-файл в директорию /var/www/discourse/tmp/pids (внутри контейнера). В логе наблюдается цикл сообщений 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

Кажется, у меня может быть устаревшая версия?

Эта версия Docker подошла мне, @StanD.

Docker version 24.0.5, build ced0996.

Попробуйте это.

ДА! У меня это сработало.

Исходя из моего опыта и опыта @Stand, похоже, что Discourse больше не работает на старых версиях Docker.