Примечание: Не уверен, куда это лучше разместить, пожалуйста, переместите в более подходящее место, если я что-то упустил.
Хотел поделиться быстрым и немного кустарным способом, который я придумал на прошлой неделе, чтобы быстро развернуть страницу-заглушку во время обновления Discourse. Я прочитал все существующие руководства, но ничего не знаю об nginx, а схема с двумя контейнерами выглядела очень пугающе.
Коротко: я что-то сделал, код ниже. ![]()
Node.js на помощь
Я подумал: какой самый быстрый способ запустить крошечный веб-сервер с одной страницей? Затем вспомнил, что node.js уже установлен, может, обойтись только им?
После быстрого поиска и копирования/вставки из StackOverflow у меня появился крошечный сервер, слушающий порт 80!
Процесс очень ручной, но я считаю, что это нормально: мне всё равно нужно следить за логами во время обновления, поэтому я жду сигнала:
Stopping old container
+ /usr/bin/docker stop -t 600 app
В этот момент у меня открыта ещё одна сессия SSH, где я быстро выполняю:
touch index.html
node server.js 80
Я создаю файл index.html с помощью touch, чтобы можно было прочитать дату обновления и заменить плейсхолдер. В моём index.html есть такая строка:
<p>This page was last updated at: LASTUPDATE</p>
В файле server.js я заменяю LASTUPDATE на дату/время последнего обновления файла index.html. Это даёт людям представление о том, когда началось обновление, и я указываю на странице, что процесс займёт 10–15 минут.
Это легко сработало на моём тестовом сервере, и я почувствовал себя готовым сделать то же самое на боевом.
Ой, нужен https 
Время обновлять боевой сервер и показать людям мою новую быструю страницу-заглушку!
Но всё пошло не по плану. Боевой сайт находится за Cloudflare и требует наличия полных сертификатов сквозного шифрования, поэтому я вывел форум из строя на 15 минут, и пользователи видели только страницу ошибки Cloudflare ![]()
К счастью, ещё немного копирования/вставки из StackOverflow помогло. Я переключил сервер с http на https и получил файлы cert.key и cert.pem, чтобы убедиться, что цепочка сертификатов целая.
Следующее обновление прошло более успешно, и страницы-заглушки появились так, как задумано:
Просто покажите код!
Вот два файла, которые я использую для этой страницы-заглушки:
index.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>We'll be right back</title>
</head>
<body>
<h1>We'll be right back</h1>
<p>Sorry for the temporary outage, we're currently applying an update, this usually take 10-15 minutes.</p>
<p>This page was last updated at: LASTUPDATE</p>
</body>
</html>
server.js
var http = require("http"),
https = require("https"),
url = require("url"),
path = require("path"),
fs = require("fs"),
port = process.argv[2] || 81;
const options = {
key: fs.readFileSync("cert.key").toString(),
cert: fs.readFileSync("cert.pem").toString(),
};
https
.createServer(options, function (request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), uri);
fs.exists(filename, function (exists) {
if (!exists) {
response.writeHead(404, { "Content-Type": "text/plain" });
response.write("404 Not Found\n");
response.end();
return;
}
let indexFile = (filename += "index.html");
if (fs.statSync(filename).isDirectory()) indexFile;
fs.readFile(filename, "utf8", function (err, file) {
if (err) {
response.writeHead(500, { "Content-Type": "text/plain" });
response.write(err + "\n");
response.end();
return;
}
var stats = fs.statSync(indexFile);
var mtime = stats.mtime;
response.writeHead(200);
file = file.replace(/LASTUPDATE/g, mtime);
response.write(file, "utf8");
response.end();
});
});
})
.listen(parseInt(port, 10));
console.log(
"Static file server running at\n => https://localhost:" +
port +
"/\nCTRL + C to shutdown"
);
Как отмечалось выше, запустить его можно так:
touch index.html
node server.js 443
Аргумент 443 — это порт, на котором вы хотите запустить сервер. По умолчанию он работает на порту 81, чтобы я мог выполнить curl и проверить вывод перед тем, как делать это во время обновления:
curl -k https://localhost:81
В какой-то момент во время обновления Discourse, когда оно завершится, вы увидите:
Error starting userland proxy: listen tcp4 0.0.0.0:443: bind: address already in use.
Именно тогда я останавливаю сервер Node и снова запускаю Discourse:
./launcher restart app
Всё. Надеюсь, это кому-нибудь поможет!
