CentOS用户操作
-
创建新用户和组
useradd deploy -G admin -p deploy
- 创建新组admin,新用户deploy,密码deploy,并将deploy用户加入admin组。
- 创建部署目标文件夹
mkdir -p /var/www/myapp
chown -R deploy /var/www/myapp
-
设置ssh
vi /etc/ssh/ssh_config
-
Port 13579
可以修改ssh的端口 -
RSAAuthentication yes
RSA验证 -
PasswordAuthentication yes
密码验证 -
PermitEmptyPasswords no
不允许空密码登录 -
AllowUsers deploy
只允许指定用户
-
开启ssh
-
service sshd start
开启ssh -
chkconfig sshd on
开机启动
-
-
shh公钥免密码登录
- 如果是mac用户,可以用ssh-copy-id
-
brew install ssh-copy-id
下载ssh-copy-id ssh-copy-id [email protected]
- 用密码登录一次,OK了,就这么简单
-
- 传统做法
ssh [email protected]
cd /home/deploy
mkdir ./.ssh
- 回到自己的本地Terminal
-
scp /path/to/.ssh/id_rsa.pub [email protected]/deploy/.ssh/authorized_keys
将本地RSA公钥复制到服务器
- 如果是mac用户,可以用ssh-copy-id
Ruby开发环境搭建
- 安装需要的软件
- `sudo yum install -y git-core openssl bzip2 bzip2-devel gcc ruby-devel zlib-devel libxml2`
- 安装MySQL
1. mysql`sudo rpm -e --nodeps mysql`删除本地
2. `sudo yum install -y mysql-server mysql mysql-deve`
3. `sudo service mysqld start`开启mysql
4. `sudo service mysqld start`设置开机启动
- 安装Node
1. `wget http://nodejs.org/dist/v0.12.2/node-v0.12.2.tar.gz`下载
2. `tar -zvxf node-v0.12.2.tar.gz`解压
3. `cd node-v0.12.2`
4. `sudo make & make install`编译
- 安装Nginx
1. `mkdir /etc/yum.repos.d/nginx.repo` 设置Nginx的镜像配置文件
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
2. `sudo yum install nginx`
1. 安装rvm
1. `curl -L https://get.rvm.io | bash -s stable` 下载rvm
2. `sed -i 's!ftp.ruby-lang.org/pub/ruby!ruby.taobao.org/mirrors/ruby!' $rvm_path/config/db` 将rvm的资源地址换到taobao
- 安装Ruby
- `rvm 2.1.4`安装ruby-2.1.4
- 改变gem source
- `gem sources --remove https://rubygems.org/`
- `gem sources -a http://ruby.taobao.org/`
- 安装bundle
- `gem install bundle --no-rdoc --no-ri`
配置Puma
首先要在Gemfile中添加
gem 'puma'
Puma中文文档
-
myapp/config/puam.rb
#!/usr/bin/env puma environment ENV['RAILS_ENV'] || 'development' daemonize true pidfile "//var/www/myapp/tmp/pids/puma.pid" stdout_redirect "//var/www/myapp/log/stdout", "//var/www/myapp/log/stderr" threads 0, 16 bind "unix:///tmp/deploy.sock"
-
myapp/bin/puma.sh
- 用于puma的操作
#! /bin/sh
PUMA_CONFIG_FILE=/var/www/myapp/config/puma.rb
PUMA_PID_FILE=/var/www/myapp/tmp/pids/puma.pid
PUMA_SOCKET=/var/www/myapp/tmp/sockets/puma.sock
# check if puma process is running
puma_is_running() {
if [ -S $PUMA_SOCKET ] ; then
if [ -e $PUMA_PID_FILE ] ; then
if cat $PUMA_PID_FILE | xargs pgrep -P > /dev/null ; then
return 0
else
echo "No puma process found"
fi
else
echo "No puma pid file found"
fi
else
echo "No puma socket found"
fi
return 1
}
case "$1" in
start)
echo "Starting puma..."
rm -f $PUMA_SOCKET
touch -f $PUMA_SOCKET
touch -f $PUMA_PID_FILE
if [ -e $PUMA_CONFIG_FILE ] ; then
bundle exec puma -C $PUMA_CONFIG_FILE
else
bundle exec puma
fi
echo "done"
;;
stop)
echo "Stopping puma..."
kill -s SIGTERM `cat $PUMA_PID_FILE`
rm -f $PUMA_PID_FILE
rm -f $PUMA_SOCKET
echo "done"
;;
restart)
if puma_is_running ; then
echo "Hot-restarting puma..."
kill -s SIGUSR2 `cat $PUMA_PID_FILE`
echo "Doublechecking the process restart..."
sleep 5
if puma_is_running ; then
echo "done"
exit 0
else
echo "Puma restart failed :/"
fi
fi
echo "Trying cold reboot"
echo [ -S $PUMA_SOCKET ]
bin/puma.sh start
;;
*)
echo "Usage: bin/puma.sh {start|stop|restart}" >&2
;;
esac
配置Mina
- 在Gemfile中添加
gem 'mina'
-
mina init
生成deploy.rb文件 - 设置myapp/config/deploy.rb
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rvm'
set :user, 'deploy'
set :domain, 'your.server.domain.ip'
set :deploy_to, '/var/www/myapp'
set :repository, 'https://github.com/YourGitName/myapp.git'
set :branch, 'master'
set :forward_agent, true
set :app_path, lambda { "#{deploy_to}/#{current_path}" }
set :stage, 'production'
set :rvm_path, '/home/deploy/.rvm/bin/rvm'
set :shared_paths, ['config/database.yml', 'log']
task :environment do
invoke :'rvm:use[ruby-2.0.0-p643@default]'
end
task :setup => :environment do
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"]
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp"]
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/sockets"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/sockets"]
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/pids"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/pids"]
queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/log"]
queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]
queue %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."]
end
desc "Deploys the current version to the server."
task :deploy => :environment do
to :before_hook do
end
deploy do
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
queue! "cd #{app_path} & RAILS_ENV=#{stage} bundle exec rake db:create"
invoke :'rails:db_migrate'
queue! "cd #{app_path} & RAILS_ENV=#{stage} bundle exec rake db:seed"
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
invoke :'puma:restart'
to :launch do
end
end
end
namespace :puma do
desc "Start the application"
task :start do
queue 'echo "-----> Start Puma"'
queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh start", :pty => false
end
desc "Stop the application"
task :stop do
queue 'echo "-----> Stop Puma"'
queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh stop"
end
desc "Restart the application"
task :restart do
queue 'echo "-----> Restart Puma"'
queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh restart"
end
end
开始部署
-
Rails 相关设置
- 编辑/config/application.rb
-
config.assets.precompile += %w(....)
在括号中加入app/assets/和lib/assets/还有vender/assets/里面js/css的文件
名
- 编辑/config/environments/production.rb
-
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
因为我们要用Nginx,所以要将此行应用。
-
setup
mina setup
- 在此过程中可能会遇到问题:
1. 安装libv8失败:可以尝试`bundle config build.libv8 --with-system-v8`
1. 安装nokogiri失败,可以尝试`bundle config build.nokogiri --use-system-li braries`
1. 安装therubyracer失败,还没有找到有效的解决办法。
- 解决方案
1. Gemfile去掉 `gem 'therubyracer'` 和 `gem 'less-rails'`
2. `bundle install`
3. 用nodejs代替libv8来提供Javascript运行时环境
- 配置 /var/www/myapp/shared/config/database.yml
- 将myapp/config/database.yml内容复制进去
-
deploy
mina deploy
-
Nginx设置
-
修改/etc/nginx/nginx.conf
user deploy; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; upstream deploy { server unix:///var/www/myapp/tmp/sockets/puma.sock; } server { listen 80; server_name your.server.domain.ip; # change to match your URL root /var/www/myapp/current/public; # I assume your app is located at this location location / { proxy_pass http://deploy; # match the name of upstream directive which is defined above proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ~* ^/assets/ { # Per RFC2616 - 1 year maximum expiry expires 1y; add_header Cache-Control public; # Some browsers still send conditional-GET requests if there's a # Last-Modified header or an ETag header even if they haven't # reached the expiry date sent in the Expires header. add_header Last-Modified ""; add_header ETag ""; break; } } }
-
-
重启nginx
sudo nginx -s reload
后记
中间可能会遇到很多问题可以从以下几个方面进行排查
-
首先保证Puma在可以跑,
- 将config/puma.rb 里的
daemonize true
注释掉 - 在/var/www/myapp/current目录里运行
bundle exec puma -C config/puma.rb
- 将config/puma.rb 里的
-
查看/var/log/nginx/error.log看错误信息
- 可能会遇到Permission denied问题,注意/etc/nginx/nginx.conf文件第一行的
user deploy
- 可能会遇到Connection refuesd问题,可能是Puma运行失败。
- 可能会遇到Permission denied问题,注意/etc/nginx/nginx.conf文件第一行的
要有耐心,说实话第一次部署会遇到各种各样的问题,遇到很多不熟悉的知识点。在此过程中可以学到很多知识,加油吧。