侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Discourse 中文安装指南

2022-06-25 星期六 / 0 评论 / 0 点赞 / 72 阅读 / 64080 字

说明:本站制作的旧版中文安装指南是根据外国网友的文档制作的,当时还没有官方安装文档。后来官方发布了正式的安装文档,因此本站根据官方指南重新制作了中文安装文档。 当前版本:0.2.0,最近更新于 2

说明:本站制作的旧版中文安装指南是根据外国网友的文档制作的,当时还没有官方安装文档。后来官方发布了正式的安装文档,因此本站根据官方指南重新制作了中文安装文档。

当前版本:0.2.0,最近更新于 2013.7.8。

0 相关说明

Discourse 意为“谈话”,是由 Stack Overflow 的联合创始人 Jeff Atwood 推出的下一代开源论坛程序,关于它的介绍可以看看 OSChina 和 36Kr 的报道。目前,网络上还没有一份详细、全面的中文 Discourse 安装指南,ofGEEK 特此整理编写本文,希望能够对需要的人有所帮助。

由于 Discourse 仍在不断更新变化之中,本指南也将随之不断调整,以适应最新的系统安装环境。更多相关信息与讨论,请访问 ofGEEK 讨论区 的 Discourse 分类(这个讨论区就是用 Discourse 搭建而成的)。

本指南在以下环境安装成功:

  • 一台 KVM VPS 服务器
  • 内存 1G (Discourse 官方推荐的最小值)
  • Ubuntu 12.10 x86 操作系统

1 准备安装环境

注意:为了操作的安全,不推荐直接使用 root 账户安装 Discourse,建议在 VPS 上增加一个用户(本文设为 admin,你可以任意选择喜欢的名称),专门用于安装 Discourse。本文中,VPS 的主机名即为域名 ofgeek.com,读者请根据实际情况自行修改。

1.1 登录 VPS

用 root 登录 VPS,创建新用户 admin,并将其加入 sudo 组,以获取管理员权限。(关于登录 VPS 的方法,本文不做详细介绍,如有需要请自行查阅。Mac OS X 或 Linux 用户可以直接打开终端使用 ssh 进行连接。Windows 用户推荐使用 Xshell,非商业用途可免费使用)。

. . . .
1 $ sudo adduser admin
. .
2 $ sudo adduser admin sudo
. . . .

退出 root 账户,用 admin 账户重新登录 VPS。

. . . .
1 $ logout
. .
2 $ ssh [email protected]
. . . .

更新 VPS 的操作系统:

. . . .
1 $ sudo apt-get update && sudo apt-get -y upgrade
. . . .

如果更新过程中,系统提示是否更新 grub 菜单,请选择不更新。

1.2 安装 Discourse 所需的包文件

. . . .
1 $ sudo tasksel install openssh-server
. .
2 $ sudo tasksel install mail-server
. .
3 $ sudo tasksel install postgresql-server
. . . .

在安装过程中,会弹出 Postfix 的配置界面,它是 Linux 系统中的邮件配置程序。如果你决定使用同一台 VPS 来发送邮件,则选择”Internet Site”,本例中,我们将使用第三方提供的邮件发送服务,所以选择“Satellite system”。然后在下一步输入你自己的域名,在本文中则是 ofgeek.com。具体的邮件设定将在下文有详细介绍。
继续安装其它所需的包文件:

. . . .
1 $ sudo apt-get -y install build-essential libssl-dev libyaml-dev git libtool libxslt-dev libxml2-dev redis-server libpq-dev gawk curl pngcrush
. . . .

1.3 设定主机名称

这里需要用到文本编辑器,你可以根据自己的喜好使用 vi、emacs 或其它,Ubuntu 12.10 系统里默认的是 nano。

. . . .
1 $ sudo nano /etc/hosts
. . . .

在第一行下面加入你的 VPS 的 IP 和域名,本文修改成:

. . . .
1 127.0.0.1  localhost
. .
2 12.34.56.78  ofgeek.com
. . . .

