Passenger Rack app 'cannot infer basepath' - ruby

I have a simple config.ru file for my Sinatra app.
require 'sinatra'
require 'app'
run Sinatra::Application
However, Passenger is failing with the error no such file to load -- app. I've tried using the 1.9 method require_relative but that now causes the error cannot infer basepath.
I'm currently using the very hacky require File.join(File.dirname(__FILE__), 'app' ), which is just horrible and I don't fancy doing that every time I want to require a file.
Is there any reason why Ruby isn't acting as usual?

In ruby 1.9.2 the current directory is no more in LOAD_PATH.
So what if your LOAD_PATH and add current_directory if is not made.

Related

Sinatra app has session issues in production

I've been working on a web application in Ruby using Sinatra. While in development, I really never had a lot of issues with sessions. However, now i'm ussing passenger to actually deploy the application I have quite a lot of issues regarding that session data keeps getting 'reset'.
I've seen other stack overflow questions related to this problem but no answer has yet fixed it for me. I've tried a couple of things:
Putting 'use Rack::Session::Pool' inside config.ru as suggested here
Used Rack::Session::Pool like explained here
Tried Memcache as explained here
Tried Redis-Rack (gives me an error: Exception NoMethodError in Rack application object (undefined method `foreign_key' for nil:NilClass))
Nothing seems to be helping really... I either end up having an error or my session gets reset each request. I know that passenger probably uses multiple threads and that that is the cause for the sessions to not be working, but I cannot seem to find a solution to the problem.
Am I missing something obvious here? Any suggestions?
Gemfile
source "https://rubygems.org"
gem 'mongo', '1.8.6'
gem 'sinatra', '1.4.8'
gem 'mongo_mapper'
gem 'bson_ext'
gem 'active_model_serializers'
gem 'activemodel-serializers-xml'
gem 'sinatra-flash'
gem 'sinatra-param', require: 'sinatra/param'
gem 'rack-recaptcha2', git: 'https://github.com/nicolas-simplex/rack- recaptcha'
gem 'mail'
gem 'slugify'
gem 'biz'
gem 'bcrypt'
gem 'redis-rack'
group :development do
gem 'mailcatcher', '~> 0.6.4'
end
config.ru
It had different forms depending on if I used just Rack::Session::Pool, Memcache or Redis. This one was the one I used for redis:
require 'rubygems'
require 'sinatra'
require File.expand_path '../app.rb', __FILE__
require 'rack'
require 'rack/session/redis'
require_relative './app'
app = App.new
sessioned = use Rack::Session::Redis.new(app)
run sessioned
App.rb
require 'rubygems'
require 'bundler/setup'
require 'sinatra'
require 'slugify'
class App < Sinatra::Base
use Rack::Protection
set :bind, '0.0.0.0'
end
require_relative './config/init' # Initialize configuration files
require_relative './helpers/init' # Initialize helpers
require_relative './routes/init' # Initialize routes
require_relative './models/init' # Initialize models
require_relative './util/tokens' # Token utility
... # Some database seeding, basic setup for some data I use
TL;DR
Sinatra and Passenger together resets sessions in production, while this doesn't happen in development.
After some more researching I found the configuration option passenger_sticky_sessions. Because in my web application session storage is quite important, this works fine for me. However, the use of this is not recommended in all use cases because all the clients sends will be routed to the same originating application process.
Documentation: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_sticky_sessions
With this configuration parameter 'on' in my conf file in nginx/sites-enabled, I was able to just use the simple rack session pool:
use Rack::Session::Pool, path: '/', expire_after: 2592000

internal server error heroku

im developing a application in ruby with sinatra. evrything worked finely until i put it on heroku. heroku gives me internal server error but no error code ):
currently my workstation is a windows computer.
my log loooks like this: http://i.imgur.com/Xd3QAms.png
config.ru
require 'tilt/haml'
require 'sass/plugin/rack'
require '4c96748'
run Sinatra::Application
gemfile
source 'https://rubygems.org'
ruby '2.2.3'
gem 'sinatra', '1.1.0'
procfile
web: bundle exec rackup config.ru -p $PORT
4c96748.rb
require 'sinatra'
require 'tilt/haml'
get '/' do
haml :index
end
pleaase help me, what do i need to do?
try following in your 6c96748.rb
require 'rubygems'
require 'sinatra'
require 'haml'
get '/' do
haml :index
end
From your logfile:
LoadError - cannot load such file -- haml
There is no Haml installed on Heroku. Every dependency you need on Heroku needs to be in your Gemfile.
Add the following Line to Gemfile:
gem 'haml'
Don't forget to run bundle before commiting your changes and pushing to heroku again.
(As a sidenote, your Sinatra version is quite outdated. The current version is 1.4.6 (see https://rubygems.org/gems/sinatra))

Accessing the irb in a modular Sinatra application

I am building an application which subclasses Sinatra like so:
require 'rubygems'
require 'sinatra/base'
require 'sinatra/assetpack'
class App < Sinatra::Base
...
run!
end
How can I access irb? Options are not parsed when executing sinatra this way, how do I programmatically open an irb shell?
Just type as below (at the shell prompt):
irb -r ./my_app.rb
I'm a little confused whether you want to open an IRB session from within your app (?) or use IRB to debug your Sinatra project?
For debugging Rack-based apps (such as Sinatra), I like using the racksh gem, which "is like script/console in Rails" for Rack applications. Its main advantage over IRB is that racksh loads the entire application environment into the shell, making debugging a breeze.
From racksh's Github page: "It's purpose is to allow developer to introspect his application and/or make some initial setup. You can for example run DataMapper.auto_migrate! or make a request to /users/666 and check response details. It's mainly aimed at apps that don't have console-like component (ie. apps built with Sinatra) but all frameworks can benefit from interactive Rack stack and request introspection."
However, racksh requires your app to have a config.ru file, so you would have to re-write your app:
# in config.ru
require 'rubygems'
require 'sinatra/base'
require 'sinatra/assetpack'
require 'app.rb'
# in app.rb
class App < Sinatra::Base
...
run!
end
Then in your app folder (where config.ru resides):
$ gem install racksh # or add gem 'racksh' to your Gemfile and run bundle
$ racksh
Check this simple search interface for Microsoft's Bing using Sinatra and binger gem.
If you follow the instructions from there you will understand better.
First at all, create a Gemfile and add:
source "https://rubygems.org"
gem 'sinatra'
gem 'binger'
Then run the bundle command that will generated Gemfile.lock.
Then create a config.ru file, and add by example:
require 'rubygems'
require 'bundler'
Bundler.require
require './app.rb'
run MyApp
Your app.rb could look like this:
class MyApp < Sinatra::Base
get '/' do
#title = "Index"
erb:index
end
end
You must have a folder named views. Create index.erb and add:
< % = #title % >
Finally, run rackup.
Source: https://github.com/thinkphp/sinatra-bing
Demo: http://sinatra-bing.herokuapp.com/

Rack/Sinatra LoadError: cannot load such file

I'm trying to build an app using Sinatra, Ruby, rack, haml, pony and SendGrid, with git and RVM for deployment on Heroku. The app is a blog variant that should send out an email with commentary submitted on a form. On my local server, when the form submits I get the following error:
LoadError at /
cannot load such file -- pony
file: tools.rb location: require line: 314
BACKTRACE
(expand)
/Users/Kevin/prog/ruby/Sinatra/Noobs/noobs.rb in block in <top (required)>
require 'pony'
When run on Heroku, form submittal results in an internal server error. The 'cannot load such file' error suggests that the file is not on the gem path, but if I understand correctly, the OS disagrees:
➜ noobs git:(master) ✗ bundle show pony
/Users/Kevin/.rvm/gems/ruby-1.9.3-p194#noobs/gems/pony-1.4
➜ noobs git:(master) echo $GEM_PATH
/Users/Kevin/.rvm/gems/ruby-1.9.3-p194#noobs:/Users/Kevin/.rvm/gems/ruby-1.9.3-p194#global
Here is the code where pony is required (noobs.rb):
require 'rubygems'
require 'sinatra'
require 'haml'
require "sinatra/reloader" if development?
# ...
post '/' do
require 'pony'
Pony.mail(:from => params[:name] + "<" + params[:contact] + ">",
What do I need to do to get pony to work?
require "bundler/setup"
Will probably fix your error.
Since you are using Bundler with Sinatra you need to require Bundler for the bundled gems to work. You probably have your gems split between Bundler and your gemset. If you have Sinatra and Haml in your gemset but Pony in your Gemfile you will see a LoadError.
I write down name of the gem (pony - in my case) in Gemfile - and it starts to work.
Just open Jemfile - and write down words jem "pony" in the new line I get the following paste2.org/6hVxHXKH

Sinatra + Bundler?

I'm wondering how one can use Bundler with Sinatra. The idea is to use the gems that Bundler downloads inside the .gems folder.
Inside your Sinatra app, you just have to require the bundler setup:
require "bundler/setup"
require "sinatra"
get "/" do
"Hello world!"
end
Alternatively, if you don't want to add the additional require "bundler/setup" at the top of your app, you can instead invoke sinatra via bundle exec (e.g. bundle exec ruby myapp.rb)
This assumes that you have a Gemfile in the root of your application. It might look like this:
source "http://rubygems.org"
gem "sinatra"
This also assumes that you've already installed bundler (gem install bundler) and that you ran bundle install to install all the gem dependencies.
I believe the best way is described here on EngineYard blog:
# This makes sure the bundled gems are in our $LOAD_PATH
require File.expand_path(File.join(File.dirname(__FILE__), 'vendor', 'gems', 'environment'))
# This actually requires the bundled gems
Bundler.require_env
class MyApp < Sinatra::Base
# stuff
end
As my original answer was quite old but there seems to be still attention to this topic here's the latest version of bundler/sinatra setup which will cover most of the use case:
A minimal config.ru
require './my_sinatra_app'
run MySinatraApp
An environment env.rb file that requires all the bundled gems (also supports loading the current environment's group):
require 'bundler/setup'
APP_ENV = ENV["RACK_ENV"] || "development"
Bundler.require :default, APP_ENV.to_sym
Then your app file (requiring the environment) with your sinatra app (Sinatra::Base):
require_relative 'env'
class MyApp < Sinatra::Base
get "/" do
"hello world"
end
end
Start your development server with rackup, and Sinatra will be loaded via Bundler, your app will be accessible from http://localhost:9292.
$ rackup
or bundle exec rackup if needed
Make sure you have a Gemfile like the following one and you run the bundle command before starting the app
source "https://rubygems.org"
gem "sinatra"
gem "puma" # a better rack server than the default webrick
+1 for the guide on the bundler website, but if you have a simple app and use Sinatra's dsl at the top level, then you need to do the following:
in your Gemfile (tell bundler not require sinatra):
gem 'sinatra', :require => false
and in the app's file (explicitly require sinatra):
require 'rubygems'
require 'bundler'
Bundler.require
require 'sinatra'
get '/' do
'hello world'
end
To use bundler with a Sinatra application, you only need to do two things. First, create a Gemfile.
gem 'sinatra'
Then, set up your config.ru file to load the bundle before it loads your Sinatra app.
require 'rubygems'
require 'bundler'
Bundler.require
require './my_sinatra_app'
run MySinatraApp
Start your development server with rackup, and Sinatra will be loaded via Bundler.
rackup
source bundler docs

Resources