部署 在 Aliyun 上快速部署 Ruby on Rails

modacker · 2014年02月28日 · 最后由 nicetyler 回复于 2017年06月07日 · 21154 次阅读

在 Aliyun 上快速部署 Ruby on Rails


莫克

2014 年 2 月 27 日于上海

写在前面

欢迎阅读《在 Aliyun 上部署 Ruby on Rails》,因为近日正好在 Aliyun©进行 RoR 的部署,之前没有任何的经验,通过搜索引擎也没搜索到比较完整的部署文档。写此文的目的只是做个笔记,下次部署的时候可以更快一点。

此文大量参考了 [Ruby China][rubychina-link] 的 [《在 Ubuntu 12.04 Server 上安装部署 Ruby on Rails 应用》][railsonubuntu-link]。

关于我在阅读《在 Ubuntu 12.04 Server 上安装部署 Ruby on Rails 应用》并实践的时候,估计是鄙人学艺不精,总是卡在一些很奇怪的小问题上。这里也算是对《在 Ubuntu…应用》一文的在一些微不足道的补充。

首先指定一下系统版本,如果是不同的版本的肯定会有一些细节的差别。

  • 服务器版本Ubuntu 12.04 64 位 安全加固版
  • 本地计算机使用的是OS X 10.9.1 (13B42)

工具

一个好的工具能让我们事半功倍,在这里列举我使用到的工具,并且我做了一些优化配置,当然你完全可以跳过此部直接阅读实际的部署过程。

  • iTerm2,[官方网站][iterm-link]

就这么一个工具了。

iTerm2 是一个替代 OS X 系统自带终端的一个软件,其实它的作用不仅如此,更多的发散应用可以通过搜索引擎自行研究,我这里只会对 iTerm2 做一些关于快速 SSH 连接服务器的设置。

依赖 iTerm2 的 Profiles,我们可以快速 ssh 到任何一个站点。 配置 Profiles,iTerm2>>>Preferences>>>Profiles。

快捷键COMMAND + ,呼出配置界面,选择 Profiles 选项卡。

通过左下角的+添加一个新的 Profiles,需要修改两个参数,一个是Name,一个是Command

# 你可以设置任何你喜欢并且容易分辨的名字
Name: SSH Server name

# [ip address]设置成服务器的ip地址
Command: ssh root@[ip address]

如果有需要可以通过-p [Number]指定端口号

Command: ssh -p [Number] root@[ip address]

然后关闭配置窗口,通过快捷键COMMAND + O来呼出 iTerm2 的 Profiles,选择刚刚配置好的 Profile,在最下面有一排按钮,本别是New Tabs in New WindowSplit HorizontallySplit VerticallyNew TabNew Window,大家可以自行测试一下,直接回车的话会在默认的New Tab中打开新的窗口。

建议勾选Close this window after opening a profile.,毕竟这个窗口有点大,我的屏幕又比较小,看着很不顺眼。

配置 uBuntu

我们第一次通过 iTerm 连接上服务器的时候会要求我们输入 root 的密码,为了安全,建议更改登陆配置使用公钥 (yuè) 登陆。

使用过 github 的朋友大部分都应该配置过 ssh-keygen,配置很简单,配置好之后会更加方便也更加安全。关于原理之类的我就不赘述了,直接上命令。

首先我们打开 iTerm2,输入以下命令:

$ cd ~/.ssh
$ ssh-keygen -t rsa -C "[[email protected]]"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]
$ ssh-add id_rsa
Enter passphrase (empty for no passphrase): [Type a passphrase]
Enter same passphrase again: [Type passphrase again]
Your identification has been saved in /Users/you/.ssh/id_rsa.
Your public key has been saved in /Users/you/.ssh/id_rsa.pub.
The key fingerprint is:
01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db [email protected]
$ pbcopy < ~/.ssh/id_rsa.pub

如果遇到-bash: cd: ~/.ssh: No such file or directory的错误,新建一个.ssh 的文件夹即可。

# mkdir ~/.ssh

