I have an app in Sinatra that accepts requests at the root and with a name using:
get '/'
'Root page'
end
get '/:name'
#Some code here
end
When hosting the application behind a reverse-proxy using a sub-directory (i.e. http://some.thing/news
points to http://localhost:4567/
), I want to have /news
to go to the get '/'
route and /news/old
to go to the get '/:name'
route.
What configuration does Sinatra need for it to know that it’s hosted within a virtual directory and not at the root of the domain? Is this even possible?
The environment within which the application is deployed uses Apache as a reverse-proxy. To re-create the scenario for a quick test, I set up nginx on my computer with:
location /news {
proxy_pass http://localhost:4567;
}
Going to /news
causes it to go to the /:name
route instead of the /
route.
2
Answers
Instead of trying to approach the problem from the framework, we can solve the problem from the reverse-proxy.
Nginx has the ability to rewrite the URL. For example:
Apache does not need any configuration apart from defining the ProxyPass directive. Here’s me entire httpd.conf file:
Absolute URLs within the HTML are not automatically re-written and may need more configuration settings.
Using the reverse proxy is a good way, as the other answer shows, but sometimes you may not have access to that, or you simply want to stay in Ruby, then you can also do this using Rack’s
config.ru
via themap
method, which you can see in the Sinatra docs:and as this helpful Sitepoint tutorial shows:
So in your case, where you want:
/news
=>get '/'
and/news/old
=>get '/:name'
Then run
rackup config.ru -p 4567
. You could even, if your code is short enough, approach the Sinatra docs’ example even more, e.g.That way you can start to organise your routes and reuse code how you like.