How to write a Dockerfile for deploying Sinatra app to Heroku - ruby

I'm starting a personal project to learn more about Ruby and Sinatra. My personal project is to build a simple web server with Ruby without Rails that responds with your current IP + current time (in HTML) . Then I want to write a dockerfile for the service and deploy it on Heroku.
But problems always arise when the docker image has been deployed on Heroku. I think it's because When deploying a container app on Heroku, they require that Dockerfiles are configured to intake the randomly assigned port on a dyno - exposed as the $PORT environmental variable. Even though Docker allows for the usage of EXPOSE to specify which port for an image to use, Heroku ignores those commands and goes by the port assigned to a dyno.
So How do I exactly write the dockerfile, config.ru, gemfile and ruby file for this task? Any help would be appreciated!
dockerfile:
FROM ruby:3.0.1
WORKDIR /Desktop
COPY . /Desktop
RUN bundle install
CMD ["bundle", "exec", "rackup"]
Gemfile:
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'
gem 'puma'
gem 'reel'
gem 'http'
gem 'webrick'
Config.ru:
require './test'
run Sinatra::Application
Test.rb (main ruby file):
require 'sinatra'
require 'socket'
#find final_ip
addr_infos = Socket.ip_address_list
final_ip = ''
addr_infos.each do |addr_info|
final_ip = final_ip + ' ' + addr_info.ip_address
end
#find current time
cur_time = Time.now.ctime
#set port
set :port, ENV["PORT"] || 3000
#print to html
get '/' do
'<h2> Current Time: </h2> <br>' + cur_time + '<br><br>' + '<h2> Current IP Address: </h2> <br>'+final_ip
end

Related

jekyll rss feed on heroku

I currently have a running jekyll set up on heroku and use the following procfile:
web: jekyll serve --no-watch --port $PORT --host 0.0.0.0
I think the issue is somewhere here, but my rss feed xml returns this and obviously doesn't have the domain name that I need to set links.
What is going on here?
The best way I found to handle this is to bundle jekyll inside Rack. http://rack.github.io/
You can do this by creating a config.ru and a Rake task that handles the build
Rakefile:
namespace :assets do
task :precompile do
puts `bundle exec jekyll build`
end
end
config.ru:
require 'rack/contrib/try_static'
require 'rack/contrib/not_found'
use Rack::TryStatic,
:root => "_site",
:urls => %w[/],
:try => ['index.html', '/index.html']
run Rack::NotFound.new('_site/404.html')

Sidekiq error on required ruby file

I'm trying to start my application. Is a unicorn + foreman + sinatra application.
This is my config.ru file:
require "rubygems"
require "sinatra"
Bundler.require
require File.expand_path '../twitter_module.rb', __FILE__
run TwitterModule
require File.expand_path '../lib/tweet_streamer.rb', __FILE__
require 'sidekiq/web'
run Rack::URLMap.new('/' => Sinatra::Application, '/sidekiq' => Sidekiq::Web)
this is my sidekiq.yml:
---
:pidfile: tmp/pids/sidekiq.pid
development:
:verbose: true
:logfile: log/sidekiq_development.log
and this is my Procfile:
unicorn: bundle exec unicorn -c config/unicorn.rb
sidekiq: bundle exec sidekiq -C config/sidekiq.yml -e development -r lib/workers
The problem now is that I always give this error:
2013-10-12T15:30:23Z 28234 TID-ov4rh38wo INFO: Please point sidekiq to a Rails 3/4 application or a Ruby file
2013-10-12T15:30:23Z 28234 TID-ov4rh38wo INFO: to load your worker classes with -r [DIR|FILE].
What am I missing?
Instead of specifying the lib/workers/ directory as the -r option for sidekiq, it's necessary to point it to some file which will deal with the necessary requires and setup for your workers. For example, you might have an environment.rb file in the root of your project, requiring all the workers within the lib/workers/ directory; you'd specify this with Sidekiq by using -r ./environment.rb. It might perhaps be useful to note that Sidekiq won't load your config.ru file by itself as it doesn't use Rackup; instead, you might like to extract anything necessary to an environment.rb file or similar, and require that from within config.ru.

How to mount a Sinatra app in a Padrino app?

