Discourse 中文安装指南

2013/09/04 21:15
阅读数 4.7K

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

当前版本: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 admin@ofgeek.com

更新 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 discourse@ofgeek.com

到这里,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 论坛地址,并注册一个用户,本文中注册的邮件地址为 admin@ofgeek.com。
然后再次用 discourse 用户登录 VPS,执行以下命令:

1 $ ssh discourse@ofgeek.com
2 $ cd ~/discourse
3 $ RAILS_ENV=production bundle exec rails c
4 > me = User.find_by_username_or_email('admin@ofgeek.com')
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 discourse@ofgeek.com
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 致谢

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

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

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

展开阅读全文
打赏
0
19 收藏
分享
加载中

引用来自“gotham”的评论

引用来自“伊藤熊吉”的评论

引用来自“gotham”的评论

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

很多时候不要总记得自己是个开发人员,有好东西就用吧,我们一些朋友在开发python的

哈哈,习惯性的代入到了coder的程序思维中,最近我们也在写一个自己的论坛,你们用什么沟通呢?能围观么

有兴趣可以加我们的,IT联合创业群,群号:330235798,不少做开发的朋友在里面吹牛啊。

晚上下班回去加
2013/09/05 15:52
回复
举报

引用来自“jerrytao”的评论

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

ruby怎么了。。。

我不会ruby 看不懂。就是这样
2013/09/05 15:51
回复
举报

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

ruby怎么了。。。
2013/09/05 15:44
回复
举报
到处看看博主

引用来自“伊藤熊吉”的评论

引用来自“gotham”的评论

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

很多时候不要总记得自己是个开发人员,有好东西就用吧,我们一些朋友在开发python的

哈哈,习惯性的代入到了coder的程序思维中,最近我们也在写一个自己的论坛,你们用什么沟通呢?能围观么

有兴趣可以加我们的,IT联合创业群,群号:330235798,不少做开发的朋友在里面吹牛啊。
2013/09/05 12:02
回复
举报

引用来自“gotham”的评论

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

很多时候不要总记得自己是个开发人员,有好东西就用吧,我们一些朋友在开发python的

哈哈,习惯性的代入到了coder的程序思维中,最近我们也在写一个自己的论坛,你们用什么沟通呢?能围观么
2013/09/05 12:00
回复
举报
到处看看博主

引用来自“伊藤熊吉”的评论

discourse的很多功能做的确实不错,可惜ruby的

很多时候不要总记得自己是个开发人员,有好东西就用吧,我们一些朋友在开发python的
2013/09/05 11:59
回复
举报
discourse的很多功能做的确实不错,可惜ruby的
2013/09/05 11:58
回复
举报
更多评论
打赏
7 评论
19 收藏
0
分享
返回顶部
顶部