这时候我们切换到 ssh 的 Profile,输入以下的命令:

# mkdir ~/.ssh
# vi ~/.ssh/authorized_keys

通过 vi 把刚刚复制到剪贴板的内容粘贴到 authorized_keys 里,然后保存退出。

# vi /etc/ssh/sshd_config

找到

#AuthorizedKeysFile      %h/.ssh/authorized_keys

#AuthorizedKeysFile %h/.ssh/authorized_keys前面的注释删掉,修改成

AuthorizedKeysFile      %h/.ssh/authorized_keys

按照常规应该是重启 sshd,service sshd restart结果这个命令报错没有 sshd 这个服务,懒得去 debug 了,直接reboot好了。

# reboot

有一点需要注意的是我们之前用的是 root 登陆,所以终端显示是#不是注释。 完成这个简单的小配置之后,我们之后打开 iTerm2 的 Profile 的时候就会直接登陆不再需要输入密码。然后更多的安全设置可以自行去深入,比如:

  • 修改一个 128 位的 root 密码
  • 取消密码登录
  • 禁用 root
  • ssh 的 ip 绑定
  • 以及更多

在这之前我们需要新建一个名为 wwwroot 的用户,并且之后的所有操作我们都会切换到这个用户进行。

# adduser wwwroot
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for wwwroot
Enter the new value, or press ENTER for the default
      Full Name []:
      Room Number []:
      Work Phone []:
      Home Phone []:
      Other []:

这里一路回车就好了。

# vi /etc/sudoers

找到root ALL=(ALL:ALL) ALL这一行,在后面添加:

wwwroot ALL=(ALL:ALL) ALL

/etc/sudoers默认是只读权限,使用vi编辑好之后用wq!命令来强制修改即可,不需要去改权限。

然后,我们需要切换到这个用户配置一下 ssh-keygen:

# su - wwwroot
$ mkdir ~/.ssh
$ vi ~/.ssh/authorized_keys

最后,再配置一下 iTerm2 的 Profiles,具体的过程请参见本文一开始的工具


阿里云镜像

中国有个东西叫The Great Wall,在互联网里也有一个和 The Great Wall 一样伟大的东西。因为这种原因我们需要第一时间去修改一下。推荐使用阿里云自己提供的 [镜像][aliyunmirrors-link]。

说句题外话,其实经过我的测试其实默认的源的速度并不会特别的慢。

root@aliyun:~# ping cn.archive.ubuntu.com
PING mirrors.sohu.com (119.188.36.70) 56(84) bytes of data.
64 bytes from 119.188.36.70: icmp_req=1 ttl=55 time=20.2 ms
64 bytes from 119.188.36.70: icmp_req=2 ttl=55 time=20.2 ms
64 bytes from 119.188.36.70: icmp_req=3 ttl=55 time=20.2 ms
64 bytes from 119.188.36.70: icmp_req=4 ttl=55 time=20.2 ms

但是,可以提高 20 倍的速率还是不错的吧!

root@Copydays:~# ping mirrors.aliyun.com
PING mirrors.aliyun.com (112.124.140.210) 56(84) bytes of data.
64 bytes from 112.124.140.210: icmp_req=1 ttl=60 time=1.50 ms
64 bytes from 112.124.140.210: icmp_req=2 ttl=60 time=1.56 ms
64 bytes from 112.124.140.210: icmp_req=3 ttl=60 time=1.52 ms
64 bytes from 112.124.140.210: icmp_req=4 ttl=60 time=1.54 ms

编辑/etc/apt/sources.list 文件,在文件最前面添加以下条目,操作前请做好相应备份。

deb http://mirrors.aliyun.com/ubuntu/ precise main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-backports main restricted universe multiverse

然后保存退出,更新一下源:

$ sudo apt-get update

查看更多阿里云镜像关于 ubuntu 的 [支持][aliyunmirrorsubuntu-link]


部署环境

重新打开 iTerm 使用 wwwroot 的 ssh 连接,以后我们的操作都会在这个 ssh 里完成。

用 RVM 安装 Ruby