确认无误后,按 Ctrl+x 保存,按 y 确认后退出。
然后再修改 hostname:

. . . .
1 $ sudo nano /etc/hostname
. . . .

本文修改成:

. . . .
1 ofgeek.com
. . . .

1.4 安装最新版的 Nginx

先删除 VPS 自带的老版本 nginx(如果你的 VPS 没有安装 nginx 则无需这一步):

. . . .
1 $ sudo apt-get remove '^nginx.*$'
. . . .

更新软件源:

. . . .
1 $ cat <<'EOF' | sudo tee -a /etc/apt/sources.list
. .
2  
. .
3 deb http://nginx.org/packages/ubuntu/ precise nginx
. .
4 deb-src http://nginx.org/packages/ubuntu/ precise nginx
. .
5 EOF
. . . .

加入 nginx 密钥:

. . . .
1 $ curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
. . . .

安装 nginx:

. . . .
1 $ sudo apt-get update && sudo apt-get -y install nginx
. . . .

1.5 安装 RVM

. . . .
1 $ /curl -s -S -L https://get.rvm.io | sudo bash -s stable
. .
2 $ sudo adduser $USER rvm
. .
3 $ newgrp rvm
. .
4 $ . /etc/profile.d/rvm.sh
. .
5 $ rvm requirements
. . . .

如果系统报权限不够,则运行

. . . .
1 $ rvm --autolibs=read-fail requirements
. . . .

根据报告中的说明,单独安装所需的包,然后再继续安装。

1.6 安装 Ruby 2.0 和打包程序

. . . .
1 $ rvm install 2.0.0
. .
2 $ gem install bundler
. . . .

到这里,Discourse 的安装环境就准备完成了。

2 安装 Discourse

2.1 创建 discourse 用户

按照官方的教程,我们将在 VPS 上再创建一个名为 discourse 的用户,专门用于安装 discourse 论坛。

. . . .
1 $ sudo adduser --shell /bin/bash discourse
. .
2 $ sudo adduser discourse rvm
. . . .

为用户 discourse 赋予操作数据库的权限:

. . . .
1 $ sudo -u postgres createuser -s discourse
. .
2 $ sudo -u postgres psql -c "alter user discourse password '[你自己设定的密码]';"
. . . .

切换到 discourse 用户:

. . . .
1 $ sudo su - discourse
. . . .

2.2 下载并安装 discourse 源码

. . . .
1 $ git clone git://github.com/discourse/discourse.git
. .
2 $ cd discourse
. .
3 $ git checkout latest-release
. .
4 $ bundle install --deployment --without test
. . . .

最后这一步耗时较长,请耐心等待。安装完毕后,就可以开始配置 discourse 了。

2.3 修改 Discourse 的相关配置文件

. . . .
1 $ cd ~/discourse/config
. .
2 $ cp database.yml.production-sample database.yml
. .
3 $ cp redis.yml.sample redis.yml
. .
4 $ cp discourse.pill.sample discourse.pill
. .
5 $ cp environments/production.rb.sample environments/production.rb
. . . .

2.3.1 修改 database.yml

. . . .
1 $ nano database.yml
. . . .

需要修改的内容包括:

  • 用户名
  • 密码
  • 主机名

实际上,你还可以修改数据库的名称,不过这里不建议新手修改。 本文修改后的 database.yml 如下,请结合你的实际情况加以修改:

. . . .
01 production:
. .
02   adapter: postgresql
. .
03   database: discourse_prod
. .
04   username: discourse   # if using username/password auth
. .
05   password: [你自己设定的密码]   # if using username/password auth
. .
06   # host: dbhost                # if not localhost
. .
07   pool: 5       # size of DB connection pool *per process*
. .
08   timeout: 5000
. .
09   # db_id: 0    # database ID if hosting multiple sites
. .
10   host_names:
. .
11     - ofgeek.com # Update this to be the domain of your production site
. .
12  
. .
13 test:
. .
14   adapter: postgresql
. .
15   database: discourse_test
. .
16   # username: discourse_test
. .
17   # password: 123123123123
. .
18   min_messages: warning
. .
19   host: localhost
. .
20   pool: 5
. .
21   timeout: 5000
. .
22   host_names:
. .
23     - test.localhost
. . . .

