这是我遇到的麻烦以及最终成功将 discourse 实例从 scaleway 迁移到树莓派 4,并在前面使用 cloudflare 的文档。
从 scaleway discourse 实例创建备份,然后运行 ./launcher stop app,并关闭机器。
在连接到树莓派 4 的 USB SATA SSD 上安装了 Ubuntu Server 23.10。
安装了 LXD,创建了一个 100GiB 的 btfs 回环存储池。
更新 default 配置文件为:
config:
cloud-init.user-data: |
#cloud-config
ssh_pwauth: false
package_update: true
package_upgrade: true
packages:
- openssh-server
- vim
- git
- rsync
users:
- name: root
lock_passwd: true
ssh_import_id: gh:balupton
description: Default LXD profile
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
添加一个 discourse 配置文件,包含:
config:
limits.memory: 1GiB
limits.memory.enforce: soft
security.nesting: 'true'
description: Configuration for Discourse instances
devices: {}
name: discourse
使用这些配置文件创建了一个 Ubuntu 23.10 最小服务器镜像。通过 ~/.ssh/config 中的以下配置访问它:
Host LXD_DISCOURCE_INSTANCE
ProxyJump LXD_HOST
User REDACTED
IdentityFile ~/.ssh/REDACTED.pub
遵循 discourse 云安装说明,并从 scaleway 实例恢复了我的 discourse 配置:
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/cloudflare.template.yml"
- "templates/web.ssl.template.yml" # https
- "templates/web.letsencrypt.ssl.template.yml" # https
# - "templates/web.ratelimited.template.yml" # not needed with cloudflare
expose:
- "80:80"
- "443:443" # https
params:
db_default_text_search_config: "pg_catalog.english"
env:
LANG: en_US.UTF-8
## HTTPS configuration for: templates/web.letsencrypt.ssl.template.yml
LETSENCRYPT_ACCOUNT_EMAIL: "redacted" # https
## The domain name this Discourse instance will respond to
DISCOURSE_HOSTNAME: "redacted"
## List of comma delimited emails that will be made admin and developer
## on initial signup example 'user1@example.com,user2@example.com'
DISCOURSE_DEVELOPER_EMAILS: "redacted"
## The mailserver this Discourse instance will use
DISCOURSE_SMTP_ADDRESS: "redacted"
DISCOURSE_SMTP_PORT: redacted
DISCOURSE_SMTP_USER_NAME: "redacted"
DISCOURSE_SMTP_PASSWORD: "redacted"
#DISCOURSE_SMTP_DOMAIN: discourse.example.com # (required by some providers)
#DISCOURSE_NOTIFICATION_EMAIL: nobody@discourse.example.com # (address to send notifications from)
#DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456
## Any custom commands to run after building
run:
- exec: rails r "SiteSetting.contact_email='redacted'"
- exec: rails r "SiteSetting.notification_email='redacted'"
## The Docker container is stateless; all data is stored in /shared
volumes:
- volume:
host: /var/discourse/shared/standalone
guest: /shared
- volume:
host: /var/discourse/shared/standalone/log/var-log
guest: /var/log
## Plugins
## https://meta.discourse.org/t/19157
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/discourse-adplugin.git
- git clone https://github.com/discourse/discourse-affiliate.git
- git clone https://github.com/discourse/discourse-assign.git
- git clone https://github.com/discourse/discourse-docs.git
- git clone https://github.com/discourse/discourse-topic-voting.git
- git clone https://github.com/discourse/discourse-github.git
- git clone https://github.com/discourse/discourse-saved-searches.git
- git clone https://github.com/discourse/discourse-shared-edits.git
- git clone https://github.com/discourse/discourse-solved.git
# - git clone https://github.com/discourse/discourse-encrypt.git
# - git clone https://github.com/discourse/discourse-reactions.git
# - git clone https://github.com/discourse/discourse-subscriptions.git
然而,在我恢复备份之前,我需要重建它。不幸的是,btrfs 存储池在 yarn install 步骤中会挂起数小时,最终超时,而机器上的负载几乎为零。
经过一些研究,我决定尝试使用 zfs 存储池,这会进一步进行,但在“Background saving terminated with sucess”之后仍然会无限期挂起,而机器上的负载几乎为零。
(我有截图,但在此处上传失败。)
然后我决定放弃 LXD,直接在树莓派 4 上的 Ubuntu Server 实例上尝试。
这是我第一次成功重建,但所有访问尝试都会重定向到自身,形成重定向循环。
重定向循环有两个原因……
如果我的 discourse 配置中有以下内容:
expose:
- "8080:80"
- "8081:443" # https
它会无限重定向,总是想重定向到 https://hostname。
解决这个问题是回到:
expose:
- "80:80"
- "443:443" # https
其次,通过 cloudflare 隧道访问的任何内容也会无限重定向到自身。结果发现原因是同时为 HTTP 和 HTTPS 设置了隧道。将隧道更改为仅 HTTPS 解决了这个问题。
我做的其他事情,但此时不确定是否重要:
- 我删除了 letsencrypt,因为我改用了 Cloudflare Origin Certificate。
- 我已将 HTTPS 隧道中的“Origin Server Name”配置为目标主机名。
可以改进的地方:
- 如果我将机器锁定为仅允许来自 Cloudflare 的连接,并设置 SSH 隧道,就可以避免从 Origin 到 Cloudflare 的 HTTPS。但是,我不确定 Discourse 是否在拥有 HTTPS(例如 http2 等)的情况下运行得更好。
- letsencrypt 是否与 cloudflare 隧道一起工作(我无法测试,因为当我使用 letsencrypt 时,我遇到了重定向循环)。
我如何调试重定向循环:
- 对于调试 discourse 重定向循环:我将
/etc/hosts设置为将我的 discourse 主机名直接指向 IP 地址,然后使用curl -k --head 'https://hostname:8081等进行测试。 - 对于调试 cloudflare 隧道重定向循环:我从
/etc/hosts中删除了它,以便主机名通过 DNS 解析,然后使用curl -k --head 'https://hostname等进行测试。
一路上还有很多其他巧妙的事情和学习,但那些可以稍后讨论。
对 discourse 的反馈:
- 重建需要更清楚地说明它在做什么。太长的时间延迟,但没有明显的动作正在执行。
- 找出为什么暴露不同的端口会导致重定向循环。
- 自从 letsencrypt 出现以来,关于如何指定自己的 SSL 证书的文档很难找到。而且似乎只能使用一个证书,因为它固定在
/var/discourse/shared/standalone/ssl/ssl.key而不是例如/var/discourse/shared/standalone/ssl/CONTAINER_ID.key,例如/var/discourse/shared/standalone/ssl/app.key— cloudflare 提供源证书,这对 cloudflare 用户来说是一个不错的选择。 - 发布一个全面的分步指南,涵盖 cloudflare + 树莓派 4 的所有内容,将非常有帮助,目前这类指南将过多的信息委托给第三方,而这些第三方彼此之间没有了解,所有的复杂性和调试都在于不同部分如何协同工作,而不是它们如何单独工作。
其他一些未来的待办事项:
- 找出它为什么会在 LXD 中挂起。
- 查看它是否可以在树莓派 5 上的 LXD,或 macOS 上的 Multipass,或使用分区/驱动器而不是回环文件的存储池的 LXD 中工作:这样我就不必浪费一台完整的机器来做这件事。
- 查看我是否可以让 docker 和 launcher 不需要 sudo。