HTTPS работает отлично, но HTTP-URL отображает приветственную страницу NGINX и не перенаправляет

Недавно я установил Discourse на VPS под управлением Ubuntu Focal Fossa, и всё работает отлично, однако я сталкиваюсь с некоторыми особенностями работы URL.

Ниже приведено поведение, которое я наблюдаю (в Safari). У меня настроены A-записи для @, WWW и * у моего регистратора доменных имен.

example.com [отображается страница «Welcome to nginx!»] FAIL
www.example.com [перенаправляет на https://example.com] PASS
http://example.com [отображается страница «Welcome to nginx!»] FAIL
http://www.example.com [перенаправляет на https://example.com и работает корректно] PASS
https://example.com [работает как ожидалось, перенаправления нет] PASS
https://www.example.com [ошибка с сообщением браузера «Это соединение не защищено»] FAIL

Я хотел бы разместить свою установку в корневой зоне (apex), поэтому при настройке указал example.com.

Буду очень благодарен за любые советы!

Запускаете ли вы внешний nginx на сервере Discourse? Зачем?

Discourse уже поставляется с предварительно настроенным nginx, который сможет это сделать, если вы разрешите ему прослушивать порты 80 и 443.

Привет @Falco, спасибо за ответ. Насколько мне известно, нет. Образ от провайдера VPS называется просто «Focal Fossa Clean OS», что, по-видимому, означает отсутствие сторонних инструментов.

Это установка «из коробки» по опубликованному сценарию на «30 минут».

sudo su

wget -qO- https://get.docker.com/ | sh

git clone https://github.com/discourse/discourse_docker.git /var/discourse

cd /var/discourse

./discourse-setup

Ох, это действительно странное поведение!

Можете поделиться здесь вашим app.yml (удалите конфиденциальные данные, например пароли). Файл находится по пути /var/discourse/containers/app.yml.

Также пришлите вывод команды docker ps -a.

Конечно, спасибо. Может ли странное расширение домена (TLD) вызвать какие-либо проблемы? (у меня .community).

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

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.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:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

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

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

  ## Какую ревизию Git должен использовать этот контейнер? (по умолчанию: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

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

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

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

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

  ## TODO: SMTP-сервер, используемый для проверки новых аккаунтов и отправки уведомлений
  ## Для работы требуются SMTP-адрес, имя пользователя и пароль
  ## ВНИМАНИЕ: символ '#' в пароле SMTP может вызвать проблемы!
  DISCOURSE_SMTP_ADDRESS: smtp.postmarkapp.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: username
  DISCOURSE_SMTP_PASSWORD: "password"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (опционально, по умолчанию true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (требуется некоторыми провайдерами)

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


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

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

и

CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                      NAMES
465fbf1c3fb8   local_discourse/app   "/sbin/boot"   47 минут назад   Up 46 минут   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   app

Возможно, в дистрибутиве, который вам предоставил провайдер, уже предустановлен nginx?

Что выводит команда curl -I localhost?

HTTP/1.1 301 Moved Permanently
Server : nginx/1.18.0
Date : Mon, 25 Jan 2021 20:18:00 GMT
Content-Type : text/html
Content-Length : 169
Connection : keep-alive
Location : https://example.com

Это значит, что он уже был установлен? (извините, я новичок в этом)

Это именно тот ожидаемый ответ при успешной работе. Значит, на http://example.com всё ещё отображается приветственная страница nginx?

https://example.com работает как часы, а http://example.com (HTTP) перенаправляет на страницу Welcome to nginx! :sob:

Можете указать фактический домен?

Итак, это совсем не выводит мне приветственную страницу nginx.

Можешь попробовать это на другом устройстве, например на телефоне?

curl -I example.com -L
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Mon, 25 Jan 2021 20:35:21 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/

HTTP/2 200 
server: nginx
date: Mon, 25 Jan 2021 20:35:22 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
x-discourse-route: finish_installation/index
cache-control: no-cache, no-store
content-security-policy: base-uri 'none'; object-src 'none'; script-src https://example.com/logs/ https://example.com/sidekiq/ https://example.com/mini-profiler-resources/ https://example.com/assets/ https://example.com/brotli_asset/ https://example.com/extra-locales/ https://example.com/highlight-js/ https://example.com/javascripts/ https://example.com/plugins/ https://example.com/theme-javascripts/ https://example.com/svg-sprite/; worker-src 'self' https://example.com/assets/ https://example.com/brotli_asset/ https://example.com/javascripts/ https://example.com/plugins/
x-request-id: 8755d4fa-387f-4509-8709-b6075f274d09
x-runtime: 0.026020
strict-transport-security: max-age=31536000

Ладно, я, очевидно, полный идиот. Попробовал с телефона через 4G (чтобы проверить локальный DNS) — все эти URL-адреса работали отлично. Подключился к Wi-Fi — всё тоже работает нормально. Тогда я очистил кэш Safari на рабочем столе, и бац — всё заработало и там.

Наверное, это осталось с момента, когда я изначально тестировал хост, и кэш так и не был очищен. Большое спасибо за помощь в устранении неполадок и извините за то, что отнял у вас время.

Кстати, сегодня я столкнулся с той же проблемой в Ubuntu 22.04. Очистка кэша Safari и перезагрузка также решили проблему.