2.3.2 修改 discourse.pill

. . . .
1 $ nano discourse.pill
. . . .

需要修改的内容包括:

  • 将 rails_root 设为 /home/discourse/discourse
  • 删除# Running bluepill as a user? Use:这一行下面那行的注释符号
  • 找到 if `hostname`.strip == “host to run on” 这一行,将其中的host to run on改为你自己的主机名

本文修改后的 database.yml 如下,请结合你的实际情况加以修改:

. . . .
001 rails_env   = ENV['RAILS_ENV']  || "production"
. .
002 rails_root  = ENV['RAILS_ROOT'] || "/home/discourse/discourse"
. .
003  
. .
004 user = ENV["DISCOURSE_USER"] || ENV['USER'] || 'discourse'
. .
005 group = ENV["DISCOURSE_GROUP"] || ENV['GROUP'] || 'www-data'
. .
006 num_webs = ENV["NUM_WEBS"].to_i > 0 ? ENV["NUM_WEBS"].to_i : 4
. .
007  
. .
008 # to debug use
. .
009 #Bluepill.application("your_app", :foreground => true) do |app|
. .
010  
. .
011 # Running bluepill as a user? Use:
. .
012 Bluepill.application("discourse", :base_dir => ENV["HOME"] + '/.bluepill') do |app|
. .
013  
. .
014 # Running bluepill as root? Use:
. .
015 #Bluepill.application("discourse") do |app|
. .
016  
. .
017   app.gid = group
. .
018   app.uid = user
. .
019  
. .
020   # getting this to work was a nightmare
. .
021   # bundle exec spawns a process totally messing with the demonize option
. .
022   # so we suck the environment out and set it up first
. .
023   app.environment = `env -i BUNDLE_GEMFILE=#{rails_root}/Gemfile /usr/local/rvm/bin/bootup_bundle exec env`.l$
. .
024      kv = l.chomp.split('=',2)
. .
025      env_hash[kv[0]] = kv[1]
. .
026      env_hash
. .
027   end if File.exist?("/usr/local/rvm/bin/rvm")
. .
028  
. .
029   app.environment ||= {}
. .
030   app.environment['RAILS_ENV'] = rails_env
. .
031  
. .
032   app.gid = group
. .
033   app.uid = user
. .
034  
. .
035     app.working_dir = rails_root
. .
036   sockdir = "#{rails_root}/tmp/sockets"
. .
037   File.directory? sockdir or Dir.mkdir sockdir
. .
038   num_webs.times do |i|
. .
039     app.process("thin-#{i}") do |process|
. .
040       process.start_command  = "bundle exec thin start -e production -t 0 --socket #{sockdir}/thin.#{i}.sock $
. .
041  
. .
042       # Alternatively, you can start with a port number instead of a socket. If you do that, then you MUST up$
. .
043       # the upstream section in the nginx config to match.
. .
044       # The nginx.sample.conf file assumes you're using sockets.
. .
045       # process.start_command  = "bundle exec thin start -e production -t 0 -p #{9040 + i} -P #{rails_root}/t$
. .
046  
. .
047       process.pid_file = "#{rails_root}/tmp/pids/thin#{i}.pid"
. .
048       process.start_grace_time = 30.seconds
. .
049       process.stop_grace_time = 10.seconds
. .
050       process.restart_grace_time = 10.seconds
. .
051       process.group = "thins"
. .
052       process.uid = user
. .
053       process.gid = group
. .
054       process.daemonize = false
. .
055       process.stdout = process.stderr = "#{rails_root}/log/thin#{i}.log"
. .
056     end
. .
057   end
. .
058  
. .
059 #debug instance
. .
060 #    app.process("thin-debug") do |process|
. .
061 #      process.start_command  = "bundle exec thin start -e development -t 0 -p 10040 -P #{rails_root}/tmp/pid$
. .
062 #      process.pid_file = "#{rails_root}/tmp/pids/thin-debug.pid"
. .
063 #      process.start_grace_time = 30.seconds
. .
064 #      process.stop_grace_time = 10.seconds
. .
065 #      process.restart_grace_time = 10.seconds
. .
066 #      process.group = "thins"
. .
067 #      process.uid = user
. .
068 #      process.gid = group
. .
069 #      process.daemonize = false
. .
070 #      process.stdout = process.stderr = "#{rails_root}/log/thin-debug.log"
. .
071 #    end
. .
072  
. .
073   app.process("sidekiq-worker") do |process|
. .
074     pidfile = "#{rails_root}/tmp/pids/sidekiq-worker.pid"
. .
075  
. .
076     process.start_command  = "/usr/bin/env PIDFILE=#{pidfile} RAILS_ENV=#{rails_env} bundle exec sidekiq"
. .
077     process.pid_file = pidfile
. .
078     process.start_grace_time = 30.seconds
. .
079     process.stop_grace_time = 10.seconds
. .
080     process.restart_grace_time = 10.seconds
. .
081     process.uid = user
. .
082     process.gid = group
. .
083     process.daemonize = true
. .
084   end
. .
085  
. .
086   if `hostname`.strip == "ofgeek.com"
. .
087     app.process("clockwork") do |process|
. .
088       pidfile = "#{rails_root}/tmp/pids/clockwork.pid"
. .
089  
. .
090       process.start_command  = "/usr/bin/env RAILS_ENV=#{rails_env} bundle exec clockwork config/clock.rb"
. .
091       process.pid_file = pidfile
. .
092       process.start_grace_time = 30.seconds
. .
093       process.stop_grace_time = 10.seconds
. .
094       process.restart_grace_time = 10.seconds
. .
095       process.uid = user
. .
096 #      process.restart_grace_time = 10.seconds
. .
097 #      process.group = "thins"
. .
098 #      process.uid = user
. .
099 #      process.gid = group
. .
100 #      process.daemonize = false
. .
101 #      process.stdout = process.stderr = "#{rails_root}/log/thin-debug.log"
. .
102 #    end
. .
103  
. .
104   app.process("sidekiq-worker") do |process|
. .
105     pidfile = "#{rails_root}/tmp/pids/sidekiq-worker.pid"
. .
106  
. .
107     process.start_command  = "/usr/bin/env PIDFILE=#{pidfile} RAILS_ENV=#{rails_env} bundle exec sidekiq"
. .
108     process.pid_file = pidfile
. .
109     process.start_grace_time = 30.seconds
. .
110     process.stop_grace_time = 10.seconds
. .
111     process.restart_grace_time = 10.seconds
. .
112     process.uid = user
. .
113     process.gid = group
. .
114     process.daemonize = true
. .
115   end
. .
116  
. .
117   if `hostname`.strip == "ofgeek.com"
. .
118     app.process("clockwork") do |process|
. .
119       pidfile = "#{rails_root}/tmp/pids/clockwork.pid"
. .
120  
. .
121       process.start_command  = "/usr/bin/env RAILS_ENV=#{rails_env} bundle exec clockwork config/clock.rb"
. .
122       process.pid_file = pidfile
. .
123       process.start_grace_time = 30.seconds
. .
124       process.stop_grace_time = 10.seconds
. .
125       process.restart_grace_time = 10.seconds
. .
126       process.uid = user
. . . .

