Rails Deployment Environment on Windows Rails Deployment Environment on Windows windows windows

Rails Deployment Environment on Windows


UPDATE: I just returned to the company where I deployed with this process. After 11 months left completely unmaintained while the product was in use, the app and server environment are still functioning flawlessly :)

Ok, it looks like I finally figured it out. Note that I am deploying to a small pool of users on a company intranet, so my solution may not work for everyone. I am using the excellent Bitnami RubyStack, which contains an integrated Apache/Rails/MySQL installation. From there I did the following (worked for Rails 3.2.6 and Ruby 1.9.3):

  1. Shut down all Apache and Rails (WEBrick/Thin/Mongrel/Unicorn) servers. Exit out of your site if you have any development versions of it open. Clear your browser cache.

  2. If you haven't already, migrate your database to production mode. From the RubyStack command line, cd to your app's directory, then run bundle exec rake db:migrate db:schema:load RAILS_ENV="production". WARNING: db:schema:load will delete all data in your production database.

  3. Precompile your assets: bundle exec rake assets:precompile. Note that this can take a very long time depending on your assets.

  4. In your httpd.conf (for me it's C:\RubyStack-3.2.5-0\apache2\conf\httpd.conf)

    Make sure necessary modules aren't commented out:

    LoadModule expires_module modules/mod_expires.soLoadModule headers_module modules/mod_headers.soLoadModule proxy_module modules/mod_proxy.soLoadModule proxy_balancer_module modules/mod_proxy_balancer.soLoadModule proxy_http_module modules/mod_proxy_http.soLoadModule rewrite_module modules/mod_rewrite.so

    Then paste the following code somewhere in the file, with app_name being the folder name of your Rails app and *:82 being any port number that Apache is listening to (signified by the command Listen <port_number>:

    <VirtualHost *:82>  # Your server's web or IP address goes here.  # You can leave at localhost if deploying to  # company intranet or some such thing.  ServerName localhost  # Customize the next two lines with your app's public directory  DocumentRoot "C:/RubyStack-3.2.5-0/projects/app_name/public"  <Directory "C:/RubyStack-3.2.5-0/projects/app_name/public">    Allow from all    Options -MultiViews  </Directory>  RewriteEngine On  # Redirect all non-static requests to Rails server,  # but serve static assets via Apache  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f  RewriteRule ^/(.*)$ balancer://app_balancers%{REQUEST_URI} [P,QSA,L]  # Serves dynamic rails assets from multiple servers  # to improve performance. A Rails server such as  # thin or WEBrick must be running on at least one of  # these ports in order for Apache to serve your site  <Proxy balancer://app_balancers>    BalancerMember http://localhost:3001/    BalancerMember http://localhost:3002/  </Proxy>  # Support for far-futures expires header  <LocationMatch "^/assets/.*$">    Header unset ETag    FileETag None    # RFC says only cache for 1 year    ExpiresActive On    ExpiresDefault "access plus 1 year"  </LocationMatch></VirtualHost>
  5. Create one Windows Batch file (*.bat) for each of the Rails servers that your app will be using. Be sure to run them in production mode on the ports in your balancer. For instance, for your first server:

    @echo offcd D:\your_app_folderrails s -e production -p 3001
  6. NOTE: The next few steps are necessary because the Rails servers need to run as services, or they will be shut down if there is no user logged in to the server. This also allows them to automatically restart upon failure. However, Windows cannot run Batch files as services, so we have to convert them to Windows EXEs. But standard Windows EXEs cannot be used as services because they don’t respond to the OnStart and OnStop methods. SO, to finally get our servers to run as Windows services, we have to use the Non-Sucking Service Manager as a frontend for our Windows EXEs.

  7. Download a BAT to EXE converter (just google for one) and make EXEs from your batch files. Make sure the converter you get has an option to hide the command windows when it runs (that option is usually called "Visibility" or something like that.)

  8. Download the Non-Sucking Service Manager (nssm.exe). Put it somewhere permanent and add that folder to your path.

  9. Start a command prompt. Type nssm install <servicename>, where <servicename> is whatever you want your service to be called. You will be prompted to enter the path to the application you wish to run as a service; choose the Windows EXEs you created in step 7, then click install, leaving commandline options blank.

  10. Repeat steps 6-8 for all of the ports in your balancer, creating a different service for every Rails server.

  11. Start all of the Services you just created (Start Menu –> Administrative Tools –> Services). The services should start immediately, but you must give the Rails servers at least 30 seconds to initialize.

  12. Start Apache. If it doesn't start, check to see if you included all the necessary modules (listed in first part of step 4).

  13. Navigate to localhost:82, substituting your port number for 82 if you customized it. You should see your site looking exactly the same as it did in development.

Please let me know if this is too long to be appropriate for StackOverflow. I have just spent quite a lot of time struggling with this problem and figured it was high time someone wrote a up to date guide to Rails deployment on Windows (if there is one, I haven't seen it yet). Good luck, let me know if anyone has problems or enhancements for this!