winton / stasis

Static sites made powerful
http://stasis.me
MIT License
677 stars 56 forks source link

Stasis Render on Heroku #33

Open mrrooijen opened 12 years ago

mrrooijen commented 12 years ago

Hi there.

I'm trying to get Stasis to render on Heroku, but am not being very successful. Whenever I run stasis . from the Heroku console, it returns this error:

NameError: uninitialized constant #<Class:0x00000002167900>::Thin::Controllers::Controller::Logging
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:23:in `<class:Controller>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:22:in `<module:Controllers>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:19:in `<module:Thin>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:3:in `_add'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis/scope/controller.rb:30:in `instance_eval'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis/scope/controller.rb:30:in `_add'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:100:in `block in initialize'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:97:in `reject!'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:97:in `initialize'
    from (irb):4:in `new'
    from (irb):4
    from /usr/local/bin/irb:12:in `<main>'

Same happens when I manually create a new Stasis object:

irb(main):004:0> s = Stasis.new(".")

NameError: uninitialized constant #<Class:0x00000002167900>::Thin::Controllers::Controller::Logging
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:23:in `<class:Controller>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:22:in `<module:Controllers>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:19:in `<module:Thin>'
    from /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:3:in `_add'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis/scope/controller.rb:30:in `instance_eval'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis/scope/controller.rb:30:in `_add'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:100:in `block in initialize'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:97:in `reject!'
    from /app/vendor/bundle/ruby/1.9.1/gems/stasis-0.1.14/lib/stasis.rb:97:in `initialize'
    from (irb):4:in `new'
    from (irb):4
    from /usr/local/bin/irb:12:in `<main>'

I do not have this issue locally and I have no idea why this is happening. Does anyone else?

Thanks!

JeanMertz commented 12 years ago

I don't think you can get stasis to work at Heroku. The problem you hare having is probably tied to the fact that heroku rewrites your logging output, but even if you could solve that, you still have to deal with the fact that Heroku has no (usable) write permission for your app. So stasis can never save the generated files.

mrrooijen commented 12 years ago

@JeanMertz I actually decided to use MiddleMan for my static website. It's very similar to stasis in some aspects. I also wrote out a little multi-file gist explaining how to get the static site to run on Heroku.

It actually is possible and Heroku does have a writable filesystem since Celadon Cedar was released months ago. Although it isn't a persistent file system, since processes are moved around, everything you write should be considered "temporary".

This however is no problem. I just tell Heroku to pre-compile the whole static website before booting the Thin app server every time a process (re)starts. I added a little Rack Middleware to serve the pre-compiled static pages afterwards. So you have to run a very small layer of Rack middleware, but it's extremely fast and static pages are cached by Heroku.

See: https://gist.github.com/1718367 (this could also work with Statis, but I keep running in to the above issues)

The key to doing all this lies mainly in using an app server like Thin, plus Rack::TryStatic plus Procfile with Celadon Cedar to customize process boot-behavior.

sorin-ionescu commented 12 years ago

A config.ru like this should allow you to use stasis-generated sites on Heroku.

use Rack::Static,
  :urls => ['/images', '/javascripts', '/stylesheets'],
  :root => Dir.pwd

run lambda { |env|
  [
    200,
    {
      'Content-Type'  => 'text/html',
      'Cache-Control' => 'public, max-age=86400'
    },
    File.open('index.html', File::RDONLY)
  ]
}