Menu

手动安装Discourse论坛程序

“论坛”作为上一代互联网产品,已经淡出了很多人的互联网生活了。不过,我仍然很喜欢“论坛”这一讨论模式。很多像我一样的互联网遗民,依旧喜欢在各论坛中水贴。今天我们就来介绍一下国外非常著名的Discourse论坛程序的安装与配置。

1, Discourse论坛程序简介

Discourse程序基于Ruby on Rails, Ember.js, 以及PostgreSQL, 完全免费开源。它拥有丰富的功能,强劲的性能,高稳定性与安全性,以及可以高度自定义的界面。其具体功能可以参考官网:https://www.discourse.org/.

Discourse可以使用Docker搭建,也可以纯手工搭建。Docker搭建比较简单,仅在第2节稍做介绍。手动安装可以让您学习Ruby on Rails程序的部署流程,且在排错搜索中提升自己的运维能力。手动部署的Discourse也可以显著降低系统要求。本文将主要介绍在Ubuntu 18.04 LTS操作系统中Discourse的手动搭建,不使用Docker.

本文许多内容翻译自 Linuxbabe , 有删改。本文作者为香菇肥牛,原文链接为 https://qing.su/article/install-discourse-without-docker.html ,转载需注明原文链接。谢谢!

长文预警,现在开始!

2, Docker搭建简介

如果是生产环境,建议您使用Docker来部署Discourse, 因为它易于维护。 Docker版本的Discourse是唯一的可以获得官方技术支持的版本。

使用Docker搭建Discourse非常简单,且支持Linux平台。您需要首先安装git, 然后执行下面的命令即可。引导程序将自动为您安装Docker和其他所有需要的组件。

1
2
3
git clone https: // github.com / discourse / discourse_docker.git / var / discourse
cd / var / discourse
. / discourse-setup

3, 手动安装的系统需求

手动安装的步骤仅在Ubuntu 18.04 LTS 64 bit操作系统上测试通过。Ubuntu 20.04 LTS 64 bit操作系统中可以使用一些方法非常麻烦地勉强安装成功(需要使用另一台Ubuntu 18.04的服务器做一次数据库移植),这里不做介绍了。其他Linux平台无法安装通过。

Discourse程序需要系统有至少1 GB内存。安装完毕后系统占用600 MB左右内存。安装过程需要约1-3小时,请留好时间。请将您的域名解析到服务器上。下文将以域名bbs.qing.su为例指代将要搭建的Discourse论坛域名。

4, 安装并配置PostgreSQL数据库

首先,安装PostgreSQL数据库程序

1
apt-get install postgresql

安装完毕后,PostgreSQL会自动运行在5432端口。然后,使用postgres账户登录postgresql并新建数据库,用户名,以及密码。

1
2
3
4
5
6
7
8
9
sudo - u postgres psql
CREATE DATABASE discourse;
CREATE USER discourse_user;
ALTER USER discourse_user WITH encrypted password 'qing.su' ;
ALTER DATABASE discourse owner TO discourse_user;
\c discourse;
CREATE extension hstore;
CREATE extension pg_trgm;
\q

这里,我们设置数据库名为discourse, 数据库用户名为discourse_user, 密码为qing.su

5, 安装Ruby和Bundler

Discourse是基于Ruby on Rails的,因此需要安装Ruby程序,以及Ruby程序的依赖环境的管理器Bundler.  Ubuntu 18.04版本的官方源中包含了Ruby 2.5版本,Ubuntu 20.04版本的官方源中包含了Ruby 2.7版本。然而,目前Discourse仅支持Ruby 2.6版本。因此,为了方便,我们使用snapd包管理器安装2.6版本的Ruby on Rails.  如果您不信邪地想要在Ubuntu 20.04上安装,这里需要手动编译安装对应的Ruby版本,不知为何snap安装的Ruby和Bundler之后会报错。

1
2
apt-get install snapd
snap install ruby --classic --channel = 2.6 / stable

第一次使用snap安装软件,需要退出SSH然后重新登录SSH.  重新登录后,继续安装Bundler.

1
/ snap / bin / gem install bundler