Resque/Sidekiq come with a web frontend, which is a Sinatra app.
The way to mount this in a Rails app is to add this to routes (http://railscasts.com/episodes/366-sidekiq?view=asciicast):
mount Sidekiq::Web, at: "/sidekiq"
How do i mount this in a Padrino app?
Mapping it in config.ru like other Rack apps does not work
map '/sidekiq' do
run Sidekiq::Web
end
Padrino uses Padrino.mount which expects apps to respond to dependencies and setup_application. This hack (https://gist.github.com/1718723) allows you to mount a Sinatra application inside a Padrino application
Padrino app is a rack app and in config.ru you would see
require ::File.dirname(__FILE__) + '/config/boot.rb'
run Padrino.application
You can change this to use Rack::URLMap
require ::File.dirname(__FILE__) + '/config/boot.rb'
run Rack::URLMap.new("/sidekiq" => Sidekiq::Web.new, "/app" => Padrino.application.new)
Add gem 'sidekiq' to Gemfile
bundle install
Add following lines to config/boot.rb
Padrino.before_load do
Padrino.dependency_paths << Padrino.root('app/workers/*.rb')
end
Add following lines to config/apps.rb
require 'sidekiq/web'
Padrino.mount('Sidekiq', app_class: 'Sidekiq::Web', app_root: Sidekiq::Web.root).to('/sidekiq')
Create any worker in app/workers/
Run bundle exec sidekiq -r ./config/boot.rb

How to make Thin run on a different port?

I've a very basic test app. When I execute this command the server ignores the port I specify and runs Thin on port 4567. Why is the port I specify ignored?
$ruby xxx.rb start -p 8000
== Sinatra/1.3.3 has taken the stage on 4567 for production with backup from Thin
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
xxx.rb file
require 'Thin'
rackup_file = "config.ru"
argv = ARGV
argv << ["-R", rackup_file ] unless ARGV.include?("-R")
argv << ["-e", "production"] unless ARGV.include?("-e")
puts argv.flatten
Thin::Runner.new(argv.flatten).run!
config.ru file
require 'sinatra'
require 'sinatra/base'
class SingingRain < Sinatra::Base
get '/' do
return 'hello'
end
end
SingingRain.run!
#\ -p 8000
put this at the top of the config.ru
Your problem is with the line:
SingingRain.run!
This is Sinatra’s run method, which tells Sinatra to start its own web server which runs on port 4567 by default. This is in your config.ru file, but config.ru is just Ruby, so this line is run as if it was in any other .rb file. This is why you see Sinatra start up on that port.
When you stop this server with CTRL-C, Thin will try to continue loading the config.ru file to determine what app to run. You don’t actually specify an app in your config.ru, so you’ll see something like:
^C>> Stopping ...
== Sinatra has ended his set (crowd applauds)
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/builder.rb:129:in `to_app': missing run or map statement (RuntimeError)
from config.ru:1:in `<main>'
...
This error is simply telling you that you didn’t actually specify an app to run in your config file.
Instead of SingingRain.run!, use:
run SingingRain
run is a Rack method that specifies which app to run. You could also do run SingingRain.new – Sinatra takes steps to enable you to use just the class itself here, or an instance.
The output to this should now just be:
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:8000, CTRL+C to stop
You don’t get the == Sinatra/1.3.2 has taken the stage on 4567 for production with backup from Thin message because Sinatra isn’t running its built in server, it’s just your Thin server as you configured it.
in your config.ru add
set :port=> 8000
Also i would highly suggest using Sinatra with something like passenger+nginx which makes deploying to production a breeze. But You need not worry about this if you are going to deploy to heroku.

How to start and stop a Sinatra application using Thin on Windows?

class App < Sinatra::Base
def hello
"world"
end
end
From documentation I found that I can start the application like this:
App.run
Although this does not return the control.
How do I start the application in the background and how can I then stop it.
My environment is: Windows, Ruby 1.9.2
Use a config.ru file like Dmitry Maksimov suggested:
#config.ru
require './your_app_file'
run YourApp
And then start with rackup -D which means deamonize and therefore it runs in the background.
I wouldn't recommend this for development though. Better have a look at Shotgun
Create in the top directory of your application rackup file - config.ru - with the following content:
# config.ru
$: << File.expand_path(File.dirname(__FILE__))
require 'your app'
run Sinatra::Application
Then just run your app with the thin start

Resources