I have a Sinatra application with WebPack, when I start my app in development I spawn a process running Webpack Dev Server and use RackProxy to serve assets from my Sinatra app.
I also have to run Webpack Dev Server when running my JS Capybara acceptance tests just when Capybara spawns the ruby server.
So far I've came up with placing the WDS start in the driver register block, but I have different drivers.
Capybara.register_driver :headless_chrome do |app|
Rack::WebpackProxy.start_server
Capybara::Selenium::Driver.new(app, browser: :chrome, args: ["headless"])
end
What is the hook to run code when Capybara server is spawned?
Capybara.server= takes the registered name of the server proc to use when starting the server, and you can register your own using Capybara.register_server. Therefore you should be able to do something like
Capybara.register_server :my_server do |app, port, host, **options|
# start whatever you need started here
do_my_stuff
Capybara.servers[:puma].call(app, port, host) # assuming you want puma as the actual server
end
Capybara.server = :my_server
Related
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"]
i am trying to debug rails app - unicorn server.
I've tried following:
1) I tried to start the server on localhost (externally, not with RubyMine) and set some break points. I can see my server when trying to "attach to process". It can attach to process but when i call some REST WebService it won't stop on this method in controller.
2) I tried to run the server from Debugger in RubyMine, the server starts, but when i call some REST WebService it won't stop on this method in controller.
How to debug the Rails App on Mac OS (localhost, unicorn)?
The Rails App ist only API. I want to debug my api calls.
Problem solved:
- i was using pow and it was redirecting to some url and not directly to localhost:3000. Once i converted the requests to use localhost:3000 instead of pow URL xxx.something.test debugger fired up.
I don't have rubymine but this worked for me:
install "pry": https://github.com/pry/pry
start unicorn on your local env:
bundle exec unicorn -c config/unicorn.rb
make sure you're listening to a valid port (in your confic/unicorn.rb):
listen 3000
add
binding.pry
in your code wherever you want a breakpoint
go to:
0.0.0.0:3000
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?
I searched the internet for a "Hello, World" type program for Webrick in Ruby, but could not find anything that worked. I found this guide on SO but for the life of me could not get it to work.
Consulting the Ruby Documentation for Webrick led me to some code snippets that got me going in the right direction. There were no easy-to-follow tutorials so I wanted to add my answer on SO.
I was using Ubuntu 14.04 without Apache or Nginx and wanted my server for a virtual host. Webrick by default does not respond to requests concurrently but for me this was a plus in addition to its small footprint. I was hoping to get it working without the Rails framework for an even lighter footprint.
To get started, I installed Ruby with the Ubuntu package manager. If you are using CentOS or another Linux distribution, you can adapt this step to your particular package manager. Also make sure port 80 is open on your web server. It's possible to get SSL with Webrick but I chose not to at this point.
sudo apt-get install ruby
Here is the script which I named myapp.rb that I am using. I placed it /var/www/myapp. Ideally, I think it should not be in document root. You should also create a special user and group just to run the script to improve security (I have not outlined those steps here)
require 'webrick'
server = WEBrick::HTTPServer.new(:Port => 80,
:SSLEnable => false,
:DocumentRoot => '/var/www/myapp',
:ServerAlias => 'myapp.example.com')
server.mount_proc '/' do |req, res|
res.body = 'Hello, world!'
end
trap 'INT' do server.shutdown end
server.start
The require statement above tells Ruby to include the Webrick classes when running the program. The second line of the script creates an instance of Webrick with the following options:
Use Port 80
Disable SSL
Set the document root to /var/www/myapp
Set the Server Alias to myapp.example.com
Of course, you'll have to configure your particular domains DNS'. The server.mount_proc is telling Ruby to serve the response, "Hello, world" at document root. I think you can specify a subdirectory there if you life. The Ruby Webrick documentation above has information on that.
The line that begins with trap means that the web server can be stopped with Ctrl-C. To start the script I typed the following at the SSH command line:
ruby myapp.rb
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.