6, 构建Discourse依赖环境

首先,使用git获取Discourse源代码。

1
2
3
4
5
apt-get install git gcc build-essential ruby-dev libxslt-dev libxml2-dev zlib1g-dev libpq-dev imagemagick screen redis-server optipng pngquant jhead jpegoptim gifsicle
git clone https: // github.com / discourse / discourse.git
mkdir / var / www /
mv discourse / / var / www /
cd / var / www / discourse /

然后前往 https://github.com/discourse/discourse/releases 查看当前的Discourse版本。我这里将使用v2.5.0.

1
git checkout 2.5.0

接下来,开始安装Discourse程序的依赖环境。这里需要安装的组件较多,时间较长,建议使用screen避免掉线后出现错误。

1
2
3
screen -S discourse
RAILS_ENV =production / snap / bin / bundle config set path '/var/www/discourse/vendor/bundle/'
RAILS_ENV =production / snap / bin / bundle install

安装完毕后,按下CTRL + A + D键退出screen.

7, 初始化Discourse数据库

依赖环境搭建完毕,我们开始配置Discourse.  编辑数据库连接文件:

1
2
cp config / discourse_defaults.conf config / discourse.conf
vi config / discourse.conf

找到下面几行,依次填入数据库信息:

1
2
3
4
5
db_host = localhost
db_port = 5432
db_name = discourse
db_username = discourse_user
db_password = qing.su

再找到hostname这行,填写论坛的域名:

1
hostname = "bbs.qing.su"

保存退出。再编辑生产环境ruby配置文件:

1
vi config / environments / production.rb

在该文件第5行添加:

1
require 'uglifier'

然后找到下面这行(我这里是第17行):

1
config. assets . js_compressor = :uglifier

将其替换成:

1
config. assets . js_compressor = Uglifier. new ( harmony: true )

如下图所示:

保存退出。然后,执行下面的命令初始化数据库:

1
RAILS_ENV =production / snap / bin / bundle exec rake db:migrate

如果该命令执行过程中报错,请再执行一遍。

8, 编译静态文件

接下来,我们要编译静态文件,比如javascript文件等。编辑文件 /var/www/discourse/lib/tasks/assets.rake , 找到并注释掉下面这行(我这里是第281行)。

1
brotli ( path, max_compress )

注释掉这一行的原因是brotli压缩和gzip压缩一起编译的时候会冲突报错。

保存退出后,编译安装静态文件:

1
RAILS_ENV =production / snap / bin / bundle exec rake assets:precompile

9, 使用Puma服务器运行Discourse

完整的Discourse部署可以分为后端运行服务器程序与前端反代服务器程序。这一节,我们介绍使用Puma服务器运行Discourse.

编辑文件 /var/www/discourse/config/puma.rb , 找到下面这行:

1
APP_ROOT = '/home/discourse/discourse'

将其替换为我们的Discourse安装目录:

1
APP_ROOT = '/var/www/discourse'

然后建好Puma服务器sockets目录:

1
2
mkdir / var / www / discourse / tmp / sockets /
mkdir / var / www / discourse / tmp / pids /

运行Discourse:

1
RAILS_ENV =production bundle exec puma -C / var / www / discourse / config / puma.rb

如果没有以外,屏幕上会显示一大堆内容,比如下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root @ server: / srv / www / forum / public_html # RAILS_ENV=production bundle exec puma -C /srv/www/forum/public_html/config/puma.rb
[ 13383 ] Puma starting in cluster mode...
[ 13383 ] * Version 4.3.5 ( ruby 2.6.6-p146 ) , codename: Mysterious Traveller
[ 13383 ] * Min threads: 8 , max threads: 32
[ 13383 ] * Environment: development
[ 13383 ] * Process workers: 4
[ 13383 ] * Preloading application
[ 13383 ] * Listening on unix: /// srv / www / forum / public_html / tmp / sockets / puma.sock
[ 13383 ] ! WARNING: Detected 4 Thread ( s ) started in app boot:
[ 13383 ] ! #<Thread:0x00005598f921d918@/srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb:38 sleep_forever> - /srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb:40:in `pop'
[ 13383 ] ! #<Thread:0x00005598fd72a4c0@/srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:334 sleep> - /srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:337:in `sleep'
[ 13383 ] ! #<Thread:0x00005598fe4eb2f8@/srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/message_bus-3.3.1/lib/message_bus.rb:700 sleep> - /srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/redis-4.2.1/lib/redis/connection/ruby.rb:55:in `select'
[ 13383 ] ! #<Thread:0x00005598fe4eb0c8@/srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/message_bus-3.3.1/lib/message_bus/timer_thread.rb:38 sleep> - /srv/www/forum/public_html/vendor/bundle/ruby/2.6.0/gems/message_bus-3.3.1/lib/message_bus/timer_thread.rb:123:in `sleep'
[ 13383 ] * Daemonizing...

