Нет защищённого соединения с самостоятельно размещённым Discourse после последнего обновления

Привет. Несколько часов назад я обновил Discourse Image и Discourse, выполнив команду ./launcher rebuild app. В процессе возникли ошибки, которые были устранены удалением устаревших строк установки плагинов из файла app.yml. Других изменений конфигурации не вносилось. Сейчас Docker-контейнер запущен и прослушивает TCP-порты 80 и 443, но nginx внутри контейнера отказывается принимать SSL/TLS-соединения. В файле error.log внутри контейнера ошибок нет, access.log не показывает запросов, подключение к порту 443 через telnet отвергается. HTTP-доступ через порт 80 работает, но возникают проблемы с аутентификацией SSO (вероятно, это связано с куками, требующими защищённого соединения). Перезапуск Launcher и выполнение discourse-doctor не помогли. Перезапуск nginx внутри контейнера также не дал результата. Куда теперь смотреть и что делать?

Так и будет, если включен ufw и не настроено разрешение подключений на https-порт 443.


Редакция: для корректной работы mail-receiver этот порт должен быть открыт.

Я ничего не менял в конфигурации ufw, iptables и т.д. Порт был открыт до обновления. Могла ли конфигурация измениться в процессе обновления Discourse?

Конечно, можно. Контейнер Docker с Discourse должен находиться перед ufw. Однако отсутствие открытого порта 443 вызывает проблемы во взаимодействии между разными контейнерами или проблемы с telnet.


Что возвращает команда .\launcher logs app? (Вы можете использовать MS Word, чтобы скрыть доменное имя и т. д.)

Доступите ли вы к своему серверу через PuTTY или другой SSH-клиент? Открыт ли порт 22?

Я также наблюдаю эту проблему на саморазмещенном экземпляре после недавнего пересборки. Изменений в конфигурации не было, кроме самой пересборки. Я могу получить доступ к серверу через SSH, и вот вывод команды ./launcher logs app.


run-parts: executing /etc/runit/1.d/00-ensure-links
run-parts: executing /etc/runit/1.d/00-fix-var-logs
run-parts: executing /etc/runit/1.d/01-cleanup-web-pids
run-parts: executing /etc/runit/1.d/anacron
run-parts: executing /etc/runit/1.d/cleanup-pids
Cleaning stale PID files
run-parts: executing /etc/runit/1.d/copy-env
run-parts: executing /etc/runit/1.d/install-ssl
Started runsvdir, PID is 45
ok: run: redis: (pid 55) 0s
supervisor pid: 53 unicorn pid: 76

Docker-контейнер запущен, что подтверждается выводом команды docker ps. (ID контейнера удален)

local_discourse/app “/sbin/boot” 16 минут назад Up 16 минут 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp app

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

Похоже, есть несоответствие между IP-адресом, который ожидает nginx (локальный IP 127.0.0.1), и тем, который назначен контейнеру. Похоже, контейнер может работать в режиме bridge? Вот настройки сети контейнера. (Обратите внимание, что этот лог взят из момента, когда я впервые выявил эту проблему в пятницу и начал расследование)

"Labels": {
    "org.opencontainers.image.created": "2025-07-25T21:40:36+00:00"
},
"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "[REDACTED]",
    "SandboxKey": "[REDACTED]",
    "Ports": {
        "443/tcp": [
            {
                "HostIp": "0.0.0.0",
                "HostPort": "443"
            },
            {
                "HostIp": "::",
                "HostPort": "443"
            }
        ],
        "5432/tcp": [
            {
                "HostIp": "0.0.0.0",
                "HostPort": "5432"
            },
            {
                "HostIp": "::",
                "HostPort": "5432"
            }
        ],
        "80/tcp": [
            {
                "HostIp": "0.0.0.0",
                "HostPort": "80"
            },
            {
                "HostIp": "::",
                "HostPort": "80"
            }
        ]
    },
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "SecondaryIPAddresses": null,
    "SecondaryIPv6Addresses": null,
    "EndpointID": "[REDACTED]",
    "Gateway": "172.17.0.1",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "IPAddress": "172.17.0.2",
    "IPPrefixLen": 16,
    "IPv6Gateway": "",
    "MacAddress": "[REDACTED]",
    "Networks": {
        "bridge": {
            "IPAMConfig": null,
            "Links": null,
            "Aliases": null,
            "MacAddress": "[REDACTED]",
            "DriverOpts": null,
            "GwPriority": 0,
            "NetworkID": "[REDACTED]",
            "EndpointID": "[REDACTED]",
            "Gateway": "172.17.0.1",
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "DNSNames": null
        }
    }
}

Похоже, что недавно принятый PR добавил новое требование к переменной в файле app.yml. Это пока не задокументировано, но вам необходимо добавить ENABLE_SSL: true в ваш файл app.yml.

Звучит как ошибка. SSL уже несколько лет включён по умолчанию. Можете дать ссылку на коммит?

Я вижу это в коде шаблона SSL. Возможно, я что-то упускаю, так как сижу с телефона, а GitHub работает с перебоями, но кажется, что это сломает каждый саморазмещённый сайт.

Это именно здесь, безусловно, непреднамеренная ошибка при слиянии конфигурации ssl-on-boot:

Я обновил ENABLE_SSL, чтобы по умолчанию он был равен 1 здесь:

Спасибо, что заметили это @tanya_byrne

Отличное спасение, Джефф! Спасибо!

Спасибо за исправление, @featheredtoast

Спасибо, ребята. Мы тоже решили проблему.