Passing options from Sinatra::Base to config.ru

1,833 views
Skip to first unread message

Aziz Light

unread,
Dec 10, 2010, 4:38:47 AM12/10/10
to sina...@googlegroups.com
Hi everybody,
I am new to Ruby and Sinatra and I have been creating a small Sinatra app: https://github.com/AzizLight/Wiki/
Now as I've read in the documentation, there are two ways to run the app:

- From config.ru by requiring the app and using rack's run method to run it.
- From a regular ruby file by using Sinatra's run! method.

I am more comfortable with the second method, but I noticed that the config.ru method was most widely used;
when I asked in the sinatra irc channel, I was told that to deploy the app on servers (namely Heroku) I needed
to use a config.ru file.

Now the thing that I don't understand is how to pass options (ie: the port number I want to app to run on) from
Sinatra to the server. I tried every variation of the set method I knew of with no success (for more info on my
failed attempts to achieve my goal, you can check out this stackoverflow question: http://bit.ly/emkwhI

So how should I proceed?

Aziz Light

Konstantin Haase

unread,
Dec 10, 2010, 4:47:29 AM12/10/10
to sina...@googlegroups.com
You do not pass a port number to Sinatra, since Sinatra does not start the server in that case.

Konstantin

> --
> You received this message because you are subscribed to the Google Groups "sinatrarb" group.
> To post to this group, send email to sina...@googlegroups.com.
> To unsubscribe from this group, send email to sinatrarb+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sinatrarb?hl=en.

Aziz Light

unread,
Dec 10, 2010, 4:51:16 AM12/10/10
to sina...@googlegroups.com
Ok so that means that all the options that I want to pass to the server need to be passed directly from the command line to the rackup/thin/whatever? Isn't there a convention or a way to setup server options in a config file or in a rackup file?

Konstantin Haase

unread,
Dec 10, 2010, 4:56:10 AM12/10/10
to sina...@googlegroups.com
You can do the following:

#\ -p 5678
require 'my_app'
run MyApp

Konstantin

On Dec 10, 2010, at 10:51 , Aziz Light wrote:

> Ok so that means that all the options that I want to pass to the server need to be passed directly from the command line to the rackup/thin/whatever? Isn't there a convention or a way to setup server options in a config file or in a rackup file?
>

Aziz Light

unread,
Dec 10, 2010, 5:05:17 AM12/10/10
to sina...@googlegroups.com
Interesting.

However that doesn't seem to work with thin (it works with rack). And it looks like a bit of a hack. I guess the only real option in the end is to pass cli options.
At least I know why what I was trying to do in the first place wasn't working.

Thanks for your quick answers and your patience.

Konstantin Haase

unread,
Dec 10, 2010, 5:09:32 AM12/10/10
to sina...@googlegroups.com
Same issue: Rack doesn't start the server in that case. You can use rackup to start thin: rackup -s thin. That should honor the port in the config.ru.
Also, most servers (like thin, unicorn, apache, ...) have their own config file format where you can set the port or unix socket or however you want to server your application.

Konstantin

Aziz Light

unread,
Dec 10, 2010, 5:20:55 AM12/10/10
to sina...@googlegroups.com
Ah! Again it makes sense. To be honest, I'll have to do some reading. I barely looked at the rack documentation, or the thin one.
The thing is that I didn't notice any consistency across all the config.ru files that I saw in Sinatra apps on GitHub (most of which are
listed on the "In the Wild" section of the Sinatra website). So as a beginner I am having a bit of hard time identifying the conventions
( if there is any) and/or the best/bad practices. I guess that all the reading and coding will change that in time.

Konstantin Haase

unread,
Dec 10, 2010, 5:23:58 AM12/10/10
to sina...@googlegroups.com
May I ask why you are trying to set those things in a config.ru in the first place? You can also use a config.ru without using modular style (run Sinatra::Application) and you don't have to use the config.ru for local development.

Konstantin

Aziz Light

unread,
Dec 10, 2010, 5:32:47 AM12/10/10
to sina...@googlegroups.com
> May I ask why you are trying to set those things in a config.ru in the first place?