2.3.3 修改 secret_token.rb 文件

为了保证站点的安全,需要生成密钥会话令牌。

. . . .
1 $ cd ~/discourse
. .
2 $ rake secret
. . . .

将生成的密钥记下来,打开 config/initializers/secret_token.rb 文件

. . . .
1 $ nano config/initializers/secret_token.rb
. . . .

执行以下步骤:

  • 清空该文件中的所有已有内容
  • 将下面这行代码拷贝到该文件中,用刚才生成的密钥代替 [TOKEN] 部分
. . . .
1 Discourse::Application.config.secret_token = "[TOKEN]"
. . . .

2.3.4 修改 production.rb 文件,设定邮件发送方式

Discourse 中,系统邮件是非常重要的,它涉及到激活用户、修改邮箱、修改密码等多项功能。如果你希望用 VPS 本身发送邮件,则需安装 sendmail(具体设置方法请自行查阅):

. . . .
1 $ sudo apt-get install sendmail
. . . .

如果你已经有了邮件服务器,则可以通过 smtp 服务发送系统邮件,本文推荐使用mandrillapp.com 提供的邮件发送服务,对于规模不大的论坛而言,它每个月 12000 封的免费方案就够用了。注册通过后,去 mandrillapp 后台生成一个 smtp 密钥。

