mlte.de

Deploying Rails on Windows Server as Java Servlet

Typically you deploy Ruby on Rails on a Linux server with an Apache HTTP server or nginx. You can use Phusion Passenger for that purpose and it works well and is quite easy to setup. But sometimes other constraints force you to use a Windows server. This article explains my steps to package a Rails application as a war archive usingWarbler and to deploy this war on Apache Tomcat used as a backend for Microsofts Internet Information Services (IIS) HTTP server on Windows Server 2012 R2.

Packaging a Rails application as war archive

To package a Rails application into a war archive that can be deployed on nearly any Java application server we first need to make sure that the Rails application runs on JRuby. If you are on Linux or Mac use RVM to install JRuby. If you develop on Windows simply use the official windows installer of the JRuby project.

If you just create a new Rails project on JRuby using

rails new example

this project is already well prepared to run in JRuby. The main difference are the database adapters specified in the Gemfile. Using JRuby these need to be one of the following depending on your database:

  • gem 'activerecord-jdbcmysql-adapter' to use a MySQL database.
  • gem 'activerecord-jdbcpostgresql-adapter' to use a PostgreSQL database.
  • gem 'activerecord-jdbcsqlite3-adapter' to use SQLite as your database. This is the default for a newly created Rails project but it is not supposed to be used in a production environment.

In your environments/production.rb you can savely disable Rails's static asset server as the Tomcat will do this for you.

Now you can install the warbler gem running

gem install warbler

This gem must not be listed in the Gemfile as we do not need it as a dependency of our Rails project but as a tool which we will apply on this project. Now run

warble config

to generate a configuration file for the warbler. This will generate the file config/warbler.rb which already contains very good defaults. I used the following settings:

  • config.dirs = %w(app config lib) to specify which directories should be included in the war archive.
  • config.webxml.jruby.compat.version = "2.1" to make sure the latest ruby version is used.

No we are ready to run

warble

to create the example.war of our project.

Deploying a Java Servlet on Apache Tomcat integrated in IIS on Windows Server

If not already done install the IIS on your Windows server using the Server Manager: Click Manage / Add Roles and Features to start the Add Roles and Features Wizard. Select Role-based or feature-based installation and select your local server in the Server Pool. Then select Webserver (IIS) as new feature. Make sure to select ISAPI Extensions and ISAPI Filters under Application Development as Tomcat will be integrated via ISAPI. If your IIS is already installed add this features if needed using the same way.

Now download and install the Apache Tomat. I used Tomcat 8.0 and the 32-bit/64-bit Windows Service Installer from the official Tomcat website.

After Tomcat is installed you can access it on http://localhost:8080 on the machine. The Windows firewall prevents this server from being available outside of this machine and we will leave this as it is, because we want to use the IIS as our webserver. You can now deploy your application example.war on the Tomcat using the application manager linked on the default root application and located on http://localhost:8080/manager.

After deploying check that everything is working correctly by opening http://localhost:8080/example in a browser on the server. If you want your application to be available as root application and not on the URL /example you can deploy it as root application of the Tomcat. Therefore goto the folder C:\Program Files (x86)\Apache Software Foundation\Tomcat 8.0\webapps and remove everything in it. Now copy your example.war as ROOT.war in this folder. Again make sure everything os working correctly by opening http://localhost:8080 in a browser on the server.

Next download the Tomcat Connector. I used the file tomcat-connectors-1.2.40-windows-x86_64-iis.zip linked under Binary Releases on the official Tomcat website. Extract the contents of this file to the folder C:\connectors and make sure that the IIS has full access rights to this folder:

  1. Right click the folder and select Properties.
  2. Switch to the Security tab and click Edit…
  3. If IIS_USRS is already present in the list then grant full access to this group. Otherwise click Add…
  4. Click Advanced… and make sure that everythin is selected in the field Select this object type.
  5. Click Find Now and select IIS_USRS in the search results.
  6. Click OK often enough and grant full access to this group.
  7. Click OK often enough to apply the changes.

Now create a file isapi_redirect.properties in this folder. It must have the same name as the isapi_redirect.dll in this folder. Add the following properties as content of this file.

extension_uri=/jakarta/isapi_redirect.dll
log_file=C:\connector\isapi.log
# Log level(debug, info, warn, error or trace)
log_level=warn
worker_file=C:\connector\workers.properties
worker_mount_file=C:\connector\uriworkermap.properties

Now create the referenced worker file workers.properties with the following contents

worker.list=myworker
worker.myworker.type=ajp13
worker.myworker.host=127.0.0.1
worker.myworker.port=8009

This settings have to match the settings specified for the Tomcat during its installation. I left everything as the default was.

Now create the referenced worker mount file uriworkermap.properties with the following content.

/example=myworker
/example/*=myworker

This assumes that your application is available on the URL /example on the Tomcat server. If you set your application as root you can use the following contents instead.

/=myworker
/*=myworker

We now finally need to tell the IIS to use the configured Tomcat connector. Therefore open the Internet Information Service (IIS) Manager and select the Default Web Site in the Connections tree view on the left. Right click it and select Add application… Enter jakarta as Alias and C:\connector as Physical path. This doesn't necessarily need to be jakarta but it has to match the extension_uri specified in the Tomcat Connector properties file created above.

Now again select the Default Web Site and open the ISAPI Filters. Add one by right clicking in the list and selecting Add… Enter Tomcat Redirector as Filter name and C:\connector\isapi_redirect.dll as Executable.

Finally again select the Default Web Site and open the Handler Mappings. Right click the first entry ISAPI-dll and right click it. Select Add Module Mapping… and enter *.dll as Request Path, again C:\connector\isapi_redirect.dll as Executable and Tomcat Redirector as Name. The manager will ask you if you want to allow this ASAPI extension. As this is exactly the plan answer Yes.

Now everything is set up and should work fine. I had to restart all servers until it finally worked.

Main source of the steps described in this article was the beautiful German blog post Apache Tomcat Connector mit IIS 7 in Ralph's Blog which contains many helpful screenshots on the single steps, too.

Enable SSL on the IIS

I finally enabled SSL using a self signed certificate on the IIS.

Do do so first create a new self signed certificate. Therefore click on the root element named after your Windows server in the Connections tree view on the left in the I_nternet Information Services (IIS) Manager_. There open Server Certificates. Then click Create Self-Signed Certificate in the Actions menu on the right. Enter a name for the certificate and click OK to create it. Now enable the HTTPS binding by selecting the Default Web Site in the Connections tree view on the left and clicking Bindings… in the Action menu on the right. Click Add… and select https as Type and your newly created certificate as SSL certificate.

Now your web application is delivered using HTTP and HTTPS. You can enforce the usage of HTTPS either in your application by redirecting to the appropriate URL, by removing the binding on port 80 or in the SSL Settings of the Default Web Site.

I learned how to do so from the blog post Tip/Trick: Enabling SSL on IIS 7.0 Using Self-Signed Certificates.