1

I use nginx, with passenger, to serve a Rails API. In preparation for our 1.0 launch, I would like to version this API using the method described in this answer.

I have a version number that is pulled from a specification, along with capistrano recipes set up to create the following directory structure:

/var/www/foamfactory.io/dev.api.foamfactory.io
  - v0
    - current (points to v0.0)
    - v0.0
      - current (points to v0.0.15)
      - v0.0.15 (this is the capistrano directory)
        - current (points to latest release under releases/)
        - releases
          - 20210308162204 (rails directory)

Now, my nginx setup was as follows, in order to rewrite, for example, dev.api.foamfactory.io/version to dev.api.foamfactory.io/current/current/current/current/current/public (I'm working on getting this basic example working before I struggle with, e.g dev.api.foamfactory.io/v0/v0.0/version.

server {
    rewrite_log on;
    server_name dev.api.foamfactory.io;
    access_log /var/log/nginx/dev.api.foamfactory.io-access.log;
    error_log /var/log/nginx/dev.api.foamfactory.io-error.log notice;

    passenger_enabled on;
    passenger_ruby /home/www-data/.rvm/rubies/default/bin/ruby;
    passenger_sticky_sessions on;
    passenger_app_env development;
    passenger_env_var SECRET_KEY_BASE redacted;

    location / {
        if ($request_method = 'GET') {
          add_header 'Access-Control-Allow-Origin' '*';
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
          add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
          add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
    }

    rewrite ^/(.*)$ /current/current/current/current/public/$1 last;
    rewrite ^/v([0-9]+)/(.*)$ /v$1/current/current/current/public/$2 last;
    rewrite ^/v([0-9]+).([0-9]+)/(.*)$ /v$1/v$1.$2/current/current/public/$3 last;
    rewrite ^/v([0-9]+).([0-9]+).([0-9]+)/(.*)$ /v$1/v$1.$2/v$1.$2.$3/current/public/$4 last;
}

I modified this first rewrite statement to be a location/ statement:

server {
    rewrite_log on;
    server_name dev.api.foamfactory.io;
    access_log /var/log/nginx/dev.api.foamfactory.io-access.log;
    error_log /var/log/nginx/dev.api.foamfactory.io-error.log notice;

    passenger_enabled on;
    passenger_ruby /home/www-data/.rvm/rubies/default/bin/ruby;
    passenger_sticky_sessions on;
    passenger_app_env development;
    passenger_env_var SECRET_KEY_BASE redacted;

    location / {
        if ($request_method = 'GET') {
          add_header 'Access-Control-Allow-Origin' '*';
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
          add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
          add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
    }

    location ~ ^/(.*)$ {
      rewrite ^/(.*)$ /current/current/current/current/public/$1 break;
      root /var/www/foamfactory.io/dev.api.foamfactory.io/current/current/current/current/public;
    }

}

I can now access the Rails app, BUT, when I try to access an endpoint (e.g. /version, as in dev.api.foamfactory.io/version, Rails reports the following error:

ActionController::RoutingError: No route matches [GET] \"/current/current/current/current/public/version\"

My suspicion is that it has something to do with the relative_url_root configuration variable inside of the Rails configuration, so inside of environments/development.rb, I modified the configuration to include:

  config.relative_url_root = '/current/current/current/current/public'

However, this did not alleviate the error.

I'm wondering if someone might be able to help me with what I need to do to get this working. I feel like I'm not even sure if it's an nginx configuration problem or a Rails configuration problem at this point.

jwir3
  • 6,019
  • 5
  • 47
  • 92

0 Answers0