注意事项:
网络环境: 主机必须能够连接外网,国内的可能出现部分网络无法访问;
软件版本: nginx-1.5.0,rvm-1.20.10, ruby-2.0.0-p195, postgresql-9.1.9, passenger-4.0.2,版本可能会过期,执行时 请换成相应的版本;
操作系统: Ubuntu-12.04, 所有命令请使用root用户执行,如果不是root用户,请使用sudo su -切换;
服务器: Nginx 或者 Apache。
一. 基本环境安装
1.更新服务器到最新的系统
1
2
3
apt-get update
apt-get dist-upgrade
do-release-upgrade
较新的系统能够减少许多不必要的兼容性问题.
2.设置 /etc/bash.bashrc 和 /etc/profile
编辑 /etc/profile 文件, 在文件头加入:
1
export system_profile_loaded=1
并且找到:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if [ "$PS1" ]; then
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc has already set the default PS1.
# PS1='h:w$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
修改成:
1
2
3
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
[ -f /etc/bash.bashrc ] && . /etc/bash.bashrc
fi
编辑 /etc/bash.bashrc ,并在开头加入:
1
2
3
4
5
[ -n "${system_bashrc_running}" ] && return
system_bashrc_running=1
[ -z "${system_profile_loaded}" ] && source /etc/profile
unset system_bashrc_running
system_bashrc_runned=1
接着安装自动补全apt-get install -y bash-completion, 不过新版Ubuntu已安装了这个包.
二. 安装 Ruby 环境
RVM 是目前最好, 也是最常用的管理和编译 ruby 的工具, 使用 rvm, 可以减少以后ruby升级带来的麻烦, 更平滑的迁移到新版本.
1. 服务器安装RVM:
1
2
apt-get install -y curl git-core
curl -L get.rvm.io | bash -s stable
最后记得重新登入或者重启一下服务器, 使得 rvm 生效. 测试的话可以输入:
1
2
type rvm | head -1
rvm is a function
如果看到 rvm is a function, 就成功的安装好了.
2. 使用 RVM 安装和编译 Ruby
安装好 rvm 以后就可以使用 rvm 来对 ruby 进行编译, 推荐安装官方的 2.0.0+ 版本的 Ruby, 搭配Rails3.0+版本使用.编译 Ruby 前首先是需要安装 Ruby 所需要的类库, 所以我们输入:
1
rvm requirements
程序会列出 Ruby 所需要的类库, 找到下面的内容:
从RVM 1.20以后就不需要手动安装确实的库了, 它会自动帮我们都装好;
等待安装完成后就可以编译 Ruby 了.
使用RVM安装Ruby, 终端输入:
1
rvm install 2.0.0
就会自动的编译和安装 Ruby, 如果需要安装其他版本的 ruby 也可以通过命令:
1
rvm list known
查看目前可以使用的 Ruby 版本, 其中有[]的条目代表当前的默认版 本.
等待 Ruby 2.0.0 安装好以后, 可以通过 rvm list 命令来查看所有通过 rvm 安装的 ruby 版本。
3. 设置 Ruby 环境
首先, 我们通过 rvm 安装完以后, 需要将安装的Ruby设置为系统默认的Ruby环境, 在终端输入:
1
rvm use 2.0.0 --default
接着我们就可以通过 ruby -v 来验证是否成功设置.
另外, 服务器是生产环境 所以 rdoc 和 ri 基本是毫无用途的, 所以我们最好默认就不让 rake 去安装 rdoc 和 ri, 所以需要编辑 /usr/local/rvm/rubies/ruby-2.0.0-p195/etc/gemrc , (如果没有就手动建出来:
1
gem: -V --no-ri --no-rdoc
设置完以后, 每次使用 gem 命令就不会下载并安装 ri 和 rdoc 了.
至此 Ruby 就算基本安装完成了。
最后一步, 安装Rails: gem install rails
三. 安装数据库及其驱动
这里演示 PostgreSQL安装方法.
1. 安装 PostgreSQL Server
安装 PostgreSQL Server, 如果有多台机器作为服务器, 显然只需要一台机器安装数据库就可以了.
1
apt-get install postgresql
安装完成以后, 编辑 /etc/postgresql/9.2/main/postgresql.conf 找到:
1
#listen_addresses = 'localhost'
将其修改成:
1
listen_addresses = '*'
这样就可以通过远程来访问该数据库了, 当然还需要开启对应的权限才可以. 接着我们编辑 /etc/postgresql/9.2/main/pg_hba.conf 在文件的最后可以看到:
1
2
3
4
5
6
7
8
9
# Database administrative login by UNIX sockets
localallpostgrespeer
# TYPEDATABASEUSERCIDR-ADDRESSMETHOD
# "local" is for Unix domain socket connections only
localallallpeer
# IPv4 local connections:
hostallall127.0.0.1/32md5
# IPv6 local connections:
hostallall::1/128md5
这样的内容, 如果是开发或者测试的服务器, 可以修改成:
1
2
3
4
5
6
7
8
9
10
11
# Database administrative login by UNIX sockets
#localallpostgrespeer
# TYPEDATABASEUSERCIDR-ADDRESSMETHOD
# "local" is for Unix domain socket connections only
localallallmd5
# IPv4 local connections:
hostallall0.0.0.0/0md5
# IPv6 local connections:
hostallall::1/0md5
这样任何人在任何的地方都可以通过 ip 来访问数据库, 方便测试和调试, 但如果 是生产环境, 请务必明白每一行代码的效果后再修改。
由于默认 postgres 用户密码是随机的, 如果需要使用 postgres 通过远程访问的话, 按照我们上述修改的话, 由于不知道密码还无法登入. 所以我们还需要在命令行输入:
1
2
3
su - postgres -c psql postgres
ALTER USER postgres WITH PASSWORD 'postgres';
q
修改 postgres 用户的密码, 我这里修改成的密码是postgres , 实在是不安全, 所以请大家务必要修改成其他的密码.
最后输入 /etc/init.d/postgresql restart 重启 postgresql 服务器使配置文件生效.
2. 安装 PostgreSQL 客户端和 Ruby 驱动
1
2
apt-get install -y postgresql-client libpq-dev
gem install pg
这样就完成了客户端和驱动的安装.
四. 安装 Web 服务器
对于 Rails 或者说 Rack 服务器来说, 有很多的选择比如 unicorn, thin, passenger 等等.我们这里使用最常用的Apache + Passenger的方式, 就是因为其部署和维护最为方便, 至于性能等有了大量用户再考虑这个问题也不迟, 再说Apache + Passenger本身性能也不差,如果需要高并发和大量静态文件需要服务器处理,也可以选用Nginx + Passenger,性能上要好很多。
Apache 的安装与配置
1. 安装 Apache 服务器
在命令行输入:
1
apt-get install -y apache2-mpm-prefork apache2-prefork-dev
安装完成以后, 用浏览器访问服务器的80端口确保可以看到It works! . 再运行:
1
2
3
a2dissite default
/etc/init.d/apache2 restart
rm /var/www/index.html
关闭刚刚那个无用的默认的网站。
2. 设置 apache 用户
apache 默认使用的是 www-data 用户, 而 Rails 程序也是使用该用户发布, 所以要修改 www-data 的相关配置信息, 允许这个 用户安装 Gem, 也就是加入 rvm 组:
1
2
usermod --shell=/bin/bash -a -G rvm www-data
chown -R www-data:www-data /var/www
完成以后 Apache 基本也就安装好了。
3. 安装 Passenger
在终端中输入:
1
gem install passenger
会自动下载并安装 passenger, 安装完 passenger 后, 输入:
1
passenger-install-apache2-module
然后一路回车, passenger 会自动检测缺少的包, 我们这里提示缺少:
1
* Curl development headers with SSL support... not found
所以我们按 ctrl + c 暂停目前的安装, 并输入:
1
apt-get install libcurl4-openssl-dev
安装 curl 的 ssl dev包, 接着重新输入 passenger-install-apache2-module 开始编译 Passenger 的 Apache 模块 等编译完成以后, 会看到这样的提示:
1
2
3
4
5
Please edit your Apache configuration file, and add these lines:
LoadModule passenger_module /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2
PassengerRuby /usr/local/rvm/wrappers/ruby-2.0.0-p195/ruby
于是我们就按照他的提示编辑 /etc/apache2/mods-available/passenger.load 输入:
1
LoadModule passenger_module /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2/ext/apache2/mod_passenger.so
再编辑 /etc/apache2/mods-available/passenger.conf 输入:
1
2
PassengerRoot /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2
PassengerRuby /usr/local/rvm/wrappers/ruby-2.0.0-p195/ruby
接下来让 apache 启用该模块, 输入:
1
2
a2enmod passenger
/etc/init.d/apache2 restart
至于 Passenger 的性能调优, 清参考 passenger 的官方文档.
Nginx 的安装与配置
注:这里因为需要Nginx集成Passenger Module,并没有采用apt-get install的安装方式,而是Passenger提供的方法手动编译;
另:Nginx 在静态文件读取和处理高并发任务上比 Apache 要快多了,有这方面需求的童鞋可以考虑,再者就是 Nginx 的配置比 Apache 要麻烦的多,每次模块的维护和升级都要重新编译。
1. 安装 passenger
只续简单输入
1
gem install passenger
等待自动下载并安装完成.
2. 下载和编译 nginx
首先需要下载一些 Nginx 和 Passenger 的编译依赖包
1
apt-get install -y libpcre++-dev libcurl4-openssl-dev
然后输入如下命令
1
2
3
4
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.5.0.tar.gz
tar xvf nginx-1.5.0.tar.gz
cd nginx-1.5.0
接着通过 passenger 的命令编译安装 nginx:
1
2
3
4
5
6
7
8
9
passenger-install-nginx-module
--auto
--nginx-source-dir=$PWD
--prefix=/usr/local/nginx
--extra-configure-flags="
--conf-path=/etc/nginx/nginx.conf
--pid-path=/var/run/nginx.pid
--lock-path=/var/lock/nginx.lock
--with-ipv6 --with-http_mp4_module"
等待他安装完成. 接着还需要安装对应的 manpage
1
2
mkdir -p /usr/local/share/man/man8/
install objs/nginx.8 /usr/local/share/man/man8/
接着需要将其连接到系统的配置和日志目录下, 输入
1
2
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
ln -s /usr/local/nginx/logs /var/log/nginx
3. 配置 nginx
一般来说默认编译出的配置并不适合生产环境的配置, 比较倾向于 ubuntu 自带的区分 sites-enabled 和 conf.d 的样子, 所以这里需要. 输入
1
2
3
4
5
6
mkdir -p /etc/nginx/conf.d
mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled
usermod --shell=/bin/bash -a -G rvm www-data
mkdir -p /var/www
chown -R www-data:www-data /var/www
稍微解释下 conf.d 放扩展的配置文件, sites-available 放服务器配置, 启用服务后需要将配置连接到 sites-enabled 下, 接着需要修改 /etc/nginx/nginx.conf 成如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include mime.types;
default_type application/octet-stream;
# Logging Settings
access_log logs/access.log;
error_log logs/error.log;
# Gzip Settings
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Virtual Host Configs
include conf.d/*.conf;
include sites-enabled/*;
}
4. 配置 passenger
虽然编译了 passenger 的模块, nginx 还需要配置 passenger 的配置.
配置前首先需要获取 passenger 的安装目录, 输入
1
ruby -e 'gem "passenger"; puts Gem.loaded_specs["passenger"].full_gem_path'
可以看到返回的 /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2 就是 passenger 的安装目录, 接着编辑 /etc/nginx/conf.d/passenger.conf文 件, 按之前的结果输入:
1
2
passenger_root /usr/local/rvm/gems/ruby-2.0.0-p195/gems/passenger-4.0.2;
passenger_ruby /usr/local/rvm/wrappers/ruby-2.0.0-p195/ruby;
保存退出后, 再在 /etc/nginx/sites-available 下新建一个叫 default 的文件, 内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/default/htdocs;
autoindex on;
index index.html index.htm;
access_log logs/default-access.log;
error_log logs/default-error.log;
passenger_enabled on; # enable passenger
}
完成后输入
1
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
启用配置, 接着输入
1
2
3
mkdir -p /var/www/default/htdocs
echo world > /var/www/default/htdocs/hello.txt
chown -R www-data:www-data /var/www
新建测试文件后, 可以通过命令 nginx 启动 nginx, 然后命令行输入 curl http://localhost/hello.txt 就可以看到其返回的结果是world了, 然后通过命令 nginx -s stop 停止 nginx 服务器.
5. 配置 Nginx 随系统自动启动
之前命令虽然已经可以启动 nginx 了, 但不会随系统一起启动. 为了让他随着系统启动我们还需要编辑 /etc/init.d/nginx 文件, 输入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/bin/sh
### BEGIN INIT INFO
# Provides:nginx
# Required-Start:$local_fs $remote_fs $network $syslog
# Required-Stop:$local_fs $remote_fs $network $syslog
# Default-Start:2 3 4 5
# Default-Stop:0 1 6
# Short-Description: starts the nginx web server
# Description:starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/sbin/nginx
NAME=nginx
DESC=nginx
# Include nginx defaults if available
if [ -f /etc/default/nginx ]; then
. /etc/default/nginx
fi
test -x $DAEMON || exit 0
set -e
. /lib/lsb/init-functions
test_nginx_config() {
if $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1; then
return 0
else
$DAEMON -t $DAEMON_OPTS
return $?
fi
}
case "$1" in
start)
echo -n "Starting $DESC: "
test_nginx_config
# Check if the ULIMIT is set in /etc/default/nginx
if [ -n "$ULIMIT" ]; then
# Set the ulimits
ulimit $ULIMIT
fi
start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid
--exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid
--exec $DAEMON || true
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile
/var/run/$NAME.pid --exec $DAEMON || true
sleep 1
test_nginx_config
start-stop-daemon --start --quiet --pidfile
/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
test_nginx_config
start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid
--exec $DAEMON || true
echo "$NAME."
;;
configtest|testconfig)
echo -n "Testing $DESC configuration: "
if test_nginx_config; then
echo "$NAME."
else
exit $?
fi
;;
status)
status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
;;
*)
echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest}" >&2
exit 1
;;
esac
exit 0
完成后还需要附上执行权限
1
chmod +x /etc/init.d/nginx
都完成后就可以通过命令 service nginx start|stop|status 来启动,停止和查看 nginx 了. 之后还需要通过命令
1
update-rc.d nginx defaults
设置 nginx 可以随着系统自动启动.
6. 自动清理日志
如果是 apt 安装的 nginx 系统已经自动帮我们把日志清理给配置好了. 不过由于我们这里必须手工编译, 所以还需要配置日志的定期归档和清理. 这里我们编辑 /etc/logrotate.d/nginx 输入:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then
run-parts /etc/logrotate.d/httpd-prerotate;
fi;
endscript
postrotate
[ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
endscript
}
五. 后记
至此,Ruby on Rails 在Ubuntu上的环境搭建就已经完成了,之后就可以在服务器上发布项目了,Rails发布项目多使用自动化部署,需要安装 Capistrano,这里不再详述。
参考文档
Rails 部署
Phusion Passenger users guide, Apache version
Phusion Passenger users guide, Nginx version
RVM官方文档