修改 config/environments/production.rb 文件:

. . . .
1 $ nano config/environments/production.rb
. . . .

修改其中有关邮件发送的部分,本文中如下:

. . . .
01 # you may use other configuration here for mail eg: sendgrid
. .
02  
. .
03  config.action_mailer.delivery_method = :smtp
. .
04  config.action_mailer.smtp_settings = {
. .
05    :address              => "smtp.mandrillapp.com",
. .
06    :port                 => 587,
. .
07    :domain               => 'ofgeek.com',
. .
08    :user_name            => '[你在mandillapp的用户名]',
. .
09    :password             => '[你在mandillapp生成的smtp密钥]',
. .
10    :authentication       => 'login',
. .
11    :enable_starttls_auto => true  }
. .
12  
. .
13 #config.action_mailer.delivery_method = :sendmail
. .
14 #config.action_mailer.sendmail_settings = {arguments: '-i'}
. . . .

2.4 初始化数据库

. . . .
1 $ cd ~/discourse
. .
2 $ createdb discourse_prod
. .
3 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake db:migrate
. .
4 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake assets:precompile
. . . .

2.5 配置服务环境

2.5.1 配置 Nginx

切换到 admin 用户

. . . .
1 $ sudo su - admin
. . . .

编辑 nginx.conf

. . . .
1 $ sudo nano /etc/nginx/nginx.conf
. . . .

在 http 部分加入下面一行:

. . . .
1 server_names_hash_bucket_size 64;
. . . .

如果该 VPS 上只有 discourse 一项服务,则禁用默认的 nginx 站点:

. . . .
1 $ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled
. . . .

编辑 discourse.conf

. . . .
1 $ sudo cp ~/discourse/discourse/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf
. .
2 $ sudo nano /etc/nginx/conf.d/discourse.conf
. . . .

将 server_name 改为你自己的主机名。
根据实际情况修改 socket 和 root 的路径,本文中如下:

. . . .
01 upstream discourse {
. .
02   server unix:/home/discourse/discourse/tmp/sockets/thin.0.sock;
. .
03   server unix:/home/discourse/discourse/tmp/sockets/thin.1.sock;
. .
04   server unix:/home/discourse/discourse/tmp/sockets/thin.2.sock;
. .
05   server unix:/home/discourse/discourse/tmp/sockets/thin.3.sock;
. .
06 }
. .
07  
. .
08 server {
. .
09  
. .
10   listen 80;
. .
11   gzip on;
. .
12   gzip_min_length 1000;
. .
13   gzip_types application/json text/css application/x-javascript;
. .
14  
. .
15   server_name ofgeek.com;
. .
16  
. .
17   sendfile on;
. .
18  
. .
19   keepalive_timeout 65;
. .
20  
. .
21   location / {
. .
22     root /home/discourse/discourse/public;
. .
23  
. .
24     location ~ ^/t//[0-9]+//[0-9]+//avatar {
. .
25       expires 1d;
. .
26       add_header Cache-Control public;
. .
27           add_header ETag "";
. .
28     }
. .
29  
. .
30     location ~ ^/assets/ {
. .
31       expires 1y;
. .
32       add_header Cache-Control public;
. .
33       add_header ETag "";
. .
34       break;
. .
35     }
. .
36  
. .
37     proxy_set_header  X-Real-IP  $remote_addr;
. .
38     proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
. .
39     proxy_set_header  X-Forwarded-Proto $scheme;
. .
40     proxy_set_header  Host $http_host;
. .
41  
. .
42     # If the file exists as a static file serve it directly without
. .
43     # running all the other rewite tests on it
. .
44     if (-f $request_filename) {
. .
45       break;
. .
46     }
. .
47  
. .
48     if (!-f $request_filename) {
. .
49       proxy_pass http://discourse;
. .
50           break;
. .
51     }
. .
52  
. .
53   }
. .
54  
. .
55 }
. . . .

