To anwer my own question: Yes it is possible.
In my case, Rails is not overkill. I have a seamless integration with our Rails-based project management system. I'm mounting a Sinatra-App as a web server, using a different public url based on user session. The session is generated via unique token, so that a user can view different static projects right after another.
routes.rb:
constraints(:subdomain => /preview/) do
mount SinatraWrapper => "/"
end
Note: i'm using constrains here, to check subdomain. Every static preview is redirected to the same app, under a different subdomain.
Sinatra Wrapper:
# a super-trivial Sinatra-based webserver
# for static content
require 'sinatra/base'
class SinatraWrapper < Sinatra::Base
before '/*' do
SinatraWrapper.set_site(session[:site])
end
def self.set_site(site)
rootPath = File.expand_path("#{Rails.root}/sites/#{site}/")
set :public_folder, "#{rootPath}/current/build/"
end
configure do
set :static, true
set :static_cache_control, [:public, :no_store, :no_cache, :must_revalidate, :max_age => 0, :expires => "Fri, 01 Jan 1990 00:00:00 GMT"]
end
set_site("default")
# route to starting page (index.html)
get "/" do
redirect "/index.html"
end
# route to custom error page (404.html)
not_found do
redirect "/404.html"
end
end
Note: i'm deploying updates from static projects via capistrano right into the rails app. The build is performed remote via Middleman ( we could use any other static site generator here). Another instance checks our git repositories for updates in the "preview"-branch and run tests on it. After passing all tests, a build is performed and deployed automatically.
Here is the tricky bit, using different behaviour for two different subdomains, but same session:
# static_pages_controller.rb:
def preview
if request.subdomain == "preview" or Rails.env.development? # local dev: no subdomains
@static_page = StaticPage.find(params[:id])
session[:site] = @static_page.slug || "default" # using a sha-slug for every static project
redirect_to "/" # redirect to root. we have a valid session now.
else
# we are NOT on the preview subdomain, so we need to redirect to proper subdomain
@project = Project.find(params[:project_id])
@static_page = StaticPage.find(params[:id])
redirect_to preview_url(project_id: @project.id, id: @static_page.id, token: @static_page.slug).sub("plattform", "preview")
end
end
Note: I have projects with many many static pages. We have a preview action for every static page from the plattform. If you hit the preview action with a link from the plattform, you are redirected to the preview subdomain and your session is set. Our authentication allows us to
- send anonymous links with authentication tokens (SHA-Slugs) to a customer
- and authenticate via database
We use this system for half a year now and are very satisfied! The customer can see a preview right away. Until now, we have not encountered any serious problems, except that the caching headers must be set correctly to ensure that new content is loaded every time you reload the page. This slows down the experience, but we can always argument, that this is a preview. To be honest, most customers do not recognize the load times.
Anyway, i am not 100% sure if my implementation for "crashing" the cache is the perfect solution. Any hint would be very much appreciated. I only have problems in Chrome and Safari (very rare), where you need to reload the page several times until new content is shown.
Another interesting question is security. I think it is relatively safe. But i'm no security expert. Any concerns?
We use this platform only internally. No product, so we do not handle errors very gentle.