Unable to push sinatra app to heroku - ruby

having trouble pushing my sinatra app to heroku based on the current setup. I have looked through all of the docs on heroku to figure this out but alas, i'm without resolution and continue to get the following error. No default language could be detected for this app.
app
--.git
-- public
-- views
- app.rb
- config.ru
- gemfile
- Gemfile.lock
- Procfile
- foo.csv
Procfile
web: bundle exec ruby app.rb -p $PORT
config.ru
require './app'
run Sinatra::Application
Gemfile
source 'https://rubygems.org'
ruby "2.4.0"
gem 'sinatra'
app.rb
require 'rubygems'
require 'sinatra'
require 'csv'
Tilt.register Tilt::ERBTemplate, 'html.erb'
set :public_folder, 'public'
get "/" do
erb :index
end
Update
Still not quite sure what the issue was here. I ended up grabbing the following sinatra/heroku shell from github, and replaced it with the assets from my app. Once I ran a bundle and pushed to heroku everything ended up working. I'm sure the issue is structurally nuanced and can be pulled from a deeper look at the working setup, for now - i'm just happy it's working.
https://github.com/runemadsen/Sinatra-Heroku-Template

Related

heroku bundler: failed to load command: rackup

I'm trying to deploy to heroku a modular sinatra app that works fine locally. This is in the heroku logs:
2020-12-28T21:05:15.907560+00:00 heroku[web.1]: Starting process with command `bundle exec rackup config.ru -p 58645`
2020-12-28T21:05:18.738254+00:00 app[web.1]: bundler: failed to load command: rackup (/app/vendor/bundle/ruby/2.7.0/bin/rackup)
2020-12-28T21:05:18.738283+00:00 app[web.1]: Gem::Exception: can't find executable rackup for gem rack. rack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?
The command bundle exec rackup config.ru -p 58645 runs fine locally.
This is my config.ru
require_relative './config/environment.rb'
use EntreeController
use UserController
run ApplicationController
and environment.rb
APP_ENV = ENV["RACK_ENV"] || "development"
ENV['SINATRA_ENV'] ||= "development"
require 'require_all'
require 'bundler/setup'
Bundler.require(:default, ENV['SINATRA_ENV'])
require_all 'app'
require_all 'app/models'
require_all 'app/helpers'
And the Procfile:
web: bundle exec rackup config.ru -p $PORT
I'll post my solution, if ever someone bumps into the same problem. I had followed the indication on the Rakefile here : https://github.com/sinatra-activerecord/sinatra-activerecord.
One solution was to entirely deleted the Rakefile when deploying to Heroku. The other solution is to put only this in the Rakefile :
require "sinatra/activerecord"
require "sinatra/activerecord/rake"
require "./app" # or whereever your app is
Switching to Bundler 2.1.4 solved the problem in my case.
For the longer run one will have to install bundler 2.1.4 and use it, but for the sake of test I just manually edited that line in Gemfile.lock:
BUNDLED WITH
2.1.4
I was using Ruby 2.7.2 and Bundler 2.2.8 — Heroku buildpack provided Bundler 2.1.4.
Funny that Heroku’s Bundler bugs list had nothing about 2.2.8.

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))

Initializing an empty sinatra application

I am trying to create an empty Sinatra application with a config.ru file. Right now the only way I know how is to initialise it with cucumber but doing that creates extra files which I don't need including step definitions etc. When I run 'gem install Sinatra' in my working directory it says:
Successfully installed sinatra-1.4.5
Parsing documentation for sinatra-1.4.5
Done installing documentation for sinatra after 0 seconds
1 gem installed
Yet there is no config.ru file.
How do I initialise a Sinatra app so I have just the config.ru?
From the sinatra documentation
first create a file called app.rb in your working directory containing the following code:
require 'sinatra'
get '/' do
'Hello world!'
end
now create a file called config.ru with the following content:
require './app'
run Sinatra::Application
now run
rackup -p4567
to run the application

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