Trying to set up and get Ruby working with docker - ruby

I try to set up and get Ruby working with docker. How can I setup logging for ruby server (fatal error, warning etc.). I ran into problem where the server would crash every time I got a fatal error and I had to restart docker again. Thanks in advance. Here is the example:
Dockerfile:
CMD ["ruby", "server.rb", "-e", "production"]
server.rb
require 'sinatra'
set :server, :puma
set :bind, '0.0.0.0'
require_relative 'routes/barcode'

Related

Need config.ru to Start up a Sinatra App from within a Docker Container?

Why isn't the simple command ruby my app.rb working to boot up my Sinatra application from within a Docker container?
I have a very simple Sinatra app:
# myapp.rb
require 'sinatra'
get '/' do
'Hello world!'
end
I run this locally with ruby myapp.rb and I get the following output
== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Puma version: 5.1.1 (ruby 2.7.0-p0) ("At Your Service")
* Min threads: 0
* Max threads: 5
* Environment: development
* PID: 49242
* Listening on http://127.0.0.1:4567
* Listening on http://[::1]:4567
Use Ctrl-C to stop
Opens up on http://127.0.0.1:4567 with no issue. When moving to Dockerize the app, I create a Gemfile with Sinatra and the following Dockerfile.
FROM ruby:2.7.0
WORKDIR /code
COPY . /code
RUN bundle install
CMD ["ruby", "myapp.rb"]
Standing up the container, it seem successful (Docker Desktop is green, no terminal errors), but clicking on the suggested link http://localhost:4567/ doesn't load (sad Chrome face). Logs from within the container look like so
[2020-12-27 18:04:52] INFO WEBrick 1.6.0
[2020-12-27 18:04:52] INFO ruby 2.7.0 (2019-12-25) [x86_64-linux]
== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick
[2020-12-27 18:04:52] INFO WEBrick::HTTPServer#start: pid=1 port=4567
However, when I add the below config.ru file and change the last line of my Dockerfile to CMD ["bundle", "exec", "rackup", "--host", "0.0.0.0", "-p", "4567"], http://localhost:4567/ opens with no issue.
# config.ru
require './myapp'
run Sinatra::Application
Why are these tweaks necessary to make the app work? The logs from with the container look nearly the same.
[2020-12-27 18:01:49] INFO WEBrick 1.6.0
[2020-12-27 18:01:49] INFO ruby 2.7.0 (2019-12-25) [x86_64-linux]
[2020-12-27 18:01:49] INFO WEBrick::HTTPServer#start: pid=1 port=4567
172.17.0.1 - - [27/Dec/2020:18:02:44 +0000] "GET / HTTP/1.1" 200 12 0.0420
I'm not necessarily wondering about "best practices" here (this is a side project). I'm more just trying to understand what I might be missing about how Dockerizing apps works.
Docker commands for both cases (and I clear the images/containers between runs):
docker build --tag sinatra-img .
docker run --name sinatra-app -dp 4567:4567 sinatra-img
When you start your app with ruby myapp.rb in a Docker container, your app is listening on localhost because it is running in development mode. If your Docker server runs in a VM, you won't be able to access your app. To fix this, when you run your app in a Docker container, make sure that it is listening on 0.0.0.0: ruby myapp.rb -o 0.0.0.0
NOTE:
The following answer relates to a previous version of the question. The new question has a different answer (fixing the binding address using the -o 0.0.0.0 CLI argument).
The Sinatra framework is based on Rack and requires a Rack compatible server... either that, or it can also fallback on the WEBrick server that's included with the Ruby language bundle.
WEBrick is a decent server, but it wasn't designed for the heavier loads or the needs of an actual web application running in production.
For this reason, you SHOULD use a Rack compatible server.
However, this does not mean that you have to use the rackup CLI helper.
Some servers, like Puma, iodine and passenger include their own CLI, so you could run your application using:
CMD ["bundle", "exec", "puma", "-p", "4567"]
Type puma -h (or iodine -h) for more command line options. A server's specific CLI might offer some server specific features you don't get with backup. For example, Iodine exposes some security options through it's CLI (maximum file upload size, maximum total header length, web socket message limits, etc').
Using the server's CLI interface should be considered a better option.
In addition, although I wouldn't recommend it, some servers also provide a Ruby API that allows you start the server from a Ruby script (instead of a config.ru file). i.e., with iodine (I'm biased):
ENV['PORT'] ||= "4567"
require 'iodine' # will test the `ENV['PORT']` value
require 'sinatra'
get '/' do
'Hello world!'
end
Iodine.listen service: :http, public: './public', handler: Sinatra::Application
# Iodine.threads = 16 # or whatever.
# Iodine.workers = -2 # half the core count (negative value).
Iodine.start
I wouldn't use this approach. It tends to be more fragile and it also hardcodes both the environment and the server settings in the application.
I would just add the config.ru and use a decent server (I like iodine, but Puma is much more popular and unless you need real-time pub/sub, websockets or some specific security/performance features, popular is often safer).
EDIT (according to comment):
If what you're really looking for is to embed the command bundle exec into the Ruby script (for version control using a gemfile), you can start the script with the lines
#!/usr/bin/env ruby
require 'bundler'
Bundler.require
Or, if you don't want to use a gemfile at all (or don't require version control), you can jus start the first line with:
#!/usr/bin/env ruby
Then you can start your server directly:
CMD ["puma", "-p", "4567"]
Or, without using the server's CLI, using the example script above, run:
CMD ["my_script.rb"]

