Нужна помощь с dual container. Проблема с LetsEncrypt уже несколько дней

Я уже дошёл до отчаяния, потому что попытки заставить бота Discourse или Claude исправить эту проблему кажутся невозможными. Я не могу внятно описать проблему, так как не обладаю достаточными знаниями, и, я думаю, именно это меня и бесит больше всего.

Я постараюсь объяснить, что произошло, с моей точки зрения.

Когда я переходил с одного контейнера на два, файл в samples/ использовал web-only, и я по ошибке оставил его как есть, вместо того чтобы использовать web_only.

Затем, из-за этого (по моему мнению), у меня не загружались изображения, потому что один «элемент» ожидал указание на web_only, но там было установлено web-only. Я внёс некоторые изменения, и изображения заработали. Но теперь проблема в сертификатах Let’s Encrypt.

Я попросил бота помочь мне это исправить. Он сказал мне подождать до следующего дня, так как проблема была в ограничении частоты (rate-limit) сертификатов. Проблема должна была решиться. Но она не решилась. Затем я спросил его снова, потом спросил Claude, потом снова Claude… и мы уже неделю сидим в этом режиме «подожди до завтра в X часов, и это ТОЧНО будет исправлено». Это никогда не исправляется. Оба говорят: «О, извините, я не должен был предполагать, что это решится, давайте попробуем вот это, потому что теперь это действительно будет исправлено». Но это не работает.

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

Claude сказал мне добавить что-то в хуки в web_only.yml, но поскольку ничего подобного не упоминается в инструкциях, предоставленных здесь на форуме, я ожидал какого-то другого решения, например… решения самой проблемы.

Пожалуйста, кто-нибудь помогите мне разобраться, в чём заключается проблема и где именно всё ломается? Я был бы очень благодарен, потому что на данный момент это изматывает. Не сама работа, а то, что я не понимаю, что происходит и почему «подождать до завтра» никогда не приводит к решению.

Спасибо!


Я попросил Claude объяснить, в чём, по его мнению, заключается проблема, может быть, это поможет? Вот что он сказал:

Заголовок: Двухконтейнерная конфигурация: папка ECC-сертификатов отсутствует после разделения, цикл --force приводит к превышению лимита запросов при каждом запуске

Конфигурация: Два контейнера (data + web_only), миграция из standalone. Шаблоны: web, ratelimited, ssl, letsencrypt, cloudflare. Имя хоста alltiago.com, без алиасов.

Симптом: При каждом запуске web_only срабатывает лимит частоты Let’s Encrypt, и nginx не может обслуживать запросы, возвращая ошибки соединения, пока строки ECC не будут вручную удалены из /etc/nginx/conf.d/outlets/server/20-https.conf.

Что я обнаружил:

Папка /shared/letsencrypt/alltiago.com_ecc/ отсутствует в моей установке. Папка /shared/letsencrypt/alltiago.com/ (RSA) существует и работает нормально, сертификаты обновляются штатно.

В web.letsencrypt.ssl.template.yml:

cert_exists() {
  [[ "$(cd ${LETSENCRYPT_DIR}/${DISCOURSE_HOSTNAME}$1 && openssl verify -CAfile <(openssl x509 -in ca.cer) fullchain.cer | grep "OK")" ]]
}

issue_cert "ec-256"
if ! cert_exists "_ecc"; then
  issue_cert "ec-256" "--force"
fi

Так как папка отсутствует, cert_exists "_ecc" возвращает false при каждом запуске, поэтому запускается --force, и запрашивается совершенно новый ECC-сертификат, независимо от того, что находится на диске. Это происходит через хук after_ssl, который патчит /etc/runit/1.d/install-ssl, поэтому он выполняется при каждом запуске контейнера, а не только при первичной настройке (bootstrap).

Результат: ошибка 429 too many certificates (5) already issued for this exact set of identifiers in the last 168h (слишком много сертификатов (5) уже выдано для этого точного набора идентификаторов за последние 168 часов). Затем --installcert выполняется всё равно против пустой папки и записывает нерабочий /shared/ssl/alltiago.com_ecc.cer. В nginx настроены оба сертификата, он не может загрузить ECC-сертификат и не может обслуживать запросы.

Подтверждено работающим: Валидация ACME HTTP-01 проходит успешно (проверено через staging, ECC-сертификат успешно выпущен для letsencrypt_test, создана правильная структура папок). RSA-сертификат успешно обновился сегодня. Так что дело не в DNS, файрволе или валидации.

Вопросы:

  1. Есть ли поддерживаемый способ пересоздать папку alltiago.com_ecc/, не дожидаясь истечения лимита частоты?
  2. Должен ли возврат false от cert_exists действительно запускать --force, а не обычный запрос? --force обходит проверку «существующий действительный сертификат» и гарантирует исчерпание лимита частоты, если папка отсутствует.
  3. Есть ли задокументированный способ работать только с RSA?

Два фактических примечания, чтобы тема не ушла в сторону: дата повторной попытки сдвинулась с 27 августа на 29 августа, потому что обновление RSA сегодня заняло слот в скользящем 168-часовом окне. И причина, по которой другие не сообщают об этом, заключается в том, что при обычной установке обе папки создаются при первом запуске, и ветка --force никогда не выполняется.

Подожди. https://alltiago.com/ кажется, работает без проблем. Но вот что я бы порекомендовал

Да, но это сложно. Если ты запросишь ДРУГОЙ сертификат, то сможешь начать отсчет заново.

