作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。
介绍
由StackOverflow的创始人之一创建的 Discourse是一个开源的讨论平台。
Discourse 通过使用 DigitalOcean 的单点安装在单个 Droplet 上运行得很好,但随着您的社区的增长,它可能会超过单个 Droplet。使用多个 Droplets 会使您的社区在您的 Droplets 之一离线时具有弹性。每个 Droplet 也会增加您的带宽容量。当您使用多个 Droplets 时,一个 Load Balancer 可以帮助扩展您的部署并为您的 Web 应用程序带来高可用性。
完成本教程后,您将有一个高度可用的,易于扩展的Discourse部署在DigitalOcean上运行,您将开始使用新的Ubuntu 20.04Dropplet,并完成一个可扩展的Discourse安装,其中包括负载平衡器,管理PostgreSQL集群,Redis实例(可选),以及额外的Dropplets。
前提条件
要遵循本教程,您将需要:
- 具有至少 2 GB RAM 的 Ubuntu 20.04 服务器配置了非 root 用户的
sudo
权限和防火墙,您可以通过遵循指南, Initial Server Setup with Ubuntu 20.04。 - Discourse 安装并配置在您的服务器上,您可以通过遵循教程, How to Install Discourse on Ubuntu 20.04执行。
- 一个域名,其 DNS 记录由 DigitalOcean 管理,您可以通过以下教程执行, How to Point to DigitalOcean Nameservers From Common Domain Registrars 。
步骤 1 — 将 DigitalOcean 负载平衡器添加到演讲服务器
在此步骤中,您将添加一个DigitalOcean负载平衡器到您在前提条件下创建的Discourse服务器. 访问您的DigitalOcean控制面板,单击 网络,然后单击 负载平衡器,然后单击 创建负载平衡器。
您需要为您的负载平衡器选择一个数据中心区域。 请确保为您的 Discourse Droplet 选择相同的区域。 负载平衡器使用其私人网络与您的 Droplet 进行通信,因此您的 Droplet 和 Load Balancer 都需要位于相同的区域。
接下来,将您的 Droplet 添加到您的负载平衡器中,将您的 Droplet 名称键入文本字段。
Discourse 通常通过在安装过程中发行免费的 Let's Encrypt证书来为您处理 HTTPS,但是当您的 Droplet 处于负载平衡器背后时,Let's Encrypt 将无法更新您的证书,因为您的域的 IP 地址不会匹配您的 Droplet 的 IP。
幸运的是,DigitalOcean Load Balancers 可以为您管理证书. 您只需要将 HTTPS 的 _forwarding 规则添加到您的负载平衡器中。
<$>[注] 注: 有关转发规则的更多信息,请参阅 负载平衡器的产品文档。
您需要两个转发规则,一个用于 HTTP 和一个用于 HTTPS. 通过为 HTTPS 添加转发规则,DigitalOcean 可以自动为您生成和更新证书。
由于您已将您的域名添加到 DigitalOcean 作为前提条件的一部分,所以添加 HTTPS 支持只需几个点击即可。在 传递规则部分中,添加一个名为HTTPS
的新规则,您可以从下落列表中选择。
然后给您的证书一个名字,然后点击 ** 生成证书** 以获得 DigitalOcean 请求并为您管理证书。
您几乎已经完成了设置您的负载平衡器。点击 Edit Advanced Settings 按钮,然后点击标记为 Enable Proxy Protocol 的框。当启用 PROXY 协议时,负载平衡器将用户的 IP 地址等客户端信息转发到负载平衡器背后的 Droplets。
最后,选择您的负载平衡器的名称,然后单击 创建负载平衡器。
现在您已经安装了 Load Balancer,您需要修改您的 Discourse 配置文件。
步骤 2 – 更改语音配置文件
在此步骤中,您将更改包含在 Discourse.SSH 中的默认配置文件到您的 Droplet 并使用此命令移动到 `/var/discourse’ 目录:
1cd /var/discourse
使用 nano 或您最喜欢的文本编辑器,在名为 loadbalancer.template.yml 的模板
目录中创建并打开新文件:
1sudo nano templates/loadbalancer.template.yml
模板文件夹为您的 Discourse 配置存储文件. 在这里,您正在添加一个新的自定义模板,以启用 PROXY 协议支持您的 Discourse 安装。
在loadbalancer.template.yml
中,插入以下行:
1[label templates/loadbalancer.template.yml]
2run:
3 - exec: "sed -i 's:listen 80: listen 80 proxy_protocol:g' /etc/nginx/conf.d/discourse.conf"
4 - exec: "sed -i 's:$remote_addr:$proxy_protocol_addr:g' /etc/nginx/conf.d/discourse.conf"
5 - exec: "sed -i 's:X-Forwarded-For $proxy_add_x_forwarded_for:X-Forwarded-For $proxy_protocol_addr:g' /etc/nginx/conf.d/discourse.conf"
第一行修改了 Discourse Nginx 配置以启用 PROXY 协议的支持。
第二行执行查找和替换,以$proxy_protocol_addr
代替$remote_addr
的所有发生。$proxy_protocol_addr
包含客户端的IP地址,由负载平衡器转发。
最后一行将X-Forwarded-For $proxy_add_x_forwarded_for
的所有事件代替为X-Forwarded-For $proxy_protocol_addr
,确保X-Forwarded-For
标题正确记录客户端IP地址,而不是负载平衡器的IP地址。
保存并关闭文件,按CTRL+X
,然后按y
。
您需要做的最后一件事是将模板加载到 Discourse 并重建 Discourse。
使用 nano 或您最喜欢的文本编辑器,在容器
目录中编辑名为app.yml
的文件:
1sudo nano containers/app.yml
首先,您将添加您刚刚创建的模板。在模板
下,如下所示,添加突出的行:
1[label containers/app.yml]
2templates:
3 - "templates/postgres.template.yml"
4 - "templates/redis.template.yml"
5 - "templates/web.template.yml"
6 - "templates/web.ratelimited.template.yml"
7 - "templates/loadbalancer.template.yml"
请确保在templates/web.template.yml
下面的一行中添加新模板。
接下来,请确保两个行 web.ssl.template.yml
和 templates/web.letsencrypt.ssl.template.yml
都通过添加字符符号 [#
] 来评论:
1[label containers/app.yml]
2templates:
3 - "templates/postgres.template.yml"
4 - "templates/redis.template.yml"
5 - "templates/web.template.yml"
6 - "templates/web.ratelimited.template.yml"
7 - "templates/loadbalancer.template.yml"
8## Uncomment these two lines if you wish to add Lets Encrypt (https)
9# - "templates/web.ssl.template.yml"
10# - "templates/web.letsencrypt.ssl.template.yml"
最后,走几行,直到你看到暴露
。评论-
443:443 # https
通过添加一个英镑符号 [#
]如下所示:
1[label containers/app.yml]
2...
3expose:
4 - "80:80" # http
5# - "443:443" # https
当您重建 Discourse 时,HTTPS 连接将在 Load Balancer 中终止,而 Load Balancer 将通过 DigitalOcean 的安全私人网络与您的 Droplet 通信,因此您不需要直接在 Discourse 服务器上设置 HTTPS。
保存并关闭文件,按CTRL+X
,然后按y
。
若要应用配置并重建 Discourse,请运行以下命令:
1sudo ./launcher rebuild app
这个命令需要超级用户权限,这就是为什么它被预先称为sudo
。
此时,您已经完成了对话和负载平衡器的配置,然后将您的域名指向负载平衡器的 IP 地址。
第3步:更新您的DNS
在此步骤中,您将您的域名指向 Load Balancer 的 IP 地址,而不是 Droplet 的 IP 地址。
如果您正在使用 DigitalOcean 的 DNS 托管,请进入控制面板,然后单击 网络. 点击您的域名,然后搜索指向您的 Droplet 的 A 记录。
您的 Discourse 服务器将运行在 DigitalOcean 负载平衡器后面,您不必管理自己的 SSL 证书,因为 DigitalOcean 将为您做。
通过访问您的域名来测试您的 Discourse 安装工作,您应该看到一个看起来类似于此的页面:
现在,您的域指向负载平衡器,您将添加一个受管理的数据库实例,为用户创建一致的体验。
步骤 4 — 添加管理的数字海洋数据库
在此步骤中,您将创建一个 DigitalOcean Managed PostgreSQL 实例,并将其添加到您的 Discourse 部署中。
负载平衡器的主要优点是将您的流量分为多个Dropplets。 到目前为止,您的数据库、Redis服务器和Web服务器都运行在一个Dropplets上。 如果您添加第二个Discourse实例,它将拥有自己的数据库、Redis服务器和Web服务器,并将作为一个完全不同的网站行事。 您的访问者可能会觉得他们正在访问其他网站,具有不同的帖子和用户,因为他们将连接到不同的数据库。 您可以通过使用DigitalOcean的Managed PostgreSQL实例来解决这个问题,而不是在每个Discourse Droplet上运行单独的数据库。
通过进入DigitalOcean控制面板来设置一个DigitalOcean Managed PostgreSQL实例. 点击 DataBases,然后点击 Create Database Cluster,最后选择 PostgresSQL,设置区域以匹配您的Droplet的位置,然后点击 Create a Database Cluster。
当您的数据库正在配置时,请将您的Droplet添加到您的数据库中作为可信来源,从而允许您的Droplet使用DigitalOcean的安全私人网络与您的数据库进行通信。
在下一个屏幕上,选择 VPC 网络,并记住数据库主机、用户名、密码和端口的值,因为您需要将这些值添加到您的 containers/app.yml
文件中。
创建数据库集群后,您需要更新 Discourse 的配置。
1sudo nano containers/app.yml
在模板
部分中,如下所示,评论- templates/postgres.template.yml
一行:
1[label containers/app.yml]
2templates:
3# - "templates/postgres.template.yml"
4 - "templates/redis.template.yml"
5 - "templates/web.template.yml"
6 - "templates/web.ratelimited.template.yml"
7 - "templates/loadbalancer.template.yml"
这阻止了Discourse在重新构建时提供自己的Postgres服务器。
接下来,搜索containers/app.yml
的env
部分,并添加下面的行,以数据库用户名、密码、主机、名称和端口为自己的值取代值。
1[label containers/app.yml]
2env:
3 DISCOURSE_DB_USERNAME: your_db_username
4 DISCOURSE_DB_PASSWORD: your_db_password
5 DISCOURSE_DB_HOST: your_db_host
6 DISCOURSE_DB_NAME: your_db_name
7 DISCOURSE_DB_PORT: your_db_port
这些额外的变量允许您的 Droplet 连接到您的外部数据库。
保存文件,按CTRL+X
,然后按y
。
如果您有已有的 Discourse 安装,您应该将其导出作为备份,您可以通过进入网站的管理区域,点击 备份,然后点击 备份来完成此操作。
<$>[注] 注: 有关备份和恢复您的网站的更多信息,请参阅 Discourse 产品文档, Move Your Discourse Instance to a Different Server。
若要应用配置并重建 Discourse,请运行以下命令:
1sudo ./launcher rebuild app
即使您已导出您的网站,您还需要再次通过 Discourse Web 安装来创建新的管理员帐户,然后您可以使用此帐户恢复 Discourse 现在您已连接到您的新数据库。
最后,您将更改一个设置,以确保用户在访问网站时留在相同的 Droplet 上。
在 DigitalOcean 控制面板中回到 Load Balancer 的设置,然后转到 网络,然后转到 负载平衡器,然后转到 设置,然后搜索 粘贴会话。
将 Sticky Sessions从 none更改为 Cookie,然后点击 Save。
Sticky Sessions 确保通过 Load Balancer 访问您的网站的每个用户在访问期间都连接到相同的 Droplet. 这很重要,因为每个 Droplet 仍然有自己的 Redis 实例,而 Redis 是 Discourse 跟踪用户登录时的方式。
正如我们在数据库中所做的那样,您可以将 Redis 移动到自己的专用实例中,然后您不需要 Sticky Sessions。
步骤 5 — (可选) 添加 DigitalOcean 管理 Redis 实例
此步骤是可选的,需要一个DigitalOcean Managed Redis实例. 直到此时,Redis实例被烤到负载平衡器背后的Droplet中,这需要Sticky Sessions来确保用户保持登录。 如果Droplet下载,Load Balancer会将用户共享到您的剩余Droplets中。
将 Redis 服务器外部添加到 Droplets 可以解决这个问题,这将有效地将 Discourse 状态从您的 Droplets 移除。
您可以建立一个 DigitalOcean 管理 Redis 服务器,就像您创建了管理 PostgreSQL 数据库一样。 进入 DigitalOcean 控制面板. 点击 Databases,然后点击 Create,然后点击 Database,并为您的数据库引擎选择 Redis. 选择与其他资源相同的区域,以确保它们在相同的 VPC 网络上。 给您的服务器一个名字,然后点击 Create a database cluster。
就像创建您的 Postgres 数据库一样,你会看到一个欢迎屏幕,其中包含一些 开始步骤。 点击 安全这个数据库集群,输入您的 Droplet 名称,然后点击 只允许这些输入源。
现在您需要为您的 Redis 服务器选择退出策略。选择 allkeys-lru. 此策略意味着如果您的 Redis 服务器填充,它将开始删除其最古老的条目。
如您的 PostgreSQL 数据库,在 ** 连接详细信息 ** 屏幕上,选择 ** VPC 网络 **。
创建 Redis 实例后,您将需要更新您的 Discourse 配置. 使用 nano
打开 containers/app.yml
:
1sudo nano containers/app.yml
如下所示,将 Redis 连接细节添加到env
部分中,请确保用您自己的信息来替换突出的文本(您不需要包含用户名字段)。
1[label containers/app.yml]
2env:
3 DISCOURSE_REDIS_HOST: your_redis_host
4 DISCOURSE_REDIS_PASSWORD: your_redis_password
5 DISCOURSE_REDIS_PORT: your_redis_port
6 DISCOURSE_REDIS_USE_SSL: true
接下来,在模板
部分中,如下所示,评论- templates/redis.template.yml
一行:
1[label containers/app.yml]
2templates:
3# - "templates/postgres.template.yml"
4# - "templates/redis.template.yml"
5 - "templates/web.template.yml"
6 - "templates/web.ratelimited.template.yml"
7 - "templates/loadbalancer.template.yml"
这阻止了 Discourse 创建自己的 Redis 实例。
保存并关闭文件,按CTRL+X
,然后按y
。
若要应用配置并重建 Discourse,请运行以下命令:
1sudo ./launcher rebuild app
有了受管理的 Redis 实例,您将不再需要 Sticky Sessions. 如果您想要,您可以关闭此选项,但您的用户无论如何都不会注意到任何差异。
现在您已将管理数据库添加到配置中,您将创建 Discourse 服务器的快照,以添加更多 Droplets。
步骤6 - 添加额外的滴滴
在此步骤中,您将创建一个 Snapshot of your Discourse Droplet,这使得创建新服务器更容易。
通过访问 DigitalOcean 控制面板创建一个新的快照。 点击 Droplets,找到您的快照,然后点击 Snapshots. 给您的快照一个名字,然后点击 Take live snapshot。
您可以使用此快照在您的负载平衡器背后添加额外的滴滴,并增加您的网站的容量。
每次创建一个新 Droplet 时,您需要更新您的 Postgres 和 Redis 服务器上的可信源,您可以通过控制面板进行更新,就像您在上一步中所做的那样,选择您想要修改的数据库实例,转到 ** Overview**,然后到 Secure this database cluster. 将您的新 Droplet IP 地址添加到可信源列表中。
在此步骤中,您使用了 Snapshot 创建额外的 Droplets,并将其添加到您的 PostgreSQL 和 Redis 实例中作为可信来源。
结论
在本教程中,您将设置一个DigitalOcean负载平衡器背后的Discourse服务器。 为了帮助扩展您的部署,您还添加了一个Managed PostgreSQL数据库和Managed Redis实例。 最后,使用快照和控制面板,您添加了更多的Dropplets。 使用控制面板,您可以随着社区的增长添加更多的资源。
现在你已经设置了负载平衡器,你可以探索其他 DigitalOcean Load Balancers 的使用案例,如 Canary 部署. 你也可以尝试使用命令行连接到你的 Redis 实例,按照教程, 如何通过 Stunnel 和 redis-cli 连接到 TLS 的管理 Redis 实例。