Окей, потребовалось всего 2 часа возни, чтобы сделать как мне нужно!
Страница обслуживания Discourse с Apache2
Как root:
cd /var/discourse
nano containers/app.yml
Закомментируйте эти строки:
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
expose:
#- "80:80" # http
#- "443:443" # https
В конце раздела templates добавьте (обязательно в самом конце):
- "templates/web.socketed.template.yml"
Примечание: это заставит Discourse слушать только внутренний IP-адрес, а apache2 перехватит порты 80/443 и возьмёт на себя завершение SSL.
Примечание: для применения изменений Discourse необходимо пересобрать:
cd /var/discourse
./launcher rebuild app
Установите apache2 и certbot:
apt install -y apache2 certbot python3-certbot-apache
Создайте директорию для HTML-страницы:
mkdir /var/www/discourse_maintenance
HTML-страница:
/var/www/discourse_maintenance/discourse_maintenance.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="5">
<title>Discourse Maintenance</title>
<style>
.center {
display: flex;
justify-content: center;
}
.container {
max-width: 500px;
padding: 50px 50px 30px 50px;
}
.title {
padding-top: 20px;
}
h1, p {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}
</style>
</head>
<body>
<div class="center">
<div class="container">
<h1 class="title">Discourse Maintenance…</h1>
<p>В данный момент мы обновляем сайт или проводим плановое техническое обслуживание.</p>
<p>Как только сайт будет доступен, вас автоматически перенаправит на него.</p>
</div>
</div>
</body>
</html>
Включите модуль Proxy:
a2enmod proxy
a2enmod proxy_http
a2enmod headers
Файл vhost для Apache:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName ваш.discourse.домен
ServerAdmin ваш@email.com
DocumentRoot /var/www/discourse_maintenance
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Режим обслуживания
RewriteEngine On
RewriteCond /var/www/under_maintenance -f
# Проверка безопасности для предотвращения циклов перенаправления
RewriteCond %{REQUEST_URI} !/discourse_maintenance.html$
# Перенаправление всех запросов на maintenance.html внутри сервера
RewriteRule ^.*$ /var/www/discourse_maintenance/discourse_maintenance.html
ProxyPass / unix:///var/discourse/shared/standalone/nginx.http.sock|http://127.0.0.1/
ProxyPassReverse / unix:///var/discourse/shared/standalone/nginx.http.sock|http://127.0.0.1/
SSLCertificateFile /etc/letsencrypt/live/ваш.discourse.домен/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ваш.discourse.домен/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Чтобы включить режим обслуживания, выполните touch /var/www/under_maintenance
Чтобы выключить режим обслуживания, выполните touch /var/www/under_maintenance
Благодарности: Add an offline page to display when Discourse is rebuilding or starting up — за первоначальную идею и HTML-страницу (сокращённую и отредактированную по моему вкусу), а также за конфигурацию nginx, на основе которой я построил конфигурацию Apache.
Редактирование: приветствуются предложения по автоматизации процесса, когда ответом является 502/503. Я пытался, но не смог заставить это работать так, как хотел, поэтому выбрал известный метод, который использую на других веб-серверах, когда бэкенд-приложение недоступно для обслуживания и т.п.