The only reason to that is probably because I don't know any better. As I said before, "as a beginner I am having a bit of hard time identifying the conventions
( if there is any) and/or the best/bad practices". The only reason I used a config.ru file in the first place is because I read that if I wanted to extend Sinatra::Base I had to use one, and then I saw a massive amount of Sinatra apps (30-40) using a config.ru file; so in my head it was clear that this is a convention (which might or might not be true). Also the idea that I don't need to use a config.ru file for local developement didn't cross my mind before, and I thing that's what I am going to do, for now at least.

Konstantin Haase

unread,
Dec 10, 2010, 6:57:39 AM12/10/10
to sina...@googlegroups.com
You usually need a config.ru for deployment. I think the documentation situation is somewhat sucks. There is enough documentation out there (even in the readme), but there is no good overview.

Randy Fischer

unread,
Dec 10, 2010, 11:58:37 AM12/10/10
to sina...@googlegroups.com


On Fri, Dec 10, 2010 at 4:38 AM, Aziz Light <aziiz...@gmail.com> wrote:
> Now the thing that I don't understand is how to pass options (ie: the port
> number I want to app to run on) from
> Sinatra to the server.

Well, people have answered that you don't need the port number, but
for other things, I usually do something like this in the config.ru file
where I have default values for development:

ENV['TIVOLI_SERVER']  ||= 'ADSM_TEST' # our tivoli server
ENV['SILO_TEMP']      ||= '/tmp'      # filesystems restored from tape land here

in my configure section, I bridge the environment variables
so the rest of my app can get them via settings.tivoli_server
and settings.silo_root as so:

configure do
  set :tivoli_server, ENV['TIVOLI_SERVER']
  set :silo_root,     ENV['SILO_ROOT']
  ...
end

For deployment (I use apache and mod_ruby) the server's apache
configuration sets up the environment as appropriate:

<VirtualHost *:80>
   ServerName silos.example.com

   SetEnv TIVOLI_SERVER    BERNICE
   SetEnv SILO_TEMP        /var/silos

   DocumentRoot /opt/web-services/sites/silos/current/public
   <Directory /opt/web-services/sites/silos/current/public>
     AllowOverride all
     Options -MultiViews
  </Directory>
</VirtualHost>

It works fairly well for me with the division of labor we have at $workplace.

-Randy Fischer

Aziz Light

unread,
Dec 11, 2010, 6:09:09 AM12/11/10
to sina...@googlegroups.com
Thanks for sharing. I like the ideas, and I will probably use it.

pachl

unread,
Dec 13, 2010, 10:41:50 PM12/13/10
to sinatrarb
On Dec 10, 2:38 am, Aziz Light <aziiz.li...@gmail.com> wrote:
> Hi everybody,

Hi Aziz!

> I am new to Ruby and Sinatra and I have been creating a small Sinatra
> app:https://github.com/AzizLight/Wiki/

I'm new to Sinatra as well so I hope I can help.

> Now as I've read in the documentation, there are two ways to run the
> app:
>
> - From config.ru by requiring the app and using rack's run method to
> run it.
> - From a regular ruby file by using Sinatra's run! method.

These two method accomplish two different things. I use both. The
first one for production, where thin spawns multiple app processes
running on different ports. The second one for development, which
Sinatra actually instantiates a single instance of itself using thin.

I wonder if we could do away with the second one and not allow any of
these external type settings controllable by Sinatra. That may
simplify things a bit.

For development it is easy to fire up a single instance of the app by
running:

$ ruby main.rb

In fact, I don't utilze code reloading, but instead use the following:

$ while :; do ruby main.rb; done

Then before heading back to my browser after saving changes I do a
quick CTRL+C on that loop, which restarts the app in milliseconds. I
find this much more reliable and simpler than code reloaders. In fact,
I think the original code reloader was ripped from Sinatra because of
its complexity. BTW, restarting the app after changing views is not
required if page caching is not enabled.


> I am more comfortable with the second method, but I noticed that the
> config.ru method was most widely used;