最后出现一个* Daemonizing…说明运行成功。此时,Discourse运行于 /var/www/discourse/tmp/sockets/puma.sock .

10, 使用Nginx反代Discourse

上一节我们提到,Discourse部署需要后端运行服务器与前端反代服务器。这一节我们将介绍使用Nginx来反代运行了Discourse的Puma后端服务器。

首先,安装Nginx.  生产环境建议编译安装Nginx.  如果是测试环境,您可以直接用源安装Nginx.

1
apt-get install nginx

将程序提供的nginx配置文件复制到Nginx配置文件目录中,并编辑。

1
2
cp config / nginx.sample.conf / etc / nginx / conf.d / discourse.conf
vi / etc / nginx / conf.d / discourse.conf

找到下面这一段,注释掉:

1
2
3
4
upstream discourse {
server unix: / srv / www / forum / public_html / tmp / sockets / nginx.http.sock;
server unix: / srv / www / forum / public_html / tmp / sockets / nginx.https.sock;
}

找到下面这一段,取消注释:

1
2
3
#upstream discourse {
#        server unix:/srv/www/forum/public_html/tmp/sockets/puma.sock;
#}

找到server_name行,在后面填写您的论坛域名:

1
server_name bbs.qing.su;

找到下面这一行,注释掉:

brotli_static on;

然后保存退出。新建Nginx缓存文件夹,然后重新载入Nginx配置文件:

1
2
mkdir -p / var / nginx / cache /
service nginx reload

此时,访问您的域名,比如http://bbs.qing.su, 应该可以看到Discourse页面了,如下图。

接着给Nginx配置SSL.  这里将使用Let’s Encrypt免费证书。其他的证书安装类似。

1
2
apt-get install certbot python3-certbot-nginx
certbot --nginx --agree-tos --redirect --hsts --staple-ocsp -d bbs.qing.su

请将bbs.qing.su换成您自己的域名。再编辑文件 /etc/nginx/conf.d/discourse.conf ,在SSL配置部分添加下面这一行:

1
add_header Content-Security-Policy upgrade-insecure-requests;

如下图所示:

保存退出后,重新载入Nginx配置文件。

1
service nginx reload

再次访问您的论坛域名,比如https://bbs.qing.su, 就可以看到SSL配置成功了。

11, 创建管理员账号并配置论坛参数

Discourse安装好之后,需要创建管理员账户。如果您一直跟着我的教程操作,那么您当前的目录位置为Discourse程序目录(/var/www/discourse/)。使用下面的命令可以新建管理员账户:

1
RAILS_ENV =production / snap / bin / bundle exec rake admin:create

按照屏幕提示输入邮箱和密码,就会生成管理员账户。如下图。

然后,重启Puma服务器。

1
RAILS_ENV =production bundle exec pumactl -P / var / www / discourse / tmp / pids / puma.pid restart

此时,访问您的论坛页面,您可以看到类似于下面的窗口,可以用管理员账号登录了。

如果您打开网站后发现是502错误,说明Puma重启失败,可以执行下面的命令启动Discourse:

1
RAILS_ENV =production bundle exec puma -C / var / www / discourse / config / puma.rb

登录之后,点击页面上面的Setup Wizard, 开始设置Discourse参数,比如站点名,站点标题,板块,Logo, 等等。