要安装 RVM,在终端中输入下面的命令:

$ \curl -L https://get.rvm.io | bash -s stable
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >>~/.bashrc
$ source ~/.bashrc
$ rvm -v

国内服务器最好把 RVM 的源替换成 Taobao 源:

$ sed -i -e 's/ftp\.ruby-lang\.org\/pub\/ruby/ruby\.taobao\.org\/mirrors\/ruby/g' ~/.rvm/config/db

为了能正常工作,RMV 必须安装一些依赖。你可以让 RVM 自动安装它们:

$ rvm requirements

Ruby-China 的指导里有关于 Readline 和 OpenSSL 的 rvm 的安装,虽然感觉可以不装,但是装一下也无妨。

$ rvm pkg install readline
$ rvm pkg install openssl

RVM 并不能管理系统自带的 Ruby,如果想返回系统管理的 Ruby,可以执行rvm reset,但是这个 ubuntu 没有自带 Ruby,类似一个纯净优化版。

用 RVM 安装 Ruby:

$ rvm install 2.0.0
$ rvm use 2.0.0 --default

如果速度比较慢,可以重新替换一次 RVM 的源,10Mb 的文件大约 5 秒就能下好。

等待编译完成,默认已经顺带把 Rubygems 也装好了。安装完成之后我们来校验一下成果,顺便把 Rubygems 的源也修改成阿里云的源:

$ ruby -v
ruby 2.0.0p451 (2014-02-24 revision 45167) [x86_64-linux]
$ gem -v
2.2.2
$ gem source -r https://rubygems.org/
$ gem source -a http://mirrors.aliyun.com/rubygems/
$ gem sources -l
*** CURRENT SOURCES ***

http://mirrors.aliyun.com/rubygems/

当然你也可以使用 Taobao 的源:

$ gem sources -a http://ruby.taobao.org/
*** CURRENT SOURCES ***

http://ruby.taobao.org
  • [阿里云 Rubygems][aliyunmirrorsrubygems-link]

  • [Taobao Rubygems][taobaorubygems-link]

安装 Rails:

$ gem install rails
$ rails -v
Rails 4.0.3

安装数据库

安装 MySQL:

$ sudo apt-get install mysql-server

或者 PostgreSQL:

$ sudo apt-get install postgresql postgresql-client libpq-dev

你还可以请参考 [阿里云的 OTS][aliyunots-link]。


Git Server

RoR 比较流行的是使用 git,我们来配置一下 Git Server,首先我们需要新建一个名为 git 的用户并且为它添加公钥。

$ sudo adduser git
$ sudo vi /home/git/.ssh/authorized_keys

我这里假设你的项目名称是 project 和准备把 git 仓库的目录设定为/opt/git,如果你没有一个/opt/git 目录,需要切换到 root 新建并且把这个目录的所有者改为 git:

$ su - root
# cd /opt
# mkdir git
# chown git git
# ls -all
# total 4
# drwxr-xr-x 3 git root 4096 Feb 27 13:50 git
$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init

如果你之前已经有一个 Rails 项目,那么可以跳过此步骤。

在本地计算机上,新建一个 Rails 项目,并且把它纳入 git 版本管理中:

$ rails new project --skip-bundle
$ cd project
$ git init
$ git add .
$ git commit -m 'initial commit'

我们需要添加 git remote 连接服务器,并且把这个项目 push 到服务器上去。

$ git remote add origin git@[ipaddress]:/opt/git/project.git
$ git push origin master
Counting objects: 59, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (48/48), done.
Writing objects: 100% (59/59), 13.41 KiB | 0 bytes/s, done.
Total 59 (delta 2), reused 0 (delta 0)
To git@[ipaddress]:/opt/git/project.git
 * [new branch]      master -> master

如果你的系统没有报错的话,这个时候我们已经完成了 Git Server 的部署。

部署站点

我之前一直没成功,后来仔细阅读了 err logs 后发现是 swap 不足的原因,希望大家能够一次成功!如果你遇到了其他的问题欢迎一起探讨解决。

