一直做的是一些前端的工作,对服务器的配置部署没有很完整的经验。这次自己完整的配置了一台服务器,记录一下同时也可以让有相同需求的人少走一些弯路。
如果配置完成的话,只要修改好本地的版本,然后git push一下,最后运行命令 cap deploy,你的本地版本就会部署到服务器上,这个过程新旧版本是无缝切换的,听上去是不是非常的棒呢!
环境安装
首先是环境安装,这部分用了个脚本
请务必完整的看一下脚本再进行安装
把这个wget到服务器上,适当编辑后(修改deploy账号密码,根据个人需要调整等)然后执行
$ wget https://raw.github.com/panlilu/scripts/master/stackscript $ vi stackscript $ sudo bash stackscript
然后就可以开始配置了,首先要对nginx进行配置:
Nginx
$ cd /usr/local/nginx/conf $ vi nginx.conf
编辑成这样
#/usr/local/nginx/conf/nginx.conf worker_processes 2; worker_cpu_affinity 01 10; worker_rlimit_nofile 51200; error_log /home/deploy/log/nginx/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { use epoll; worker_connections 51200; } http { include mime.types; default_type application/octet-stream; charset utf-8; access_log /home/deploy/log/nginx/access.log; sendfile on; tcp_nopush on; keepalive_timeout 65; tcp_nodelay on; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml text/javascript; gzip_vary on; include /usr/local/nginx/conf/vhosts/*.conf; }
注意上面配置文件倒数第二行,主配置文件会包含 /usr/local/nginx/conf/vhosts/ 下的.conf后缀配置文件作为虚拟主机配置
我们在/usr/local/nginx/conf/vhosts/下新建配置文件 <your_site>.com.conf
注意替换<your_site>作为你自己的域名
#/usr/local/nginx/conf/vhosts/<your_site>.com.conf limit_conn_zone $binary_remote_addr zone=default:10m; upstream <your_site>_backend { server unix:/tmp/unicorn.<your_site>.sock fail_timeout=0; } server { listen 80; server_name <your_site>.com www.<your_site>.com; root /home/deploy/app/<your_site>/current/public; try_files $uri/index.html $uri.html $uri @unicorn; location ~* ^(/assets|/favicon.ico) { gzip_static on; access_log off; expires max; } location @unicorn { limit_conn default 5; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering on; proxy_pass http://<your_site>_backend; } }
配置完成后重启nginx
$ sudo /etc/init.d/nginx restart
如果重启成功没有返回什么错误,这个时候你如果域名绑定成功了,访问域名出现一个503bad gateway错误的话,说明你的配置大概已经成功了。
接下来需要配置应用了
关于如何配置本地的rails环境,我就不多说了,参考rails官网。
新建一个rails应用后,你需要对其进行一些修改:
Unicorn
首先我们要修改应用的gemfile使其包含unicorn
# Gemfile gem "unicorn" group :development do gem "capistrano" end
然后 bundle intall 一下就安装好了
然后对unicorn进行配置
#config/unicorn.rb rails_env = ENV['RAILS_ENV'] || 'production' app_path = "/home/deploy/app/<your_site>/current" listen "/tmp/unicorn.<your_site>.sock" worker_processes 4 pid "#{app_path}/tmp/pids/unicorn.pid" stderr_path "#{app_path}/log/unicorn.log" stdout_path "#{app_path}/log/unicorn.log" preload_app true timeout 30 before_fork do |server, worker| old_pid = "#{app_path}/tmp/pids/unicorn.pid.oldbin" if File.exists?(old_pid) && server.pid != old_pid begin Process.kill("QUIT", File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH puts "Send 'QUIT' signal to unicorn error!" end end end
这样就完成了。
capistrano
先要安装capistrano
和安装unicorn差不多只要配置gemfile然后bundle install就行
# Gemfile group :development do gem "capistrano" end
bundle install完成之后还需要运行下面命令来生成一些文件
capify .
配置capistrano比较的麻烦,我直接帖出我已经配置好的文件
#config/deploy.rb require "bundler/capistrano" set :application, "<your_site>" set :user, "deploy" set :use_sudo, false set :repository, "deploy@git.<your_site>.com:repo/<your_site>.git" #请改成自己的git源 set :scm, :git # Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none` set :deploy_to, "/home/deploy/app/#{application}" set :deploy_via, :remote_cache set :domain, "feather.<your_site>.com" set :normalize_asset_timestamps, false #for Solve the probem: Not precomplie assets role :web, domain # Your HTTP server, Apache/etc role :app, domain # This may be the same as your `Web` server role :db, domain, :primary => true # This is where Rails migrations will run set :rails_env, "production" after "deploy", "deploy:cleanup" namespace :deploy do task :start, :roles => :app do run "cd #{deploy_to}/current/; RAILS_ENV=production bundle exec unicorn_rails -c config/unicorn.rb -D" end task :stop, :roles => :app do run "kill -QUIT `cat #{deploy_to}/current/tmp/pids/unicorn.pid`" end desc "Zero-downtime restart of Unicorn" task :restart, :roles => :app do run "kill -USR2 `cat #{deploy_to}/current/tmp/pids/unicorn.pid`" end task :setup_config, roles: :app do sudo "ln -nfs #{current_path}/config/unicorn_ini.sh /etc/init.d/unicorn_#{application}" run "mkdir -p #{shared_path}/config" end after "deploy:setup", "deploy:setup_config" desc "Make sure local git is in sync with remote." task :check_revision, roles: :web do unless `git rev-parse HEAD` == `git rev-parse origin/master` puts "WARNING: HEAD is not the same as origin/master" puts "Run `git push` to sync changes." exit end end # desc "run 'bundle install' to install Bundler's packaged gems for the current deploy" # task :bundle_install, :roles => :app do # run "cd #{current_path} && bundle install" # end before "deploy", "deploy:check_revision" after 'deploy:update_code' do run "cd #{release_path}; RAILS_ENV=production rake assets:precompile" end end # if you're still using the script/reaper helper you will need # these http://github.com/rails/irs_process_scripts # If you are using Passenger mod_rails uncomment this: # namespace :deploy do # task :start do ; end # task :stop do ; end # task :restart, :roles => :app, :except => { :no_release => true } do # run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}" # end # end task :mongoid_create_indexes, :roles => :web do run "cd #{deploy_to}/current/; RAILS_ENV=production bundle exec rake db:mongoid:create_indexes" end
Unicorn_ini.sh 这个脚本配置完成后会自动软链接到/etc/init.d/unicorn_<your_site> 的,方便控制unicorn的运行
#config/unicorn_ini.sh #!/bin/sh ### BEGIN INIT INFO # Provides: unicorn # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Manage unicorn server # Description: Start, stop, restart unicorn server for a specific application. ### END INIT INFO set -e # Feel free to change any of the following variables for your app: TIMEOUT=${TIMEOUT-60} APP_ROOT=/home/deploy/app/<your_site>/current PID=$APP_ROOT/tmp/pids/unicorn.pid CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production" AS_USER=deploy set -u OLD_PIN="$PID.oldbin" sig () { test -s "$PID" && kill -$1 `cat $PID` } oldsig () { test -s $OLD_PIN && kill -$1 `cat $OLD_PIN` } run () { if [ "$(id -un)" = "$AS_USER" ]; then eval $1 else su -c "$1" - $AS_USER fi } case "$1" in start) sig 0 && echo >&2 "Already running" && exit 0 run "$CMD" ;; stop) sig QUIT && exit 0 echo >&2 "Not running" ;; force-stop) sig TERM && exit 0 echo >&2 "Not running" ;; restart|reload) sig HUP && echo reloaded OK && exit 0 echo >&2 "Couldn't reload, starting '$CMD' instead" run "$CMD" ;; upgrade) if sig USR2 && sleep 2 && sig 0 && oldsig QUIT then n=$TIMEOUT while test -s $OLD_PIN && test $n -ge 0 do printf '.' && sleep 1 && n=$(( $n - 1 )) done echo if test $n -lt 0 && test -s $OLD_PIN then echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds" exit 1 fi exit 0 fi echo >&2 "Couldn't upgrade, starting '$CMD' instead" run "$CMD" ;; reopen-logs) sig USR1 ;; *) echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>" exit 1 ;; esac
配置完成后,本地运行:
cap deploy:setup
补充
为了防止每次静态文件编译过慢,我们需要引入一个新的gem
gem 'turbo-sprockets-rails3'
服务器的路径结构是这样的
~/app/<your_site> 应用的存放目录
~/app/<your_site>/current 当前的版本
~/app/<your_site>/releases 最近的releases
~/app/<your_site>/shared 应用的公用文件,比如日志等
~/app/repo 存放git仓库
~/log log的链接
~/conf 配置文件的链接
至于git的配置我想大家都轻车熟路,我就不多说了。
参考
以上