我的更新过程中出现了一个错误
api_key = "a quick brown fox"
fetch("https://api.example.com/data", headers: { 'Authorization' => api_key })
请帮我修复它。
我的更新过程中出现了一个错误
api_key = "a quick brown fox"
fetch("https://api.example.com/data", headers: { 'Authorization' => api_key })
请帮我修复它。
嘿!
我不是在回答你的问题,只是出于好奇。你为什么觉得需要维护页面?设置起来似乎挺麻烦,而且收益甚微。
我的实例每个月停机更新大概5分钟,基本上就这样了。
每当我进行重大更改,例如安装插件时,有时需要花费20分钟。
考虑到这些操作并非每周甚至每月都要进行,这倒不是什么大问题。但对于新访客来说,看到那个显示“某些功能无法正常工作”的丑陋页面,并不会留下良好的第一印象。即使是那些不知道网站会停机的老访客,也可能因此陷入“恐慌模式”,以为整个社区被关闭了或发生了其他严重事故,其中一些人甚至会立刻发邮件问我到底发生了什么。
我认为,无论是新访客还是老访客,告知他们当前正在发生的事情,都是一个贴心的细节。
如果Claude提出的这种方案只需花费几分钟,且之后无需再频繁调整,我相信这绝对是一笔值得投入的时间。
我使用 dual container build 并置于 Cloudflare CDN 之后。双容器模式将停机时间降至最低,我的两个主要生产论坛在重建期间最多只有 30 秒的离线时间。我喜欢使用维护页面,因为默认的网络服务器宕机页面既难看,又无法提示用户离线时间有多长。
例如,对于 your-domain.com 这个站点,我只需设置一个 Cloudflare Workers 路由,指向 *yourdomain.com/*(包含星号)。
你可以在 Cloudflare 的 workers & pages 设置页面中设置维护页面——点击 create application 按钮:
然后使用 hello world 模板:
然后给它起个名字并点击 deploy:
然后进入该维护页面的概览页面,点击 edit code:
并将以下代码粘贴到 worker.js 代码窗口中(替换你的域名以及你想要的消息,编辑文本、文字颜色、背景等):
export default {
async fetch(request, env, ctx) {
try {
// Fetch the original request from your server
const response = await fetch(request);
// If YOUR SITE is swapping containers, it throws a 502, 521, or 530
if (response.status === 502 || response.status === 521 || response.status === 530) {
return returnCustomErrorPage();
}
// If everything is fine, return the normal forum traffic
return response;
} catch (e) {
// If the server is completely unreachable
return returnCustomErrorPage();
}
}
};
function returnCustomErrorPage() {
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>System Refresh - YOUR-SITE.com</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; text-align: center; padding: 50px; color: #333; background-color: #f9f9f9; }
h1 { font-size: 2.5em; margin-bottom: 0.5em; color: #9400D3; }
p { font-size: 1.2em; line-height: 1.5; }
.container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<div class="container">
<h1>Just a quick update window</h1>
<p><strong>YOUR-SITE</strong> is undergoing a brief 30-second system refresh.</p>
<p>Grab a quick sip of your drink—this page will automatically refresh as soon as we are back online.</p>
</div>
<script>
// Automatically check if the site is back up every 10 seconds
setInterval(function() {
window.location.reload();
}, 10000);
</script>
</body>
</html>
`;
return new Response(html, {
status: 503, // 503 is best for SEO so Google doesn't penalize you for downtime
headers: {
"Content-Type": "text/html;charset=UTF-8",
"Retry-After": "30"
}
});
}
它看起来应该像这样。点击 deploy 以保存:
现在进入 Cloudflare worker route 页面,点击 add route 按钮以调出新的路由模态框,填入域名路由并选择你刚刚创建的 worker 页面,然后点击保存:
现在,当你通过 ssh 进入服务器并运行系统更新或进行重建时,在真正发生停机时显示的将不再是网站宕机或错误页面,而是这个页面(我的设置是 30 秒,因为这是我的站点的最大停机时间)
我倾向于在维护时添加和删除我的 workers 路由页面,但有些人喜欢一直保留它(我保留页面的实际代码,只是添加和删除路由)。
我想这就完了。
我还使用服务器上的 unix shell 脚本来运行双容器特定的更新,我是这样创建的:
cat << 'EOF' > /root/update-web.sh
#!/bin/bash
cd /var/discourse
echo "➡️ Pulling latest Discourse docker scripts..."
git pull
echo "➡️ Bootstrapping new web container in the background (takes ~8 mins)..."
./launcher bootstrap web_only
if [ $? -eq 0 ]; then
echo "✅ Bootstrap successful! Swapping containers..."
./launcher destroy web_only && ./launcher start web_only
echo "🚀 Done! Site updated with almost zero downtime."
else
echo "❌ Bootstrap failed! Aborting swap to keep current site online."
fi
EOF
chmod +x /root/update-web.sh
然后在服务器的 root 提示符下使用命令 ./update-web.sh 运行它。
编辑:除非你有付费的 cloudflare 账户,否则不要执行以下步骤。
你可以将其自动化到特定时间,例如你本地时间的周日凌晨 1 点。对我来说,1:00am local 是 8:00 AM UTC,(你可以通过在 ssh 登录时输入 date 来查看服务器的 UTC 日期)。
所以:
运行此命令以打开服务器的任务调度器:
crontab -e
(如果它要求你选择编辑器,请选择你喜欢的编辑器,选择 1 即 nano 可能最容易)
我滚动到注释的底部并粘贴以下内容:
0 8 * * 0 /root/update-web.sh >> /var/log/discourse-update.log 2>&1
(这意味着在分钟 0、小时 8(UTC)、每个周日早上运行 /root/update-web.sh 文件)
然后保存并退出(如果你使用的是 nano):
Ctrl + O 保存。Enter 确认。Ctrl + X 退出。然后我可以在周日早上醒来时运行 cat /var/log/discourse-update.log 来检查它是否正常运行。如果你确实使用 cron 任务调度器,那么你将需要保留 workers 页面路由。
我想这就是全部了。 如果你有问题请告诉我 lol。 这比我看起来要简单得多 lol。 ![]()
哇!我非常感谢你提供的详细步骤!![]()
我已经把你的回复保存到我的笔记里了,这样当我不久后再次安装 Discourse 时,就可以回来参考。我一定会告诉你进展如何,即使安装过程需要花一些时间。目前我正在完成一些编码工作,之后才会重新专注于 Discourse。
我也同意“web serve is down”页面很难看,而且对于没有经验的用户来说,这条信息意义不大。拥有一个带有自定义消息的简单维护页面总是更好的选择,即使这需要一些设置工作。
再次非常感谢你抽出时间分享这些。希望其他人也能从中受益 ![]()
问题就在这里。
这并非一个简单的改动,还涉及需要担忧和维护的额外基础设施,恕我直言,为了几秒钟的停机时间,这完全 不 值得。
我明白你的意思,但那只是其中一种情况。如果真的出现严重故障,我需要花更多时间(不止几秒钟)来修复怎么办?
另外,你是怎么做到只有几秒钟的停机时间的?我安装插件后,看到的停机时间大约是20分钟。
因为在双容器设置(我们在帖子中都链接了,且是不可或缺的依赖项)中,你使用 ./launcher bootstrap web_only 引导新构建(在此期间你的网站仍保持 100% 正常运行),然后你只需销毁并立即启动刚刚构建好的新容器(这只需几秒钟)。
哦,好的,那还是针对双容器部署方案的。我原以为你是在说完全搭建双容器部署方案不值得费这个劲。你的意思是,不值得做的只是那个维护页面所增加的额外工作,对吧?
个人而言,是的。
如果你希望为在30到60秒内通过全新导航出现的网页访问者提供双重保障,那么使用维护页面是合理的。
你需要权衡这样做的好处与维护相关基础设施所需的时间。
现在我明白了。谢谢。
那么我现在想问:使用 2 个容器时,那大约 20 分钟的时间依然存在,唯一的区别是我可以在非实时运行的那个容器上执行操作,等准备就绪后再进行切换。是这样吗?
是的,构建容器仍然需要一些时间。顺便提一下,你需要确保你的服务器配置足够强大,以便在正常为社区提供服务的同时,能够并行进行该构建过程(最关键的是确保有足够的内存——因此务必确保你有足够的交换空间)。构建过程还会占用至少一个 CPU 核心,因此建议你的服务器拥有多 1 或 2 个核心。
对于这种配置,我建议至少使用 4GB 内存和 3 个核心(“vcpu”)……
作为参考,因为有人在另一个话题中问过,(编辑:错误)答案是:Any cheaper alternatives to Hetzner? - #2 by Canapin
这是唯一符合要求的……价格差异真大……
![]()
我想我现在得先用单个容器搭建,等时机成熟(
)再升级。
谢谢你的信息,Robert!
我持不同意见,我认为设置维护页面是值得的。根据我的经验,当用户看到 Discourse 错误页面时,他们做的第一件事通常是刷新页面,随后会看到简短的维护页面,并在容器切换完成后自动重新加载网站。设置起来并不复杂,而且只需配置一次。在采用双容器配置进行重建时,引导阶段会在后台进行,用户仍可使用网站;导致短暂停机的是容器切换过程(这与标准的单容器配置不同)。
服务器成本和选择是完全不同的问题,应该放在另一个独立的话题中讨论。
我想我现在处于中间立场。我理解你的意思,也理解 @merefield 的观点。拥有这个功能确实是个不错的点缀,而且如果只需设置一次,我想也不算什么大碍吧?
同时,如果最坏情况下确实需要长达 60 秒,并非每个人都会在 0 秒整访问网站并被迫等待 60 秒。有些人可能会看到丑陋的页面 5 秒,有些 20 秒,有些 60 秒。甚至有些人根本不会看到它(我想是这样?),例如,如果他们只是在阅读回复或撰写回复,这个切换可能在他们点击“发送”之前,或者在他们停止阅读主题并点击“回复”(或访问其他页面)之前就已经完成了。
我对 nginx 路由方案的顾虑,更多是与单容器设置中 20 分钟的问题有关。既然可以选择使用 2 个容器,并将时间从 20 分钟缩短到最多 60 秒,我在想这是否真的还重要?尤其是,如果我能够在顶部添加一个公告,说明服务将在低流量时段短暂中断几秒钟,这应该就不会成为大问题了吧?
我得坐下来好好想想。不过,如果我能找到划算的服务器优惠,双容器设置肯定是我打算实施的方案。
你能否用我能理解的简单方式解释一下?我对 Workers 还不太熟悉……
如果一直保留没有问题,为什么还要添加和删除 Workers 路由页面呢?所以,如果我添加了维护页面,我是否真的只需设置一次,之后就可以一直通过终端 SSH 连接到服务器,像操作单个容器那样在那里完成所有操作,而无需再访问 Cloudflare?
@merefield 提到维护页面、Workers 等也需要维护,所以我想知道这真的是“设置后就不用管了”的东西,还是说偶尔需要做一些操作?