How does sinatra start the server? - sinatra

I have been trying to delve into how sinatra works, and most recently I've been trying to figure out how sinatra starts the server after processing the routes, when it is required at the top of the file. I was looking at this tutorial and they end with an example app looking like this (their version of sinatra is called nancy):
# app.rb
# run with `ruby app.rb`
require "./nancy"
get "/" do
"Hey there!"
end
Rack::Handler::WEBrick.run Nancy::Application, Port: 9292
I am wondering how you are not forced to include that last line in sinatra.

Sinatra does that by defining an at_exit callback, see main.rb
This basically says "when the ruby script is done and exits, then run the Sinatra app!"
For more information see the ruby docs for at_exit!

For serving a sinatra application you just need to execute ruby app.rb on shell.
app.rb
# install sinatra gem before everything
# by typing `gem install sinatra`
# on shell. or add sinatra to your Gemfile
# then execute bundle install
require 'sinatra'
get '/' do
"Hey there"
end
Then you'll see such output
$ ruby app.rb
Puma 2.11.3 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
== Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from Puma
The tutorial you've been appealing at is not about the actual sinatra - there author have built his/her own pseudo-sinatra. By the way, ruby also have a microframework called nancy
To run his/her pseudo-sinatra successfully, you need to follow the tutorial from beggining to end.

Related

Deploy and run a Go API server on Ubuntu/Centos

I just finished my first backend with Go using Iris framework but now I need to put it on production so I can use it in the Slack app I built.
In order to test the code locally I only run my file with go run main.go and ngrok to test with the Slack API, it's working and it's finished.
I have a droplet with Ubuntu 16.04.3 and other one with Centos 7... I was searching for something like pm2 for go, running the server and using nginx to point that port but I read that with Go it's different and I have to use something like this https://fabianlee.org/2017/05/21/golang-running-a-go-binary-as-a-systemd-service-on-ubuntu-16-04/
But that's a very long configuration for a simple server and my questions are:
Is this the usual way to config the APIs with Go?
Apart of DigitalOcean, do you recommend to use a different service to run my API?
This is really my first time with Go and I just want to learn more, I am a backend developer with Laravel and NodeJS.
You can use pm2 if you want. When you build a go project it creates a binary executable, lets say backend-server, which you can run from terminal and will start the app like this:
$ ./backend-server
If it's not executable or has permission denied issue, add the executable permission to it.
$ chmod +x backend-server
You binary should be ready to run. I like to do it with a json config file (process.json) so that I can pass extra env variables as well and don't have to type a lot in terminal.
My process.json looks something like this:
{
"apps" : [{
"name" : "backend-app",
"script" : "./backend-server",
"env": {
"DB_USER": "db_user",
"PORT": 8080
}
}]
}
Finally you can start the app using pm2 like this:
$ pm2 start process.json
More details about json config can be found in official doc
I think most people use Supervisor for this purpose, including me.
To make it very easy for you, just take a look at my Golang project, isaac-racing-server and use it as a template for yours by replacing isaac-racing-server with the name of your app. (The Supervisor files are in a subdirectory.)

Sinatra - how to match production urls with the app's urls

Consider the following simple Sinatra application:
require 'sinatra'
post '/user/login' do
# login logic...
end
When deploying the application to a production environment, the url /user/login is usually changed to something else, i.e., /nitro/nutcracker/v1/user/login. And of course, the Sinatra app will not serve this url.
To cut the unwanted prefix, I've considered using a filter (i.e., before block), and routes with regex (i.e., get /*/user/login), but surely there are better solutions?
What say you?
You can mount it with rack. On the production server, create a config.ru file, and put this inside:
require_relative 'my_app.rb'
map('/nitro/nutcracker/v1/') { run Sinatra::Application } # Or your class, if it's modular
This will prefix the entire app with /nitro/nutcracker/v1/.
Then you run the server with rackup, or your application server might have a command line argument to pass a rack config file.

How to configure Sinatra classic to use Puma

I have an old project with classic Sinatra (not modular < Sinatra::Base). How can I make it use the Puma web server instead of Thin?
The only examples on the internet I could find using Puma were with modular Sinatra.
reference: http://www.sinatrarb.com/intro.html#Modular%20vs.%20Classic%20Style
Or if you just want use rakeup you can add to your config.ru
#\ -s puma
require './yourapp'
run Sinatra::Application
Just create config.ru:
require './yourapp'
run Sinatra::Application
then run:
puma

How do I not start sinatra when Gemfile refers to it?

all, I have a client application which is a sinatra app, but that's only part of it, some other parts will do related work like download so need to spawn in a new process, this is mostly required the gem dependencies of the same client project, so I of course using some code to load in the bundler environment:
Dir.chdir(File.expand_path(File.dirname(__FILE__)))
ENV["BUNDLE_GEMFILE"] = File.expand_path("../Gemfile", __FILE__)
require 'bundler'
env = ENV['RACK_ENV'] || 'development'
Bundler.setup
Bundler.require :default, env.to_sym,
but unfornately even with no code,like
puts 3,the sinatra app will starts and listens on 4567 which is quite irritating,
I also tried modular approach to write in the file an empty class
class MyApp < Sinatra::Base;
end
but still sinatra starts on 4567, which is
quite irritating,
do I have a way not to start sinatra? Thanks.
Find out the problem,
because in Gemfile, is:
gem "sinatra",
better use
gem "sinatra", :require =>"sinatra/base"
instead.

Why do I get an error on the first request after restarting a Sinatra app with Rack and Phusion Passenger?

After I touch tmp/restart.txt and my app restarts, the first request throws an error, usually something about not finding Haml::Engine or some other gem. The second and subsequent requests all work fine. I was having this problem on Dreamhost which was running Rack 0.4.1 and Sinatra 0.3.3 but after moving to my own host and running a newer Rack (0.9.1) and Sinatra (0.9.0.4) I still see the problem.
If you don't know the exact answer but have tips on how I could track it down, please let me know.
Here's my config.ru:
require 'rubygems'
require 'sinatra'
disable :run
set :environment, :production
set :raise_errors, true
require 'app.rb'
run Sinatra::Application
I'd look into making sure you're requiring all the necessary gems. Perhaps there's something about the order you're doing it that's causing it to fail the first time. Are you requiring rubygems?
It might also help if you posted your rack configuration for the app (config.ru).
The error is caused by the Sinatra gem loading too late. This is the solution:
#config.ru
ENV['GEM_HOME'] ||= `gem env path`.strip.split(':').first
ENV['GEM_PATH'] ||= `gem env path`.strip
Gem.clear_paths
require 'application-filename-goes-here'
set :environment, :production
run Sinatra::Application