Deploy RoR application with Nginx
This article will talk something about deploying RoR application to local and remote nginx server.
Deploy RoR on local machine
Like deploying other website, the static file is served via nginx, and the Ruby logic will be handled via some middle-wares, here is the list:
Thin
Install the
thin
viahomebrew
gem install thin
Start the thin server. Since this is a testing deploy, I just execute thin in the project directory.
thin start
After the command executed, you can find some information printed via thin
command. The default port of the server is 3000, which should be used to
fill the nginx configuration file.
Update the configuration file for nginx. The
upstream
section should be put inhttp
block.upstream todo_app { server http://127.0.0.1:3000
}
The location
section should be put in server
block.
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
try_files $uri $uri/index.html $uri.html @ruby;
}
location @ruby {
proxy_pass http://todo_app
}
The proxy_pass
will pass all ruby request to the upstream server. Unix socket
can also be used in the upstream
section.
- Restart the nginx server, the RoR project can be shown in the web browser now.
Passenger
Install passenger via gem
gem install passenger
Install passenger module for nginx
passenger-install-nginx-module
Or you can install nginx and passenger module with brew like this
brew install nginx --with-passenger
If nginx still report the error that can not find the PassengerLoggingAgent
,
try to use passenger package-runtime
and then get the agent from package
passenger-standalone/XXX/support.tar.gz
In the http section, you should specify the value of passenger_root
and
passenger_ruby
. Here is the configuration in my laptop:
passenger_root /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.12;
passenger_ruby /usr/local/bin/ruby;
NOTICE: Make sure to set rails_env
variable is set to the same stage with development, seems the default value is production
. Here is my configuration section in nginx:
passenger_root /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.12;
passenger_ruby /usr/local/bin/ruby;
server {
listen 8080;
server_name localhost;
root /Users/ziming/tmp/learn_rb/rails/todo_app/public;
passenger_enabled on;
rails_env development;
}
Unicorn
Install unicorn via gem
gem install unicorn
Get the sample configuration file from unicorn website
curl -o config/unicorn.rb https://raw.github.com/defunkt/unicorn/master/examples/unicorn.conf.rb
And update the working_directory
, pid
, stderr_path
and stdout_path
in
the sample configuration file. NOTICE: Need absolute path here.
- The left step is the same with Thin, a
upstream
section should be added to nginx.conf, and redirection should be added tolocation
section.
Deploy remotely via Capistrano
Capistrano is a useful tool for deploying RoR application to remote server(s). The Capistrany package provides several tasks for simplfying the deploying jobs.
- Prepare the RoR application
Before deploying, we should prepare the application. Since this only show how to deploy, so we just use the generated project. I have create a repository on bitbucket, and the scm used for this application is mercurial.
First I create the repository DailyCheckIn on butbucket, then I clone the
project to local directory dailycheckin
. The directory is an empty directory
except some mercurial information. After directory ready, I create RoR
application via rails new
command. Before doing the initialization commit, I
should create a .hgignore
file based on the .gitignore
(Just add syntax: glob
at the first line, remove the leader slash in the path, and rename
.gitignore
to .hgignore
). After all things done, commit the new added file
and push to the server, then we have a RoR application.
- Capify the RoR project
The project should be ‘capified’ before deplying via Captistrano, which can be
done via command capify .
easily. This command will create Capfile
and
config/deploy.rb
file in current directory. The Capfile
is the wrapper,
and the tasks is written in file deploy.rb
- Configure the Capistrano
Here are the information should be checked before deploying:
* Application name
* Server information
* Application layer
* Wer server
* Database
* SCM information
* Repository location
* SCM type
* Directory the project should be deployed to
Here is a sample configuration file for the project
set :application, "DailyCheckIn"
set :repository,
set :scm, :mercurial
server , :web, :app, :db, :primary => true
set :deploy_to,
set :use_sudo, false
The detailed information of configuration can be found in [Capistrano document](https://github.com/capistrano/capistrano/wiki/2.x-From-The- Beginning).
- Deploy the application
Next step is deploy the application. The first step is setting up the server,
Capistrano provide task cap deploy:setup
to do this. This task will do a
series of mkdir
calls. Make sure the permission of directory.
After setting up completed, it is recommended to check the dependencies via
cap deploy:check
command. Re-run this command after any change to the
environment to make sure all check passed.
The next step should be done manually, you should login to the server and make
sure the database can meet the requirement configured in the
config/database.yml
file.
After environment ready, task deploy:update
can be used to clone the code to
server. The clone operation will create a new snapshot in the releases
directory, and link it with symbol link current
in top level of depoly
directory. Then cap deploy:start
can be used to start the services.