Sinatra doesn't want to say hello

What could possibly be wrong? I run this file:
require 'sinatra'
get '/' do
"Just Do It"
end
Server starts up:
== Sinatra (v2.0.0) has taken the stage on 3000 for development with backup from Thin
Thin web server (v1.7.1 codename Muffin Mode)
Maximum connections set to 1024
Listening on 127.0.0.1:3000, CTRL+C to stop
(I set the address and port because it is what I have in my vagrantfile.
However I get nothing, either in Chrome or Firefox. I've tried various config.ru's and changed the file above to an ru extension to try rackup but that hasn't worked either.
I have uninstalled and reinstalled the Mustermann and Sinatra gems and made sure I had the gems that are required in base.rb.
Any ideas?

Can't launch simple Sinatra app using rackup and jRuby (no response from web server)

I've got a Sinatra "hello world" app that I am trying to run using jRuby. It works when I run the app, but not when I run rackup. Can anyone tell me what is going on here?
Here's the app, in a file 'app.rb':
require 'rubygems'
require 'bundler/setup'
require 'sinatra'
configure do
set :bind, '0.0.0.0'
end
get '/' do
'Boo!'
end
I can run this using bundle exec ruby app.rb and it works fine:
jonea#centos7andy[~/andy/sinatra_sand_jruby]%: bundle exec ruby app.rb
[2015-01-12 10:36:06] INFO WEBrick 1.3.1
[2015-01-12 10:36:06] INFO ruby 1.9.3 (2014-12-09) [java]
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from WEBrick
[2015-01-12 10:36:06] INFO WEBrick::HTTPServer#start: pid=31654 port=4567
Here is my config.ru to call the above program:
require 'rubygems'
require 'bundler/setup'
require 'sinatra'
require './app'
run Sinatra::Application
If I run this, it appears to work, but I can't access the server using a web browser:
jonea#centos7andy[~/andy/sinatra_sand_jruby]%: bundle exec rackup -p4567
[2015-01-12 10:29:06] INFO WEBrick 1.3.1
[2015-01-12 10:29:06] INFO ruby 1.9.3 (2014-12-09) [java]
[2015-01-12 10:29:06] INFO WEBrick::HTTPServer#start: pid=31553 port=4567
I note the suspicious lack of "Sinatra has taken the stage..."
When you run the Ruby file directly (or when you add Sinatra.run! to the config.ru file) Sinatra runs its own server. In this case the call to set :bind, '0.0.0.0' will take effect. When you run through rackup this setting is ignored.
The default host that rackup listens to is localhost, so the server will only be available through the same machine, you won’t be able to access it from other machines. To access it through other machines set the --host option:
bundle exec rackup -p4567 --host 0.0.0.0
(Note the output of rackup -h for the current version says the default host is 0.0.0.0, but this is out of date and has been fixed in master.)
Well, this is hardly sufficient to explain what is going on, but I can make it work if in config.ru I replace
run Sinatra::Application
with
Sinatra::Application.run!
In fact, knowing that makes me even more confused. Some sort of bug in Rack?
#config.ru
require "./app.rb"
set :bind, '0.0.0.0'
set :port, 9292 #set your port!
Sinatra::Application.run!
try this code and type rackup
Then you can get the results you want.
I have slightly similar situation.
But the difference is that, my Jruby + Sinatra rackup app is finally starts responding.
But it takes lots of time, sometimes it starts responding 5 minutes after app start.
I found out, that after app start port is not listened for some period time.
If we make netstat -an it will not show our app port.
Actually I don't know the reason of such behavior, but I'll dig for it.

ruby sinatra remote connection

I'm trying to get hello world working remotely in sinatra:
require 'sinatra'
get '/' do
"hello world"
end
locally it works fine:
curl localhost:4567
hello world
but when I try to access it remotely, I get a 404 error.
The server is visible; I have other web applications running just fine (but not on nonstandard ports). this is a near-stock ubuntu install so there aren't any iptables rules that would block access to port 4567. Is there something I'm missing? I've had difficulty googling this.
I assume this is not firewall issue. Add bind set :bind, '0.0.0.0' something like below
#app.rb
require 'sinatra'
set :bind, '0.0.0.0'
get "/" do
"Working"
end
to run this
ruby app.rb

debugging a sinatra app with rubmine

I'm trying to debug a sinatra app using RubyMine. I am using rackup to run the app on localhost and unicorn to run it on remote host. My ruby version is 1.9.3.
I should also note that the "run debug mode icon" is grayed out. I don't know what is missing from the configuration.
What gems do I need? What else do I need to do?
update:
I have run the server process on localhost using rackup -p 9000. In order to start debugging -run rdebug-ide --port 1234 -- rackup and got this message :
Fast Debugger (ruby-debug-ide 0.4.17.beta16, ruby-debug-base 0.10.5.rc1) listens on 127.0.0.1:1234
I still don't understand how to debug using Rubymine. I have opened the browser in http://0.0.0.0:1234 and I don't get any response (it keeps loading)
I run the remote host using unicorn like so :
unicorn -c etc/fin_srv_unicorn.conf -E staging
how shold I set up remote debugging? I have tried also rack and ruby remote.
Tried connection to the remote host and running the service (using the command listed above), and then running the rdebug like so :
rdebug-ide --port 1911 -- $SCRIPT$
where for $SCRIPT$ I have tried app/main.rb staging , unicorn -E staging, unicorn -c etc/fin_srv_unicorn.conf -E staging

Resources