Again, that's because you are seeing production examples or examples
where guys just prefer to run thin directly for development and show-
and-tell.

> Now the thing that I don't understand is how to pass options (ie: the
> port number I want to app to run on) from
> Sinatra to the server.

Sinatra actually passes the port number, etc. to thin for
instantiating itself. However, thin is used to instantiate multiple
apps. To do this, use a thin config file. There are lots of options
for thin:

$ thin -h

For production, use:

$ thin -C thin-production.yml -R config.ru start

Here is an example thin-production.yml file:

---
address: localhost
port: 3020
servers: 4
max_conns: 1024
max_persistent_conns: 512
timeout: 30
environment: production
pid: tmp/pids/thin-production.pid
log: log/thin-production.log
daemonize: true

You could use a different thin configuration file depending on your
needs or environment. For example, you probably want only one server
running in the foreground (non-daemonized) during development.

thin-production.yml above will instantiate four Sinatra apps running
at ports: 3020, 3021, 3022, 3023. Now your front-end webserver (e.g.
nginx) will proxy to these four ports. It looks like this:

nginx(80) -> thin(3020,3021,3022,3023) -> [rack -> sinatra]


> I tried every variation of the set method I knew
> of with no success (for more info on my
> failed attempts to achieve my goal, you can check out this
> stackoverflow question:http://bit.ly/emkwhI

I'm heading over to Stackoverflow...

Jamison Dance

unread,
Dec 14, 2010, 12:48:34 AM12/14/10
to sina...@googlegroups.com

In fact, I don't utilze code reloading, but instead use the following:

   $ while :; do ruby main.rb; done

I like that! I have stolen it for my own use, but will name a child after you to thank you. 

pachl

unread,
Dec 14, 2010, 3:51:17 AM12/14/10
to sinatrarb
Glad you like it! It works great for iterative development, espcially
if you're a keyboard-centric kind of guy (i.e. keyboard to flip
through windows). The only problem is that if you have syntax errors,
you will get tons of continuous output. You'll just have to hit CTRL+C
twice in rapid succession to break out of the loop or go fix and save
your code.

I was use to my web frameworks having code reloading, until I started
using Sinatra. I looked into installing a code reloader, using Racks
reloader, etc. and thought it looked like too much work and just more
code. So I started using this little "ditty" a few weeks ago when I
started using Sinatra. At least with with technique, I know my code is
fresh. I always seemed to get bit by code reloaders, especially in
Ramaze. I woudl often find that just restarting the entire app fixed
things.

This technique also forces you to write a lean, quick-starting app. My
app is about 80 routes and about 15 database models. It takes about
300 milliseconds to restart on my 2.4GHz Core2 Duo.

Aziz Light

unread,
Dec 14, 2010, 4:16:04 AM12/14/10
to sina...@googlegroups.com
There is a lot of useful info in that response, thanks a lot. You even
answered a question that I was going to ask sometime this week (about
nginx and thin). About code reloaders, I use shotgun and really like it,
and I run the application using a tiny shell script that is actually a
wrapper around the shotgun command:

#!/bin/bash

# Development
shotgun --server=thin --port=4567 config.ru

I called the shellscript `wiki` and I made it executable, so now all I need
to do to run the app is run `wiki` while in the project's directory, and it
works like a charm.

Again, thanks a lot for your answer.

Jason Rogers

unread,
Dec 14, 2010, 10:24:19 AM12/14/10
to sina...@googlegroups.com
CTRL+Z will work on most *nix shells, if not all. That pauses the
process. You can then issue a kill %1 (or whatever job number your
application happens to be).

> --
> You received this message because you are subscribed to the Google Groups "sinatrarb" group.
> To post to this group, send email to sina...@googlegroups.com.
> To unsubscribe from this group, send email to sinatrarb+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sinatrarb?hl=en.
>
>

--
Jason Rogers

"I am crucified with Christ: nevertheless I live;
yet not I, but Christ liveth in me: and the life
which I now live in the flesh I live by the faith of
the Son of God, who loved me, and gave
himself for me."
    Galatians 2:20

Reply all
Reply to author
Forward
0 new messages