如果您使用CloudFlare CDN反代您的网站,您需要配置CDN域名,请在后台找到settings -> security -> content security policy src, 然后添加https://bbs.qing.su/cdn-cgi/.  将bbs.qing.su换为您的域名。

12, 使用Sidekiq运行后台服务

Sidekiq是一个开源的计划任务执行程序。通过配置Sidekiq, 我们能够实现发送注册邮件等后台任务。这里,我们可以把Sidekiq简单地理解为系统里的cron job.

编辑文件 /var/www/discourse/config/sidekiq.yml ,在文件末尾添加下面这几行:

1
2
3
4
5
6
7
production:
:concurrency: 2
:queues:
- [ critical, 4 ]
- [ default, 2 ]
- [ low ]
- [ ultra_low ]

如果您的访客量较大,可以提高对应的数值。

保存退出,然后新建sidekiq后台服务。新建文件 /etc/systemd/system/discourse-sidekiq.service , 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[ Unit ]
Description =Discourse sidekiq background processing service
After =multi-user.target
[ Service ]
Type =simple
User =root
PIDFile = / var / www / discourse / tmp / pids / sidekiq.pid
WorkingDirectory = / var / www / discourse
Environment = RAILS_ENV =production
ExecStart = / snap / bin / bundle exec sidekiq -C config / sidekiq.yml
Restart =on-failure
RestartSec = 5
[ Install ]
WantedBy =multi-user.target

然后运行sidekiq服务:

1
service discourse-sidekiq start

13, 为Discourse建立系统服务

如果您一直跟着我的教程操作,那么您当前的目录位置为Discourse程序目录( /var/www/discourse/ )。先暂停Puma服务器:

1
RAILS_ENV =production / snap / bin / bundle exec pumactl -P / var / www / discourse / tmp / pids / puma.pid stop

编辑文件 /var/www/discourse/config/puma.rb , 然后分别找到下面这两行,注释掉。

1
pidfile "#{APP_ROOT}/tmp/pids/puma.pid"
1
daemonize true

然后新建puma-discourse后台服务。新建文件 /etc/systemd/system/discourse.service , 内容为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ Unit ]
Description =Discourse service
[ Service ]
Type =simple
User =root
PIDFile = / var / www / discourse / tmp / pids / puma.pid
WorkingDirectory = / var / www / discourse
Environment = RAILS_ENV =production
ExecStart = / snap / bin / bundle exec puma -C config / puma.rb
Restart =on-failure
RestartSec = 5
[ Install ]
WantedBy =multi-user.target

然后,运行服务:

1
service discourse start

此时访问您的论坛,应当正常运行了。

14, 其他设置

论坛注册或者通知需要使用邮件系统。可以编辑 /var/www/discourse/config/discourse.conf 文件配置SMTP发信。

找到下面几行:

1
2
3
4
5
6
7
8
smtp_address =
smtp_port = 587
smtp_domain =
smtp_user_name =
smtp_password =
smtp_authentication = plain
smtp_enable_start_tls = true
notification_email =

填上您的邮件服务器信息即可。

我们还可以修改Discourse运行参数,减少其内存占用。编辑文件 /var/www/discourse/config/puma.rb , 更改workers和threads值。下面的值对于一个单核, 1 GB内存的VPS较为合适。

1
2
workers 2
threads 4 , 16

修改Discourse的任何配置文件后,需要重启服务。

1
service discourse restart

到这里,我们成功在Ubuntu 18.04 LTS 64 bit操作系统上安装并配置好了Discourse论坛程序。通过本教程,您还可以学习到Ruby on Rails程序通常的安装部署方法,Puma服务器的使用,Nginx反代与配置SSL, Systemd的写法等各种知识。如果您想在生产环境中使用,建议您使用Docker安装。

本文许多内容翻译自 Linuxbabe , 有删改。如果您在安装过程中遇到各种问题,欢迎留言与我讨论。本文作者为香菇肥牛,原文链接为 https://qing.su/article/install-discourse-without-docker.html ,转载需注明原文链接。谢谢!

Leave a Comment Cancel reply