在这之前,我们还是先看下 swap 的大小吧:

$ free -m
      total       used       free     shared    buffers     cached
Mem:           490        405         84          0         12        311
-/+ buffers/cache:         80        409
Swap:            0          0          0

可能是我选择的是低配的原因,根本就没有 Swap,有没有其他使用阿里云的朋友可以来解惑下高配的版本的 Swap 有多少?现在我要来解决下我自己的问题了。

$ sudo mkdir /swap
$ cd /swap
$ sudo dd if=/dev/zero of=swapfile bs=1024 count=500000
$ sudo mkswap -f swapfile
$ sudo swapon swapfile

接下来我们要把项目的源代码弄到/home/wwwroot 下面来:

$ cd ~
$ git clone /opt/git/project.git
$ ls
project

修改你的数据库配置,创建数据库,合并等,这里我就不赘述了,最后你的项目能用rails s跑起来。

Passenger for Nginx

因为我这里使用 passenger for Nginx,Passenger 需要重新编译 Nginx,如果之前有 Nginx 需要卸载掉sudo apt-get remove nginx-common nginx-full nginx。然后安装 Passenger:

$ gem install passenger
$ passenger -v
Phusion Passenger version 4.0.37

进入 rvmsudo 使用 Passenger 安装 Nginx:

$ rvmsudo passenger-install-nginx-module

如果无法运行我们可以尝试下面这个方法:

$ export ORIG_PATH="$PATH"
$ rvmsudo -E /bin/bash
# xport PATH="$ORIG_PATH"
# /home/wwwroot/.rvm/gems/ruby-2.0.0-p451/wrappers/ruby /home/wwwroot/.rvm/gems/ruby-2.0.0-p451/gems/passenger-4.0.37/bin/passenger-install-nginx-module

按照默认的选项一路回车下去,这里输入1继续回车。

Automatically download and install Nginx?

Nginx doesn't support loadable modules such as some other web servers do, so in order to install Nginx with Passenger support, it must be recompiled.

Do you want this installer to download, compile and install Nginx for you?

  1. Yes: download, compile and install Nginx for me. (recommended) The easiest way to get started. A stock Nginx 1.4.4 with Passenger support, but with no other additional third party modules, will be installed for you to a directory of your choice.

  2. No: I want to customize my Nginx installation. (for advanced users) Choose this if you want to compile Nginx with more third party modules besides Passenger, or if you need to pass additional options to Nginx's 'configure' script. This installer will 1) ask you for the location of the Nginx source code, 2) run the 'configure' script according to your instructions, and 3) run 'make install'.

Whichever you choose, if you already have an existing Nginx configuration file, then it will be preserved.

Enter your choice (1 or 2) or press Ctrl-C to abort:1[ENTER]

耐心等待编译。

最后看到

Nginx with Passenger support was successfully installed.

恭喜你安装成功,若是出现问题可以参考 [Passenger 官方文档][passengerinstall-link]。

如果你使用的是第二种 rvmsudo 的方法,最后别忘了exit退出 rvmsudo 模式。

Nginx init script

接下来安装 Nginx 的启动脚本,以及配置开机自动启动:

$ cd ~/
$ git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
$ sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
$ sudo chmod +x /etc/init.d/nginx
$ sudo update-rc.d nginx defaults

配置 Nginx 和站点

以下内容几乎照抄《在 Ubuntu…应用》一文。

打开 Nginx 的 nginx.conf

$ sudo vim /opt/nginx/conf/nginx.conf

PS: 如果你不是 Passenger 安装的 Nginx,这个配置文件还有可能在/usr/local/nginx/或/etc/nginx 下面

请参考下面的例子修改:

user wwwroot; # 修改成你的系统帐号名,不然项目目录/home/wwwroot这里没有权限
worker_processes 8; # 修改成和你 CPU 核数一样
pid /var/run/nginx.pid;

