MENU

Rails 部署总结

Cover

学 Ruby 和 Rails 有一段时间了,后面准备也准备把站点换了。不过开始开发之前,我先把 Rails 部署的坑先踩了。之所以部署先行是因为之前 Django 部署把我坑惨了,导致之前写的 Django 代码还是 Github 静静地躺着。 忽悠妹子给我在腾讯云买了服务器后,马不停蹄的就开始了填坑之旅。这里我选择的系统是 Ubuntu 16.04 ,所以下面的命令以此为准。

准备工作

在开始部署之前有些准备工作需要去完成,这些准备工作其实在每次开始新建服务器后你都要去做。

为了安全起见我一般习惯不使用密码登录服务器而是使用 SSH 的方式。所以第一步就是配置好服务器 SSH 证书并下载私钥并将其发到 .ssh 文件夹下,并修改私钥权限以防权限太大而无法登录。

$ chmod 400 ~.ssh/PathOfKey

接着我们 SSH 登录到服务器:

$ ssh -i "~.ssh/PathOfKey" ubuntu@119.xxx.xxx.xxx

完成登录后首先就是系统更新了:

$ sudo apt-get update
$ sudo apt-get upgrade

现在开发过程中 Git 服务几乎是必不可少的,为了更好的使用它需要对服务器 .ssh 文件夹进行设置:

$ sudo chown username: /home/username/.ssh 
$ sudo chown username: /home/username/.ssh/* 
$ sudo chmod 700 /home/username/.ssh  
$ sudo chmod 600 /home/username.ssh/

命令执行完成后,你就可以像往常一样配置 Github、Coding 这样的 Git 服务了。

软件环境配置

首先需要安装的就是 Ruby、Rails ,过程并没有太多的难度,具体说明可以参考 RubyChina。下面我仅仅列出使用到的命令:

安装 Ruby 版本控制器 RVM:

$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
$ \curl -sSL https://get.rvm.io | bash -s stable
$ source ~/.bashrc
$ source ~/.bash_profile

切换软件安装源:

$ echo "ruby_url=https://cache.ruby-china.org/pub/ruby" > ~/.rvm/user/db

安装最新的 Ruby、Rails

$ rvm install 2.4.0
$ rvm use 2.4.0 --default
$ gem install rails

接下来需要安装的就是 MySQL、Nginx ,过程常规没有什么值得说的。

$ sudo apt-get install nginx
$ sudo apt-get install mysql-server mysql-client libmysqlclient-dev
$ sudo mysql_secure_installation
$ sudo apt-get install nodejs

当然数据库完全依据个人偏好,你也可以选择 PostgreSQL。Nginx 安装好之后,你可以通过在浏览器中直接输入 IP 检测,默认会有一个欢迎页。

部署的过程

通过 Git 获取其他方式将代码拉取到服务器之后,接下来就是配置数据库文件并创建数据库了。因为不同系统和数据库配置存在差异,所以第一次配置的时候你可以通过在服务器上新建测试工程来拷贝其中的配置。

$ rails new testapp -d mysql

然后将配置文件 database.yml 中的 socket 字段配置信息拷贝到自己的代码中。另外需要通过配置生产环境的 secret_key_base,命令如下:

$  RAILS_ENV=production rake secret

然后将生成的随机字符串拷贝到 config/secrets.yml 中,当然你也可以将其作为 Shell 的环境变量。

创建数据库:


$  RAILS_ENV=production rails db:create
$  rails db:create

配置好数据库后就是拉起 Rails 了,但是此处有坑。

$ rails s 

在 Rails 5 中第一条拉起命令会出错,错误提示如:

initialize': Cannot assign requested address - bind(2) for "IP"

这是因为 Rails 5 已经是 IP V6 Only,而腾讯云默认是不开启的,所有需要我们手动修改设置。

$ cd /etc
$ sudo vim sysctl.conf

如果配置文件中存在下列设置将其注释掉:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

设置好之后重启服务让设置生效。

puma 设置

接下来我们需要将 puma 配置为生产环境,打开配置文件:

$ vim config/puma.rb

将其修改为:

# Change to match your CPU core count
workers 2

# Min and Max threads per worker
threads 1, 6

app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"

# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

# Set up socket location
bind "unix://#{shared_dir}/sockets/puma.sock"

# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true

# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app

on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end

把workers的数量改为你的服务器的CPU核心的数量。上面给puma配置你应用的位置,Puma的socket、logs、PIDs的位置。可以自由修改这个文件,加入其他你需要的选项。

现在创建配置文件里引用到的目录:

$ mkdir -p shared/pids shared/sockets shared/log

接下来我们创建一个Upstart init script ,这样就能简单的开始和停止Puma,并确保在服务器启动时同时启动。

从 Puma GitHub库下载Jungle Upstart tool到你的home目录:

$ cd ~
$ wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma-manager.conf
$ wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/upstart/puma.conf

修改 puma.conf 文件指向服务用户和用户组,腾讯云默认都是 ubuntu


$ vim puma.conf

找到指定 setuid 和 setuid 的两行,然后用你的开发用户和组的名字替换。

setuid deploy
setgid deploy

拷贝 scripts 到 Upstart servives 目录:

$ sudo cp puma.conf puma-manager.conf /etc/init

新建 puma 的应用管理文件:


$ sudo vim /etc/puma.conf

文件里的每一行就是你希望puma-manager管理的一个应用的路径。现在加入你的应用的路径. 比如:

/home/ubuntu/apps/testapp

但是这里还有一个问题需要解决,在 Ubuntu 15.04 + 的系统中上面的管理脚本不会起重要所以我们还要进一步处理。

$ sudo apt-get install upstart-sysv
$ sudo update-initramfs -u
$ reboot

重启完成后服务就会生效,此时我们通过下列命令来拉起 Rails。

$ sudo restart puma-manager

然后你就可以在浏览器中通过 IP:3000 访问到程序了,接下来就是设置 Nginx 了。

Nginx 配置

下面我们设置 Nginx 进行反代理 puma,打开默认配置文件:

$ sudo vim /etc/nginx/sites-available/default

用下面的代码块替换文件内容。确定使用相应的用户名和应用名字替换 ubuntu 和应用路径部分

upstream app {
    # Path to Puma SOCK file, as defined previously
    server unix:/home/ubuntu/apps/testapp/shared/sockets/puma.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    root /home/ubuntu/apps/testapp/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

这样HTTP请求通过Unix socket 抵达Puma应用服务器。随意修改配置到你感到满意为止。

重启Nginx使修改生效:


$ sudo service nginx restart

现在你的应用的生产环境已经可以通过你的服务器的公共IP地址或者FQDN访问了。要访问我们之前创建的Tasks controller,在web浏览器里面访问:

http://server_public_IP

你会看到和第一次测试时同样的页面,不过现在被架设在了nginx和Puma上。

总结

总的来说部署过程还算顺畅没有什么太大问题,后面再试试持续集成。

标签: Rails, 部署
添加新评论

已有 1 条评论
  1. 厉害厉害,我想知道你在部署Django的时候遇到了什么样的坑,能否分享一下。这是我部署Django博客后写的教程。不知有没有你遇到的问题