Deploy Rails + AngularJS on Apache

Basic Architecture

  1. Rails serve as REST API backend.
  2. AngularJS take care of routes and front-end.
  3. Apache host the web server using mod_proxy, which proxy to the default webrick server for rails.
  4. The server is RHEL 7.1, with Apache 2.4.

Rails Production Settings

1. Production key

Generate your secret key.

rake secret

Either export it to your environment variable SECRET_KEY_BASE, or put it into config/secret.yml.

production:
  secret_key_base: your_generated_key

2. Do not uglify JS

Dependency injection in angularJS might become problematic in production settings if we enable uglify JS. The real way to fix this is keep using following programming style while coding in angular.

var app = angular.module('diskInfoControllers', ['ngResource']);

app.controller('DiskInfoCtrl', ['$scope', 'Disk', '$location', function($scope, Disk, $location) {
    $scope.disks = Disk.disks.query();

    $scope.searchDisk = function(serial) {
        $location.path(serial)
    };

    $scope.editDisk = function(serial) {
        $location.path(serial + "/edit")
    }

  $scope.addDisk = function() {
    $location.path('/new')
  }
}]);

Here we fix it by disabling the uglify JS in production settings in rails.

Edit the config/environments/productions.rb.

class NoCompression
  def compress(string)
    string
  end
end

config.assets.compress = true
config.assets.js_compressor = NoCompression.new
config.assets.css_compressor = NoCompression.new

3. Asset settings

Edit the config/environments/productions.rb.

# following obsolete, consider using config.serve_static_files
config.serve_static_assets = true
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true

In application.rb.

config.assets.precompile = ['*.js', '*.css']

Apache settings

# Load modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so

<VirtualHost *:80>
  #ServerName your.servername.com
  ProxyRequests Off
  ProxyPreserveHost On

  <Proxy *>
    Order deny,allow
    Allow from all
    AuthType None
  </Proxy>

  # rails request
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/
</VirtualHost>

RHEL 7 Settings

At last, you have two choice, disable the selinux or simply allow the port.

Here I used the second one.

# Allow http port
firewall-cmd --zone=public --add-port=80/tcp --permanent
# Allow rails webrick server port
semanage port -a -p tcp -t http_port_t 3000

Done.