记录一下部署Discourse论坛的过程

Posted by 橙叶 on Wed, Feb 21, 2018
Discourse 是 Stack Overflow 的联合创始人 Jeff Atwood 推出的一个新的开源论坛项目,其目的是为了改变十年未变的论坛软件。它摒弃了传统论坛的话题讨论形式、拥有自学习系统、全Web应用同时适用于桌面和移动终端。
[infobox]本文不是一篇严格的教程,仅为记录技术信息,仅供参考[/infobox]

硬件环境

实际安装前在本地用虚拟机测试了一下,安装所耗费的资源不算少,4GB的内存几乎跑满,所以内存还是要足够的,至少1GB。

考虑到需要使用的配置稍高一些,而Vultr和AWS的账户余额已罄,手头上只有这台2CPU 4GB的ECS,就只好用它了。

论坛占用的存储空间是很难控制的,最好用S3或者OSS这类作为后端存储。也不知道Discourse是否支持,安装完再说。

软件环境

考虑到政策因素,事实上国内正经地搭建论坛比单纯的网站麻烦得多,因为涉及到“交互式服务”。理论上连博客的评论功能都不能要呢。当然,鉴于实际的力度和范围,这一条暂时可以忽略。

按官方的说法,因为直接搭建Discourse要涉及很多服务的配置,很复杂,怕我们拎不清,就直接以Docker的形式打包,还提供了管理容器的脚本。Docker版本要求在ce 17.06.0以上,推荐17.06.2.

当然VPS要支持Docker,比如Bandwagon好像就不能用Docker。

系统仍然推荐Linux,至于具体哪个发行版就没什么讲究了,内核版本别太旧。本文以ubuntu 16.04作为演示环境。

准备好你的邮件服务器,不然连管理员也注册不了。

安装环境

ubuntu的默认apt源所安装的Docker为1.13.0版本,所以要换掉。

删除Ubuntu上旧版本的Docker:

$ sudo apt-get remove docker docker-engine docker.io

从Docker官方源:https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/ 里下载Deb包,选择你需要版本下载。我需要下载docker-ce_17.06.2~ce-0~ubuntu_amd64.deb

下载到服务器上,执行dpkg命令安装:

$ sudo dpkg -i docker-ce_17.06.2~ce-0~ubuntu_amd64.deb

稍等一会即可完成安装。安装完成后查看Docker版本:

$ sudo docker -v
Docker version 17.06.2-ce, build cec0b72

下载官方的管理工具

安装Git:
$ sudo apt-get install git
开始安装,创建目录以及从Github上clone代码:
sudo -s
mkdir /var/discourse
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
执行配置脚本:
./discourse-setup
如果服务器上已有Web服务器运行,就会显示80端口占用的错误:
Port 80 appears to already be in use.

This will show you what command is using port 80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 5623 root 9u IPv4 2002350 0t0 TCP *:http (LISTEN) nginx 5667 www 9u IPv4 2005920 0t0 TCP *:http (LISTEN) nginx 5666 www 9u IPv4 2021920 0t0 TCP *:http (LISTEN)

If you are trying to run Discourse simultaneously with another web server like Apache or nginx, you will need to bind to a different port

需要先关掉Web服务器,继续执行安装。

脚本会询问你网站域名和邮件相关的配置,按提示填写即可。填写完确认一下开始部署Docker容器,好,我先关掉Web服

插:让Discourse和其它网站跑在同一台主机上

20分钟后,

我回来了。在Discourse完成部署后,执行./launcher stop app 停掉容器,此时可以恢复原有的Web服务器了。

现在我们要让Discourse不再占用80端口。编辑/var/discourse/containers/app.yml文件,将开始的一部分改成这样:

找到这样10~17行,将它们修改成这个样子:

# base templates used; can cut down to include less functionality per container templates:
  - "templates/cron.template.yml"
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/sshd.template.yml"
  - "templates/web.template.yml"
  # - "templates/web.ssl.template.yml" # 注释原有配置
  - "templates/web.ratelimited.template.yml"
  - "templates/web.socketed.template.yml"  #添加的新配置,Nginx将使用Unix Socket监听
# which ports to expose?
# expose: comment out entire section

往下拉,看到:

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "80:80"   # http
  - "443:443" # https

将后面两行注释之,或将三行全部注释掉。接下来是Nginx反向代理的配置。这儿有一个简易的模板,扒自官方论坛

server {
    listen 80; listen [::]:80;
    server_name forum.example.com;  # <-- change this

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;  listen [::]:443 ssl http2;
    server_name forum.example.com;  # <-- change this

    ssl on;
    ssl_certificate      /var/discourse/shared/standalone/ssl/ssl.crt;
    ssl_certificate_key  /var/discourse/shared/standalone/ssl/ssl.key;
    ssl_dhparam          /var/discourse/shared/standalone/ssl/dhparams.pem;
    ssl_session_tickets off;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

    http2_idle_timeout 5m; # up from 3m default

    location / {
        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

使用Unix Socket做反向代理,还是第一次见。

简单地改一下,就可以继续了。

继续

按照新模板重新配置容器:
./launcher rebuild app
待配置完成后,访问服务器,点击Register注册管理员,但是我因为邮件配置有问题,无法收到激活邮件,只能手动注册管理员。首先进入容器:
./launcher enter app
创建管理员账户:
rake admin:create
回到原来的页面,此时可以使用刚才创建所用的信息登录了。

邮件问题

此时邮件还是不能正常发送:

而运行于同一台主机上的另一个应用却可以正常发件。经过反复测试,才发现自己多么粗心,没有区分SSL和STARTTLS。邮件服务器时使用的阿里云企业邮箱,官方文档只说SMTP有25(非加密)和465(SSL加密)端口,于是我就耿直地使用465端口,但是Discourse默认使用的是STARTTLS(587端口)。实测阿里云企业邮箱也支持587端口和STARTTLS加密的。

在阿里云主机上部署,还需要额外做些事,详见Discourse中文论坛:https://meta.discoursecn.org/t/topic/28。设置完成后发件基本正常了。

至于国内源的问题倒是没有出现。

小结

总的来说过程还是很顺利的,没有出现什么诡异的错误,可见这套论坛系统已经非常成熟。包括Nginx反向代理、后面的SSO,与WordPress结合使用,都是一次成功,没有卡在某个地方。有许多安装过程中担心的问题也没有出现,支持CDN、S3也是正中我下怀。整个过程耗时很长,每次rebuild都要20分钟左右,后面调试花了我两天。

搭建好的论坛就在这里:https://forum.orgleaf.com,主机4GB的内存快要占满了,好在仍然响应迅速,也没有影响其它应用。只是我很怀疑官方文档上说的1GB也能完美带起来。



comments powered by Disqus