重启 nginx 服务:

. . . .
1 $ sudo /etc/init.d/nginx reload
. . . .

2.5.2 安装并配置 Bluepill

Discourse 官方使用 bluepill 来管理所有 discourse 的相关服务,省去了很多麻烦。
切换到 discourse 用户

. . . .
1 $ sudo su - discourse
. . . .

安装并配置 bluepill

. . . .
1 $ gem install bluepill
. .
2 $ echo 'alias bluepill="NOEXEC_DISABLE=1 bluepill --no-privileged -c ~/.bluepill"' >> ~/.bash_aliases
. .
3 $ rvm wrapper $(rvm current) bootup bluepill
. .
4 $ rvm wrapper $(rvm current) bootup bundle
. . . .

注销并重新登录以激活 bluepill

. . . .
1 $ logout
. .
2 $ ssh [email protected]
. . . .

到这里,discourse 就安装完成了,可以通过下面的命令行来启动:

. . . .
1 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=4 bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill
. . . .

为了让 discourse 每次开机就能自动运行,还需要在 crontab 里写入 bluepill 服务:

. . . .
1 $ crontab -e
. . . .

在其中写入下面一行:

. . . .
1 @reboot RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=4 /usr/local/rvm/bin/bootup_bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill
. . . .

2.6 创建管理员

登录你的 discourse 论坛地址,并注册一个用户,本文中注册的邮件地址为 [email protected]
然后再次用 discourse 用户登录 VPS,执行以下命令:

. . . .
1 $ ssh [email protected]
. .
2 $ cd ~/discourse
. .
3 $ RAILS_ENV=production bundle exec rails c
. .
4 > me = User.find_by_username_or_email('[email protected]')
. .
5 > me.activate
. .
6 > me.admin = true
. .
7 > me.save
. . . .

2.7 启用中文支持

目前,Discourse 已经可以支持中文界面,使用管理员账户登录后,点击右上角的管理员名称进入设置界面,然后再点击右上角的小扳手 Admin 进入系统管理界面,在第二项 Settings 中,把 default_locale 从默认的 en 更改为 zh_CN,然后返回论坛主界面,按 Ctrl+F5 刷新浏览器缓存,中文界面就出来了。

3 更新

鉴于 discourse 更新很快,建议每隔几天就执行一次更新。
用 discourse 用户登录 VPS,执行以下命令:

. . . .
01 $ ssh [email protected]
. .
02 $ bluepill stop
. .
03 $ cd ~/discourse
. .
04 $ git checkout master
. .
05 $ git pull
. .
06 $ git fetch --tags
. .
07 $ bundle install --without test --deployment
. .
08 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake db:migrate
. .
09 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake assets:precompile
. .
10 $ bluepill start
. . . .

如果启动失败并出现重试,则按 Ctrl+C 中止,然后执行以下两条命令重启 bluepill 服务:

. . . .
1 $ bluepill quit
. .
2 $ RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=4 /usr/local/rvm/bin/bootup_bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill
. . . .

4 致谢

本指南基于以下资源创建,特此表示感谢:

  • Discourse 官方安装指南。
  • Christopher Baus 的 Discourse 安装指南(英文)。
  • Lee Dohm 的 Discourse 安装指南(英文)。
  • surrealroad 的 Discourse 安装指南(英文)。

后面再用centos安装了一下,基本差不多,天不遂人愿啊,vps提供商提供的centos好用些。

弄了个论坛在: itbbs.uwetech.com

广告 广告

评论区