Its all about Ruby On Rails
Posts tagged deploy
11 Things to Consider Before Deploying Your Rails Application
Nov 16th
Cross Posted from http://vinsol.com/blog
At VinSol, we have been developing and deploying Rails applications for more than four years. During this period, we have identified some best practices that we prefer to follow while deploying rails application to production server.
Below is the checklist of these practices:
1. Ensure that NS records and MX records are changed if they need to be changed
Changing nameservers will point the domain to the hosting server, and changing MX records will redirect incoming mails to the mail server. As a very first step, we should make sure that name servers of the domain are set to be the correct one. Changing MX record is a must if our application is parsing incoming mails or we wants to use other mail services for e-mail exchange, for example Gmail.
2. Ensure some backup mechanism in place for both data as well as user uploaded content like images/documents etc.
Since production data is very critical, we must setup backup mechanism. It could be some type of scheduled task that takes periodic backup of all critical data, Or it could be some type of backup service provided by hosting company. When we talk about critical production data, it includes production DB, content generated by application users like images, documents, etc.
3. Ensure database indexes
We might have done development without having proper database indexes, but we should avoid going to production without them. Adding indexes might slow down insert queries a bit but it increases the performance of read queries. It applies when application in production has percentage of read operations much more than write operations.
4. Enable your slow query log
This is specific to MySQL. Enabling slow query log allows MySQL to log slow running queries to a file. And this log can be used to find queries that take a long time to execute and are therefore candidates for optimization.
5. Ensure exception capturing is in place
We might want to be notified when something bad happens to our application. There are several hosted services available who receive and track exceptions, for example Hoptoadapp.com, GetExceptional.com etc… Either we can choose one from these hosted services or we can use “exception notifier” plugin.
6. Ensure adding entries for cron/scheduled jobs
Most of the applications have some functionality/jobs that need to be run periodically, for example generating invoices, sending newsletters etc. In most cases these jobs are done by a rake task. We should make sure that we have added such jobs to cron or similar program.
7. Monitoring important processes
To ensure that our site is up 24×7 we need to ensure that all processes that our application needs are up. There can be many processes like MySQL, Mongrel, Apache etc.. These processes are very important as our application directly depends on them. For example if MySQL process get killed accidentally, our application would not be able to connect to MySQL and will start throwing exceptions.
We can choose any of the available monitoring tools like God, Monit, 24×7 etc…
8. Ensure confidential data filtering
We would never like to leak/share confidential information of our application users. We should make sure that none of the user’s confidential data like SSN, Credit card info, password are being written to log files. We might not have paid much attention on this while developing the application.
9. Rotate log files
Once our site is up and running, every single request write some text in log file. And hence size of the log file keeps on increasing. Larger log files can put us in trouble if we get it beyond certain size. Its difficult to manage these log files, as larger files need more memory to open and need more time to download. In one of the rescue project we did , the log file size was 3GB.
We would recommend having logrotate setup for the application.
10. Setup Asset Host
Setting up asset hosts can reduce loading time by 50% or more. We must setup asset hosts for our application. Once asset hosts are all set, our static files will be delivered via asset hosts for example asset1.hostname.com, asset2.hostname.com
11. Clearing up stale sessions
We should make sure we should not left any stale session on the server. If our application is using DB or file system as session store, we must add a schedule task to delete stale sessions.
These are some of the points we have identified from our past experience and we might be missing some. Feel free to always add them as comments, and I’ll keep this post updated.
We also provide affordable rails deployment services.
WebByNode: A New Hosting Service Launching Soon
Nov 9th
Guys, I received a mail today that there will be a new hosting service launching soon. They said that it makes easier to deploy your applications. Whether its Ruby on Rails, Django, LAMP or your choice of Linux Distribution, its a ready-to-go solution. For more information please visit http://www.webbynode.com/
I am signing up there as a beta tester. Lets see how webby-node can help rails community by its services.
Running Rails Application on https with pound
Sep 13th
Hours ago, I posted about, “How to deploy rails application with pound as a Balancer”.
Lets run rails application on https with pound. For that your machine should have:
* Pound installed with ssl support
* Pound and mongrels running
Now, First of all we need a ssl certificate, that can be generate by issuing “openssl req -x509 -newkey rsa:1024 -keyout mydomain.pem -out mydomain.pem -days 365 -nodes” . Give all the information it asks. Now copy mydomain.pem to /etc/pound/ directory(I am assuming that your pound.cfg file resides in /etc/pound/). Now put the following code in pound configuration file(/etc/pound/pound.cfg):
ListenHTTPS
Address 0.0.0.0
Port 443
Cert "/etc/pound/mydomain.pem"
# pass along https hint
AddHeader "X-Forwarded-Proto: https"
HeadRemove "X-Forwarded-Proto"
Service
URL "/(images|stylesheets|javascripts)/"
BackEnd
Address 127.0.0.1
Port 8080
End
Session
Type BASIC
TTL 300
End
End
Service
BackEnd
Address 127.0.0.1
Port 8000
End
BackEnd
Address 127.0.0.1
Port 8001
End
BackEnd
Address 127.0.0.1
Port 8002
End
End
End
I am assuming that your mongrels are running at ports 8000, 8001, 8002, apache running at 8080 and pound is listening ports 443 & 80.
Restart pound, and you are done. With this configuration all requests for dynamic content at port 443(https) will get redirected to mongrels and requests for static content will get redirected to apache.
You may want to check if the request is https or not before serving the content. That can be done by adding a before_filter (defined below) in application.rb :
def confirm_ssl
unless request.ssl?
request.env["HTTPS"] = "on"
redirect_to "/"
return
end
end
By adding this method as before_filter in application.rb your application will check for https, if the request is not of type https it will redirect to an https request.
Deploying rails application with pound as a Balancer
Sep 13th
Now a days Apache + mod_proxy + mongrel_clusters, Lighttpd + Mongrel cluster and Nginx + mongrel cluster are well known for deploying rails applications.
You can also deploy your rails application with pound(a reverse proxy, load balancer and HTTPS front-end for Web server).
First you need to setup mongrel_clusters for your rails application by issuing ” mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 3 -c ./ ” inside the rails application root directory(on client machine). This will create mongrel_cluster.yml in config directory. You can change parameters in this command, as -p 8000 specifies that mongrel instances will start up on port number starting 8000, -a 127.0.0.1 specifies that mongrel instances will listen to the localhost, -N specifies the number of mongrel instances and -c specifies the rails root directory.
Now you need to install pound(if not installed) by issuing following commands(as root):
- cd /opt/src
- wget http://www.apsis.ch/pound/Pound-2.3.2.tgz
- tar xzpf Pound-2.1.6.tgz
- cd Pound-2.1.6
- ./configure
- make
- make install
This will install pound in /usr/local/sbin/pound. In order to proceed further we need to create pound.cfg(pound configuration file) in /etc/pound/pound.cfg . Below is the content of pound.cfg:
User "pound"
Group "pound"
ListenHTTP
Address 0.0.0.0
Port 80
Service
BackEnd
Address 127.0.0.1
Port 8000
End
BackEnd
Address 127.0.0.1
Port 8001
End
BackEnd
Address 127.0.0.1
Port 8002
End
End
End
Start mongrel cluster by issuing mongrel_rails cluster::start in you app root directory, start pound by /usr/local/sbin/pound -f /etc/pound/pound.cfg , now you are done. Pound is listening the port 80 and redirect all requests to mongrel instances running on 8000, 8001, 8002.
* Please Note that we have configured pound at port 80, if port 80 is being used by apache or any other application pound will not start. You need to stop any service using port 80, if it is apache then stop apache, change line ‘Listen 80′ to “Listen 8080″ and start apache.
In a specific case, when apache is running at some port (let say 8080), you may want to use apache to serve static content of your application, in order to reduce some load from mongrels. In that case use the following:
User "pound"
Group "pound"
ListenHTTP
Address 0.0.0.0
Port 80
Service
URL "/(images|stylesheets|flash|javascripts)/"
BackEnd
Address 127.0.0.1
Port 8080
End
Session
Type BASIC
TTL 300
End
End
Service
BackEnd
Address 127.0.0.1
Port 8000
End
BackEnd
Address 127.0.0.1
Port 8001
End
BackEnd
Address 127.0.0.1
Port 8002
End
End
End
This will redirect all requests for image, stylesheets, javascripts, flash to apache. Now we need to configure apache to serve those static content. Just add a virtualhost for that:
<virtualHost *:8080>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html/example.com/public
<directory "/var/www/html/example.com/public" >
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</directory>
RewriteEngine On
# For static files it's good to avoid hitting your mongrel process
# so let apache knows it should serve it directly
# for a rails application it means, files in images / stylesheets / javascripts
RewriteRule "^/(images|stylesheets|flash|javascripts)/?(.*)" "$0" [L]
</virtualHost>
Its all done. All requests for dynamic content at port 80 will be redirect to mongrel running at 8000, 8001, 8001 and requests for static content will be served by apache running at port 8080.
Customizing CruiseControl build for RSpec
Aug 30th
Yesterday I posted about CruiseControl for Rails projects. It was working fine with all my rails projects using traditional test cases, But today I faced a problem with a project using RSpec. Actually, By default CruiseControl follows the following step to build:
- rake db:test:purge
- rake db:migrate
- rake test
This default was not working with my last project As I was using RSpec for my project. I found that we can overwrite default way of building by creating a rake task named cruise in our project. Means by building CruiseControl will run your custom rake task only, so you have to take care of all other things i.e. migrate etc.
Hence I created following rake task in RAILS_ROOT/lib/tasks/custom_cc.rake
desc 'Custom curise task for RSpec'
task :cruise do
ENV['RAILS_ENV'] = 'test'
if File.exists?(Dir.pwd + "/config/database.yml")
if Dir[Dir.pwd + "/db/migrate/*.rb"].empty?
raise "No migration scripts found in db/migrate/ but database.yml exists, " +
"CruiseControl won't be able to build the latest test database. Build aborted."
end
# perform standard Rails database cleanup/preparation tasks if they are defined in project
# this is necessary because there is no up-to-date development database on a continuous integration box
if Rake.application.lookup('db:test:purge')
CruiseControl::invoke_rake_task 'db:test:purge'
end
if Rake.application.lookup('db:migrate')
CruiseControl::reconnect
CruiseControl::invoke_rake_task 'db:migrate'
end
end
CruiseControl::invoke_rake_task 'spec:all'
end
and it worked for my rails project using RSpec.