Я бы, скорее всего, порекомендовал добавить www к имени хоста, чтобы получить сертификаты для обоих (но возможно, ты уже это сделал, тогда можно добавить третье имя, просто чтобы получить новый сертификат).

Set up Let’s Encrypt with multiple domains / redirects должен помочь.

Да, всё так, потому что мне сказали использовать «пластырь», связанный с nginx. Я не могу в полной мере объяснить, что это такое, так как сам это не понимаю.
Но проблема в том, что если я потом захочу выполнить обычную пересборку, у меня возникнут трудности (по крайней мере, так мне сказали, если я сделаю это до 29 августа, когда, надеюсь, сертификат будет перевыпущен. На данный момент я не могу полностью доверять ни одному из этих утверждений).

Да, www уже был добавлен ещё при моей первой установке Discourse в прошлом году.

Теперь, после того как я заставил Claude выложиться по полной, чтобы помочь мне понять, что происходит, вот что я выяснил. Не стесняйтесь оспаривать это, потому что я готов учиться, когда это возможно:

  • ECC, который, похоже, является проблемой сейчас, на самом деле не является строго необходимым, потому что RSA — это значение по умолчанию, и все смогут продолжать обращаться к моему сайту без проблем, если я полностью откажусь от ECC.
  • Как я уже сказал, надеюсь, что 29 августа вся эта проблема исчезнет, как только 168-часовое окно сбросится и лимит в 5 сертификатов также будет сброшен:
sudo docker exec web_only grep -i "retry after" /shared/letsencrypt/acme.sh.log | tail -1
  "detail": "too many certificates (5) already issued for this exact set of identifiers in the last 168h0m0s, retry after 2026-08-29 03:43:15 UTC: see https://letsencrypt.org/docs/rate-limits/#new-certificates-per-exact-set-of-identifiers",
  • Если 29 августа всё не вернётся в норму, Claude рекомендует отказаться от ECC. Вот что он сказал, когда я спросил, какой файл будет изменён и какой раздел:

Файл: копия, которую мы собираемся создать, web.letsencrypt.rsa-only.template.yml (оставив ваш исходный стандартный файл нетронутым в качестве резервного варианта).

Что будет удалено из него: весь этот блок, найденный в разделе /usr/local/bin/letsencrypt файла:

########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"

if ! cert_exists "_ecc"; then
  # Try to issue the cert again if something goes wrong
  issue_cert "ec-256" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh \
  --installcert --ecc \
  -d ${DISCOURSE_HOSTNAME} \
  --fullchainpath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.cer \
  --keypath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.key \
  --reloadcmd "sv reload nginx"

Это весь раздел ECC, в остальной части файла ничего не меняется. Раздел RSA прямо над ним остаётся в точности таким, какой есть.

Ещё один файл будет затронут после этого: containers/web_only.yml, чтобы указать на эту новую копию вместо стандартного шаблона. Мы сделаем это отдельным, более поздним шагом.

Да. Нет. Я бы не стал менять ни один шаблон.

Думаю, самый простой способ — подождать, а затем пересобрать всё с помощью стандартных шаблонов. Если только вы не хотите, чтобы с этого момента вам помогал ИИ, а не кто-то, кто действительно знает, как пользоваться Discourse.

Я попросил Claude следовать вашему совету, добавив www как новый запрос сертификата (если так это называется?). Похоже, теперь всё работает.

Когда я спросил, какие файлы являются остатками от всего этого процесса, я получил вот такой ответ:

Вот что реально есть, разделено на то, что появилось сегодня ночью, и старые остатки, появившиеся до этого разговора:

Сегодня ночью (в этой сессии):

  • /tmp/acme.sh.txt — копия скрипта, которую вы просили скачать; теперь, когда у вас есть копия на Mac, её можно безопасно удалить
  • /tmp/crtsh.json — пустой файл размером 150 байт, возникший из-за ошибки 502 от crt.sh; мусор, можно безопасно удалить
  • /root/discourse-backup-20260827-1857.tar.gz — настоящая резервная копия от начала этой ночи (настройки SSL/letsencrypt); её действительно стоит сохранить, это не мусор

Старые, от до начала этого разговора (23 и 25 августа), я их туда не клал:

  • /tmp/app.yml
  • /tmp/check.png, /tmp/check162.png, /tmp/after.png, /tmp/rendered_avatar.png

Я не знаю, для чего нужны эти старые файлы. Они появились раньше того, что мы делали сегодня ночью, скорее всего это остатки от предыдущей сессии по устранению неполадок (вашей, бота или предыдущего чата с Claude). Вы их узнаёте, или хотите, чтобы я помог разобраться, откуда они взялись, прежде чем решать, удалять ли их?

Ничего подозрительного не было найдено за пределами /tmp и /root, общий сканирование системы показало, что всё чисто, только обычные файлы журналов.


Могу я просто удалить все эти файлы?

Мне тогда стоит отменить то, что я только что сделал?

Мне совершенно не против общаться с живыми людьми, но я просто не хочу задавать все вопросы здесь и засорять форум всем процессом (вывод/логи из Терминала). Вместо этого я скорее хотел бы предложить что-то, что уже «более-менее» работает, чтобы сделать разговор чуть короче. У всех у нас есть своя жизнь и ограниченное время, и я не хочу сразу же бежать на форум, если только я не упрусь в тупик, понимаете?

Я ценю вашу помощь!
Так что, мне сейчас стоит отменить то, что я сделал? Вы видите какие-либо проблемы с таким подходом по сравнению с тем, чтобы просто подождать до 29-го?