http {
  include       mime.types;
  default_type  application/octet-stream;

  client_max_body_size 50m;

  sendfile        on;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  gzip on;
  gzip_disable "msie6";

  ## ------------ 重点修改内容 --------

  server {    
    # 此处用于防止其他的域名绑定到你的网站上面
    listen 80 default;
    return 403;
  }

  server {
    listen       80;
    server_name  you.host.name; # 请替换成你网站的域名
    rails_env    production;
    root         /home/wwwroot/project/public;
    passenger_enabled on;

    location ~ ^(/assets) {
      access_log        off;
      # 设置 assets 下面的浏览器缓存时间为最大值(由于 Rails Assets Pipline 的文件名是根据文件修改产生的 MD5 digest 文件名,所以此处可以放心开启)
      expires           max; 
    }
  }

  ## ---------------------------------
}

重启 Nginx 查看你的网站。

$ sudo /etc/init.d/nginx start

最后吐槽下 ruby-china 的 markdown 语法和我用的不太一样……

[rubychina-link]:http://ruby-china.org/ "Ruby China" [railsonubuntu-link]:http://ruby-china.org/wiki/install-rails-on-ubuntu-12-04-server [iterm-link]:http://www.iterm2.com/ [aliyunmirrors-link]:http://mirrors.aliyun.com/ [aliyunmirrorsubuntu-link]:http://mirrors.aliyun.com/help/ubuntu [aliyunmirrorsrubygems-link]:http://mirrors.aliyun.com/help/rubygems [taobaorubygems-link]:http://ruby.taobao.org/ [aliyunots-link]:http://www.aliyun.com/product/ots/ [passengerinstall-link]:http://www.modrails.com/install.html

ruby-china 的 markdown 用的是 GFM

诶哟好长....好用心的样子....

楼主辛苦,支持楼主:thumbsup: @modacker

点击楼主的链接,看到这样一句话:

若使用阿里云服务器,将源的域名从 mirrors.aliyun.com 改为 mirrors.aliyuncs.com,不占用公网流量。

#4 楼 @sefier 这个是针对使用阿里云服务器的设定,其实这点流量在小型应用上来说的话并不是特别多。

@Magic @ruohanc 谢谢

若你的机器多了 是不是可以考虑使用其他的配置工具啊 配置一台得多费时间啊

#1 楼 @miclle 恩,对于 markdown 我也是新人,电脑上有个 Mou,支持一些快捷键,用起来很爽,然后把东西一贴上来,发现很多格式不对。

#6 楼 @kewin 脚本语言就是为此而生的。当然我现在就一台机器,还没考虑去脚本,不过后期如果时间允许我会尝试的

好复杂。。

#7 楼 @modacker Mou 里面也可以使用 GFM. Preferences > CSS > Use CSS: GitHub/GitHub2

#11 楼 @miclle 谢谢提醒,有时间研究一下!

#6 楼 @kewin 如果多台机器都在阿里云上的话,可以考虑配置好一台,建个硬盘快照,别的机器都用这个快照恢复。不过必须在挂载数据盘前建快照。

#13 楼 @birdfrank 我刚刚正在阿里云研究快照这个玩意,刚刚看到快照完成之后还可以通过快照自定义镜像,这个功能很不错。

#14 楼 @modacker 对,以后就可以通过这个镜像去装别的服务器。

#10 楼 @modacker thanks ,heroku slowly!!

#16 楼 @iamsmallid 那么你可以 cdn 加速啊,哈哈。计算机其实就是为懒人服务的,总会有足够轻松的部署方案的

#15 楼 @birdfrank 看来你也是阿里的用户啊

#19 楼 @modacker 是,不过我也只是刚开始用。

Ruby-China 的指导里有关于 Readline 和 OpenSSL 的 rvm 的安装,虽然感觉可以不装,但是装一下也无妨。

openssl 是要装的,不然会出问题

修改你的数据库配置,创建数据库,合并等,这里我就不赘述了 .... 😢 我就是想知道这个怎么做的啊....

楼主,可否加个好友,求教了。13761259714

厉害了我的哥,我现在也在学好难啊,上线一个网站这么难,主要是没有什么好的教程,要疯了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号