Запуск Discourse на / при обслуживании кастомного приложения на /tickets в том же домене

Всем привет,

Я пытаюсь подтвердить правильную архитектуру для размещения пользовательского приложения по подпути, сохраняя Discourse в корне (/), без изменения внутренних компонентов Discourse.

Что я хочу (конечная цель)

https://mydomain.com/         → Discourse
https://mydomain.com/tickets  → Пользовательская система тикетов (Go + Gin)

Требования:

  1. Discourse должен оставаться в /, а приложение — в /tickets
  2. Один домен
  3. Никаких плагинов Discourse

Текущая среда

  1. OVH VPS (Ubuntu), Discourse работает в Docker (/var/discourse)
  2. Пользовательское приложение на Go работает на том же сервере по адресу 127.0.0.1:8080
  3. Внешний nginx установлен на хосте (не внутри контейнера)

Я не пытаюсь запустить Discourse в подпапке, например /forum. И прежде чем кто-то спросит: да, я пробовал использовать плагин Discourse Tickets — он не работает так, как мне нужно.

Это можно легко сделать с помощью nginx. Хотя это и не рекомендуется, я не знаю, чтобы Discourse использовал маршрут /tickets для каких-либо целей.

Спасибо за быстрый ответ! Я использую nginx и испытываю трудности. Вот моя конфигурация, но пока безрезультатно.

Это содержимое моего файла app.yml

expose:
  - "4000:80"
  #- "80:80" # http
  #- "443:443" # https

/etc/nginx/sites-enabled/filename

server {
    listen 80;
    server_name mydomain.com;

    # ---- Приложение для тикетов ----
    location ^~ /tickets {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Заголовки аутентификации Discourse
        proxy_set_header X-Discourse-Username $http_x_discourse_username;
        proxy_set_header X-Discourse-User-Id $http_x_discourse_user_id;
        proxy_set_header X-Discourse-Groups $http_x_discourse_groups;
    }

    # ---- Discourse ----
    location / {
        proxy_pass http://127.0.0.1:4000;
        proxy_http_version 1.1;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Можете ли вы подробнее рассказать, в чём именно заключаются ваши трудности?

Думаю, это, пожалуй, лучшие инструкции. Вам нужно будет следовать им, но как бы наоборот. Ваш внешний обратный прокси будет направлять / в Discourse, а /tickets — в ваше приложение.

@pfaffman Итого я понял так: используйте концепцию, а не конфигурацию — поставьте внешний обратный прокси перед ним, который будет маршрутизировать:

  • / → Discourse

  • /tickets → мое собственное приложение

Discourse вообще не будет знать о /tickets.
Посмотрите, пожалуйста, на это: Serve Discourse from a subfolder (path prefix) instead of a subdomain

Я думаю, что внешний nginx — самый простой способ это сделать. Можно было бы создать шаблон, позволяющий сделать то же самое с внутренним, но это сложнее и, на мой взгляд, даёт мало преимуществ.

Да, но вам не нужно вносить какие-либо изменения в контейнер Discourse, кроме удаления шаблонов ssl/let’s encrypt и, возможно, использования сокета. (Так что, по сути, в той теме мало что действительно полезно.)

У меня получилось!

Спасибо вам обоим за ответы!

Ссылка «Tickets», которую я добавил в заголовок Discourse, тоже работает, если установить её значение не как «self», а оставить пустым. Тогда /tickets воспринимается как маршрут Discourse, и просто меняется React-представление. Пустое значение заставляет выполнить полную перезагрузку страницы.

Если вы хотите это исправить, я почти уверен, что компонент темы поможет, если добавить маршрут для /tickets и указать ему делать . . . что-то (я не очень силен в Ember). Также, думаю, вы можете добавить еще один поддомен к вашему серверу Discourse (например, tickets.mydomain.com), используя DISCOURSE_HOST_ALIASES, и затем ссылаться на этот домен. В этом случае произойдет перенаправление, и Ember не попытается перехватить маршрут.