说明:本站制作的旧版中文安装指南是根据外国网友的文档制作的,当时还没有官方安装文档。后来官方发布了正式的安装文档,因此本站根据官方指南重新制作了中文安装文档。
当前版本: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,非商业用途可免费使用)。
2 |
$ sudo adduser admin sudo |
退出 root 账户,用 admin 账户重新登录 VPS。
更新 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。
在第一行下面加入你的 VPS 的 IP 和域名,本文修改成:
确认无误后,按 Ctrl+x 保存,按 y 确认后退出。
然后再修改 hostname:
1 |
$ sudo nano /etc/hostname |
本文修改成:
1.4 安装最新版的 Nginx
先删除 VPS 自带的老版本 nginx(如果你的 VPS 没有安装 nginx 则无需这一步):
1 |
$ sudo apt-get remove '^nginx.*$' |
更新软件源:
1 |
$ cat <<'EOF' | sudo tee -a /etc/apt/sources.list |
3 |
deb http://nginx.org/packages/ubuntu/ precise nginx |
4 |
deb-src http://nginx.org/packages/ubuntu/ precise nginx |
加入 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 |
4 |
$ . /etc/profile.d/rvm.sh |
如果系统报权限不够,则运行
1 |
$ rvm --autolibs=read-fail requirements |
根据报告中的说明,单独安装所需的包,然后再继续安装。
1.6 安装 Ruby 2.0 和打包程序
到这里,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 用户:
2.2 下载并安装 discourse 源码
1 |
$ git clone git://github.com/discourse/discourse.git |
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
需要修改的内容包括:
实际上,你还可以修改数据库的名称,不过这里不建议新手修改。 本文修改后的 database.yml 如下,请结合你的实际情况加以修改:
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* |
09 |
# db_id: 0 # database ID if hosting multiple sites |
11 |
- ofgeek.com # Update this to be the domain of your production site |
15 |
database: discourse_test |
16 |
# username: discourse_test |
17 |
# password: 123123123123 |
2.3.2 修改 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" |
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 |
009 |
#Bluepill.application("your_app", :foreground => true) do |app| |
011 |
# Running bluepill as a user? Use: |
012 |
Bluepill.application("discourse", :base_dir => ENV["HOME"] + '/.bluepill') do |app| |
014 |
# Running bluepill as root? Use: |
015 |
#Bluepill.application("discourse") do |app| |
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] |
027 |
end if File.exist?("/usr/local/rvm/bin/rvm") |
029 |
app.environment ||= {} |
030 |
app.environment['RAILS_ENV'] = rails_env |
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 $ |
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$ |
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" |
054 |
process.daemonize = false |
055 |
process.stdout = process.stderr = "#{rails_root}/log/thin#{i}.log" |
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" |
068 |
# process.gid = group |
069 |
# process.daemonize = false |
070 |
# process.stdout = process.stderr = "#{rails_root}/log/thin-debug.log" |
073 |
app.process("sidekiq-worker") do |process| |
074 |
pidfile = "#{rails_root}/tmp/pids/sidekiq-worker.pid" |
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 |
083 |
process.daemonize = true |
086 |
if `hostname`.strip == "ofgeek.com" |
087 |
app.process("clockwork") do |process| |
088 |
pidfile = "#{rails_root}/tmp/pids/clockwork.pid" |
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 |
096 |
# process.restart_grace_time = 10.seconds |
097 |
# process.group = "thins" |
099 |
# process.gid = group |
100 |
# process.daemonize = false |
101 |
# process.stdout = process.stderr = "#{rails_root}/log/thin-debug.log" |
104 |
app.process("sidekiq-worker") do |process| |
105 |
pidfile = "#{rails_root}/tmp/pids/sidekiq-worker.pid" |
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 |
114 |
process.daemonize = true |
117 |
if `hostname`.strip == "ofgeek.com" |
118 |
app.process("clockwork") do |process| |
119 |
pidfile = "#{rails_root}/tmp/pids/clockwork.pid" |
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 |
2.3.3 修改 secret_token.rb 文件
为了保证站点的安全,需要生成密钥会话令牌。
将生成的密钥记下来,打开 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 |
03 |
config.action_mailer.delivery_method = :smtp |
04 |
config.action_mailer.smtp_settings = { |
05 |
:address => "smtp.mandrillapp.com", |
07 |
:domain => 'ofgeek.com', |
08 |
:user_name => '[你在mandillapp的用户名]', |
09 |
:password => '[你在mandillapp生成的smtp密钥]', |
10 |
:authentication => 'login', |
11 |
:enable_starttls_auto => true } |
13 |
#config.action_mailer.delivery_method = :sendmail |
14 |
#config.action_mailer.sendmail_settings = {arguments: '-i'} |
2.4 初始化数据库
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 用户
编辑 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 的路径,本文中如下:
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; |
13 |
gzip_types application/json text/css application/x-javascript; |
15 |
server_name ofgeek.com; |
22 |
root /home/discourse/discourse/public; |
24 |
location ~ ^/t\/[0-9]+\/[0-9]+\/avatar { |
26 |
add_header Cache-Control public; |
30 |
location ~ ^/assets/ { |
32 |
add_header Cache-Control public; |
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; |
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) { |
48 |
if (!-f $request_filename) { |
49 |
proxy_pass http://discourse; |
重启 nginx 服务:
1 |
$ sudo /etc/init.d/nginx reload |
2.5.2 安装并配置 Bluepill
Discourse 官方使用 bluepill 来管理所有 discourse 的相关服务,省去了很多麻烦。
切换到 discourse 用户
安装并配置 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
到这里,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 |
@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,执行以下命令:
3 |
$ RAILS_ENV=production bundle exec rails c |
2.7 启用中文支持
目前,Discourse 已经可以支持中文界面,使用管理员账户登录后,点击右上角的管理员名称进入设置界面,然后再点击右上角的小扳手 Admin 进入系统管理界面,在第二项 Settings 中,把 default_locale 从默认的 en 更改为 zh_CN,然后返回论坛主界面,按 Ctrl+F5 刷新浏览器缓存,中文界面就出来了。
3 更新
鉴于 discourse 更新很快,建议每隔几天就执行一次更新。
用 discourse 用户登录 VPS,执行以下命令:
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 |
如果启动失败并出现重试,则按 Ctrl+C 中止,然后执行以下两条命令重启 bluepill 服务:
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