-
Notifications
You must be signed in to change notification settings - Fork 91
how to deploy rails to ubuntu1404 with rails template
rails-template
是一套全栈式的解决方案, 基于它的布署是非常快速, 安全的.
Ubuntu14.04 / 16.04 LTS 是目前最稳定且常见的发布版本, 推荐使用.
下文基于 rails-template
来说明它的最佳布署实践.
#
开头代表该命令使用 root 权限执行.
$
开头代表该命令使用 ruby 用户权限执行.从 root 切换至 ruby 用户, 使用
su - ruby
,-
的作用可以确保 ruby 用户的环境变量的正确加载.如果命令中有
xxx
, 请自行替换为自己的项目名称.
本地执行
(本地命令)
$ ssh root@yourserverip
输入密码确保登录成功.
更新源, 并安装必需的用户.
# apt-get update
# apt-get install -y git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev imagemagick libmagickwand-dev
# adduser ruby ( 不要使用 useradd )
随便输入一个复杂密码即可, 因为后续我们只使用 ruby 用户的 sshkey 登录方式.
# su - ruby
第一步, 安装 rbenv ( https://github.com/rbenv/rbenv )
以下是关键安装步骤
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ git clone https://github.com/andorchen/rbenv-china-mirror.git ~/.rbenv/plugins/rbenv-china-mirror( 可选, 将下载切换至 ruby.taobao.org 速度会超快 )
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ echo 'source ~/.bashrc' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv install 2.5.3
$ rbenv global 2.5.3
$ rbenv rehash
第二步,安装 rails 依赖 gem
和 bundler
$ gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/ ( 可选 )
$ echo "gem: --no-document" > ~/.gemrc ( 可选 )
$ gem update --system
$ gem install bundler
$ bundle config mirror.https://rubygems.org https://gems.ruby-china.com ( 可选 )
准备发布目录
# mkdir -p /data/www/
# chown ruby:ruby /data/www
准备无密码登录
$ ssh-keygen
$ vi ~/.ssh/authorized_keys ( 然后复制本机的 id_rsa.pub 内容写入. )
新打开本地终端, 测试是否ok:
(本地命令)
$ ssh ruby@yourserverip
无须密码即可登录, 说明已经配置成功.
准备github clone 权限
$ cat ~/.ssh/id_rsa.pub
将输出复制到 github 仓库的 deploy key 里, 保证发布环境主机能 clone 仓库.
测试方法:
$ git clone xx.git
确保能够克隆代码
准备 postgresql
# apt-get install -y postgresql libpq-dev
postgresql user 设置
( 最简单的一种方式是 将 /etc/postgresql/9.3/main/pg_hba.conf
里面的 md5 与 peer 统一改为 trust )
然后重启 postgresql
# service postgresql restart
安装 redis
# apt-get install redis-server
安装 nodejs ( 用来编译 assets 使用 )
# curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
# apt-get install -y nodejs
安装 yarn ( 用来编译 webpacker 使用 )
# curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
# echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
# apt-get update
# apt-get install -y yarn
$ yarn config set registry https://registry.npm.taobao.org ( 可选, 切换到 ruby 用户目录执行 )
在本地的主机执行: $ mina setup
根据提示, 到服务器修改对应的配置 application.yml
和 database.yml
, 可以分别参考 application.yml.example
和 database.yml.example
$ vi /data/www/xxx/shared/config/application.yml
$ vi /data/www/xxx/shared/config/database.yml
调整 config/deploy/production.rb
的配置后, 可以开始第一次发布了.
发布任务往往第一次会失败, 为了方便调试和追踪, 可以先进行一次冒烟
(本地)$ mina first_deploy
如果一切顺利, 进入正式发布流程.
(本地)$ mina deploy
发布成功后, 开始配置 nginx
为了确保 action cable 可以正确工作, 需要 nginx 版本不低于 1.9
nginx 安装与配置
# add-apt-repository ppa:nginx/stable
# apt-get update
# apt-get install nginx
# nginx -v ( > 1.9 )
# cp /data/www/xxx/current/config/nginx.conf.example /etc/nginx/conf.d/xxx.conf
调整里面的 server_name 指向自己的域名
# nginx -s reload
在本地浏览器打开 http://yourserverdomain
来检查是否发布成功.
我们采用 ufw 来作为防火墙, 简单而不失安全.
ufw 配置, 打开 22
, 80
, 443
端口
# ufw allow 22/tcp
# ufw allow 80/tcp
# ufw allow 443/tcp
# ufw enable
这样, 可以防止大部分的入侵了.
CDN 可以大大加速应用的访问速度, 使用一个 CDN 服务后( 例如又拍云或七牛云 ), 拿到回源后的CDN地址.
在线上 application.yml 配置如下:
CDN: ''
添加以下代码到: config/environments/production.rb
if ENV['CDN'].present?
config.action_controller.asset_host = ENV['CDN']
end
重新编译 assets
$ cd /data/www/xxx/current
$ RAILS_ENV=production bundle exec rake assets:precompile
刷新页面, 检查静态资源是否正确显示, 即可.
# apt-get install monit
# cp /data/www/xxx/current/config/monit.conf.example /etc/monit/conf.d/xxx.conf
(可选, 集成 slack 通知)
rails-template
默认集成了日志分割工具, 确保在长期运行过程中日志不会无限增加. 默认的配置逻辑是每天切一份, 保留最近七天的日志.
# cp /data/www/xxx/current/config/logrotate.conf.example /etc/logrotate.d/xxx
测试一下
# logrotate -f /etc/logrotate.d/xxx
如果有安全问题, 请在配置中添加 su ruby ruby
, 然后重试.
如果你的应用使用了 actioncable, 必须确保连接数支持限制打开. 使用
$ ulimit -Sn
$ ulimit -Hn
来检查. 输出值都应该设置为 65535
. 如果不是, 请修改 limits.conf
配置.
# vi /etc/security/limits.conf
添加以下内容
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
然后使用上述命令再次检查输出结果, 确保成功.
推荐使用 exception_notification + slack 做异常监控.
参考代码如下:
Gemfile 添加:
gem 'exception_notification'
gem 'slack-notifier'
执行: bundle install
application.yml.example 添加:
# exception notification
EXCEPTION_SLACK_WEBHOOK: ''
EXCEPTION_USERNAME: ''
config/environments/production.rb 中添加:
if ENV['EXCEPTION_SLACK_WEBHOOK'].present?
config.middleware.use ExceptionNotification::Rack,
:slack => {
:webhook_url => ENV['EXCEPTION_SLACK_WEBHOOK'],
:channel => "#exceptions",
:username => ENV['EXCEPTION_USERNAME'].presence || 'webhook',
:additional_parameters => {
:mrkdwn => true,
}
}
end
发布之前, 别忘了在线上的 shared/config/application.yml 中添加 EXCEPTION_SLACK_WEBHOOK 的配置信息. 之后就可以了.
我们推荐使用 let's encrypt
来生成 ssl 证书, 用 acme.sh 命令来具体操作.
开始之前, 需要确保你的网站应用已经正常可以访问: http://yourdomain.com
, 这在生成证书时需要校验.
安装:
# curl https://get.acme.sh | sh
source ~/.bashrc
生成证书( 将示例域名和目录替换成实际项目的域名和目录 ):
# acme.sh --issue -d yourdomain.com -w /data/www/xxx/current/public
# mkdir /etc/nginx/sslkeys
安装到 nginx 目录中( 将示例域名替换成实际域名 )
# acme.sh --installcert -d yourdomain.com --keypath /etc/nginx/sslkeys/yourdomain.com.key --fullchainpath /etc/nginx/sslkeys/yourdomain.com.key.pem --reloadcmd "service nginx force-reload"
准备 dhparam( 安全协议 ):
# openssl dhparam -out /etc/nginx/sslkeys/dhparam.pem 2048
# cp /data/www/xxx/current/config/nginx.ssl.conf.example /etc/nginx/conf.d/xxx.ssl.conf
更新配置 /etc/nginx/conf.d/xxx.ssl.conf
:
server_name yourdomain.com;
ssl_certificate /etc/nginx/sslkeys/yourdomain.com.key.pem;
ssl_certificate_key /etc/nginx/sslkeys/yourdomain.com.key;
ssl_dhparam /etc/nginx/sslkeys/dhparam.pem;
移除非 ssl 的配置
# rm /etc/nginx/conf.d/xxx.conf
推荐使用 backup gem 来做数据备份, rails-template 已经准备好一份 backup.rb 的示例. 操作如下:
$ gem install backup -v '5.0.0.beta2'
$ backup generate:model --trigger xxx --archives --storages='local' --compressor='gzip'
$ cp /data/www/xxx/current/config/backup.rb.example ~/Backup/models/xxx.rb
$ backup perform --trigger xxx
这样已经将数据库与配置文件备份到 /data/www/backups 中了.
在实际使用中, 我们需要设定自动备份, 以及云端备份( 建议使用 FTP 上传模式 ), 那么操作如下:
先注释 ~/Backup/models/xxx.rb
中的 local 字段,打开 FTP 字段,调整其中的配置参数,然后往下看。
安装 whenever 并设定配置:
$ gem install whenever
schedule.rb 配置如下:
env :PATH, ENV['PATH']
every 1.day, :at => '02:00' do
command "backup perform -t xxx"
end
$ cd ~/Backup
$ mkdir config
$ cp schedule.rb config/schedule.rb
生成 crontab 配置
$ whenever --update-crontab
使用 backup perform -t xxx
来检查是否备份成功.
By dao42 team