I know that I can start a rails server on another port via -p option. But I'd like to setup another port per application as long as I start webrick.
Any ideas?
Regards
Felix
Append this to config/boot.rb:
require 'rails/commands/server'
module DefaultOptions
def default_options
super.merge!(Port: 3001)
end
end
Rails::Server.send(:prepend, DefaultOptions)
Note: ruby >= 2.0 required.
Quick solution: Append to Rakefile
task :server do
`bundle exec rails s -p 8080`
end
Then run rake server
Option 1:
You can launch WEBrick like so:
rails server -p 8080
Where 8080 is your port. If you like, you can throw this in a bash script for convenience.
Option 2:
You could install $ gem install foreman, and use foreman to start your production webserver (e.g. unicorn) as defined in your Procfile like so: $ foreman run web. If unicorn is your web server you can specify the port in your unicorn config file (as with most server choices). The benefit of this approach is not only can you set the port in the config, but you're using an environment which is closer to production.
If you put the default options on config/boot.rb then all command attributes for rake and rails fails (example: rake -T or rails g model user)! So, append this to bin/rails after line require_relative '../config/boot' and the code is executed only for the rails server command:
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
The bin/rails file loks like this:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
# Set default host and port to rails server
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
require 'rails/commands'
For Rails 5.1:
# config/boot.rb
# ... existing code
require 'rails/command'
require 'rails/commands/server/server_command'
Rails::Command::ServerCommand.send(:remove_const, 'DEFAULT_PORT')
Rails::Command::ServerCommand.const_set('DEFAULT_PORT', 3333)
Related
After upgrading our team's rails application to 4.2, as the release note mentioned, the default ip rails server binds to is changed to localhost from 0.0.0.0.
We develop with Vagrant, and want the development server to be accessible directly from browser on the host machine.
Instead of typing rails s -b 0.0.0.0 every time from now on, I wonder if there's any more elegant solution, so that we can still use sth as simple as rails s to start the server. Perhaps:
a config file rails s reads where I can modify the default binding ip (without using -c)
port forward with vagrant (tried but failed, see problem encountered below)
a monkey patch to rack, that changes the default binding ip
The real goal behind this is that I want the upgrade to be smooth among our team, avoiding the glitch that people will have to constantly restarting their rails server due to the missing -b 0.0.0.0 part.
I tried vagrant port forwarding, but still get Connection Refused when I visit localhost:3000 on the host machine. The two configuration lines I tried was:
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.network "forwarded_port", guest: 3000, guest_ip: '127.0.0.1', host: 3000
Didn't find any relevant instructions in the official docs. Any help will be appreciated.
I'm having the same issue here and I found today a better solution. Just append this code to your config/boot.rb and it should work with vagrant.
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
ps: Its based on: this answer
You can use foreman to run a Procfile with your custom commands:
# Procfile in Rails application root
web: bundle exec rails s -b 0.0.0.0
Now start your Rails application with:
foreman start
The good thing about foreman is that you can add other applications to the Procfile (like sidekiq, mailcatcher).
The bad thing about foreman is that you have to train your team to run foreman start instead of rails s.
Met the same problem. Found the blog Make Rails 4.2 server listens to all interfaces.
Add the following to config/boot.rb
require 'rails/commands/server'
module Rails
class Server
alias :default_options_bk :default_options
def default_options
default_options_bk.merge!(Host: '0.0.0.0')
end
end
end
For Rails 5.1.7 with Puma 3.12.1 the selected answer does not work, but I accomplished it by adding the following to my config/puma.rb file:
set_default_host '0.0.0.0' # Note: Must come BEFORE defining the port
port ENV.fetch('PORT') { 3000 }
I determined this by inspecting the dsl file. It uses instance_eval on that file, so there are probably other ways to do it, but this seemed the most reasonable to me.
If you put the default options on config/boot.rb then all command attributes for rake and rails fails (example: rake -T or rails g model user)! So, append this to bin/rails after line require_relative '../config/boot' and the code is executed only for the rails server command:
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
The bin/rails file loks like this:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
# Set default host and port to rails server
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
require 'rails/commands'
If you use docker or another tool to manage the environment variables, you can set the HOST environment variable to the IP you need to bind.
Example:
HOST=0.0.0.0
Add it to docker.env file if you use Docker or .env if you use foreman.
Here's a simpler solution that I'm using. I already like/need dotenv and puma-heroku, so if using those doesn't work for you then this might not be for you.
/config/puma.rb
plugin :heroku
Gemfile
gem 'dotenv-rails', groups: [:development, :test]
.env
PORT=8080
Now I can start both dev and production with rails s.
For Rails 5 with Puma the selected answer does not work. You may get such error: cannot load such file -- rails/commands/server
For proper solution add following to config/puma.rb:
bind 'tcp://0.0.0.0:3000'
Switch to Puma and specify port in config/puma.rb, e.g.:
port ENV.fetch("PORT") { 3000 }
Apparently it will bind to 0.0.0.0 for the specified port: https://github.com/puma/puma/issues/896
I have a rails server on a remote box (debian wheezy, ruby 2.2, rails 4.2) and the server does not respond when I try to connect to it in my local browser or curl. The request times out. However when I ssh into the box and wget localhost:3000 it gets me the root page perfectly. Any suggestions?
Rails 4.2 changed the default IP address that rails server binds to, instead of binding to 0.0.0.0 (ie. all interfaces) it binds only to localhost.
Edit
Sorry, I see now that you made no mention of production, just a remote box. So I removed that bit from above.
To get around this you can do two things, either always start with the -b option:
rails s -b 0.0.0.0
Or, there's a little trick to add that to the default, see https://stackoverflow.com/a/8998401/152786 (note that you only need to merge in the :Port and :Host options, and you can set the :Host to 0.0.0.0 if you want).
To bind the server without using command arguments you can append this to bin/rails after line require_relative '../config/boot' and the code is executed only for the rails server command:
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
The bin/rails file loks like this:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
# Set default host and port to rails server
if ARGV.first == 's' || ARGV.first == 'server'
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
end
require 'rails/commands'
My environment is Macbook OSX 10.7 Lion with Ruby 2.0 and Rails 4.
I am new to RoR. I built a website with one column database using a scaffold.
It's just a little website about weather.
I want to input degrees to database every hour.
And I found the gem clockwork, but I have no idea how to use it with my project.
I wrote clock.rb and put it in my project file and ran rails s but nothing happened.
Here is myproject/clock.rb
myproject/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
puts "Running #{job}"
every(1 hours, ''){
Mydata.create(:degree => input_data)
}
end
What should I do with it or where should I put the file?
They say that I need to use $ clockwork clock.rb, but when I run rails s, there's no way to use that...
Thanks a lot.
As stated in the official docs you need a couple of things.
setup the clock file, I've set it in app/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
case job
when 'weather.input_degree'
Mydata.create degree: input_data
# when 'some_other_task'
# ...
else
puts "Couldn't find your job!"
end
end
every(1.hour, 'weather.input_degree') # the string indicates an arbitrary job name
# every(20.seconds, 'weather.some_other_task')
end
The starting process. The key is to use something like Foreman
$ gem install foreman
Create a file named Procfile in root of your app:
web: bundle exec rails -s
clock: bundle exec clockwork app/clock.rb
# any_other_service_you_want: bash script here
start your server
$ foreman start
Add to Gemfile
gem 'clockwork'
after adding upper listed gem in gemfile, use bundle install to add this gem into project.
Example
Create a file clock.rb under /lib directory
clock.rb
require File.expand_path('../../config/boot', __FILE__)
require File.expand_path('../../config/environment', __FILE__)
require 'clockwork'
include Clockwork
module Clockwork
## Here Student is a domain class, having a method insertRecord to
## insert a record in DB
every(20.seconds, 'job Inserting Record in DB') { Student.insertRecord }
end
Command to Run the clockword
bundle exec clockwork lib/clock.rb
This code needs stay outside of handler block:
every(1.hour, ''){ Mydata.create(:degree => input_data) }
You can execute the clock like that:
bundle exec clockwork clock.rb
You can make use of Cron. Write a rake task and call the rake task from the Cron for repeating processes.
Example (Add this to cron to run the task every hour):
0 * * * * cd /home/projectdir;rake do:task
A Rails 3.2.6 application running as a 'web' Heroku process is connecting to Redis using the ENV["REDISTOGO_URL"] environment variable:
irb(main):002:0> Redis.current
=> #<Redis client v2.2.2 connected to redis://xxx.redistogo.com:1234/0 (Redis v2.4.11)>
----- /initializers/redis.rb
if Rails.env.development?
Redis.current = Redis.new
elsif Rails.env.test?
Redis.current = Redis.new
elsif Rails.env.production?
uri = URI.parse(ENV["REDISTOGO_URL"])
Redis.current = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
end
A ruby daemon 'streaming' process runs as a secondary worker:
----- Procfile
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
worker: bundle exec rake jobs:work
streaming: RAILS_ENV=production ruby bin/streaming.rb start
However, the streaming process is crashing when it calls methods in the main Rails application that connect with Redis - even though the streaming process supposed to be loading the same redis.rb initializer as the 'web' Rails application process.
----- /bin/streaming_ctl.rb
# encoding: UTF-8
require "rubygems"
require "bundler/setup"
require "daemons"
Daemons.run(File.expand_path("../streaming.rb", __FILE__))
----- /bin/streaming.rb
# encoding: UTF-8
# TODO: set rails env in init script
ENV["RAILS_ENV"] ||= "production"
# load rails environment
require File.expand_path('../../config/environment', __FILE__)
logger = ActiveSupport::BufferedLogger.new(File.expand_path("./../../log/streaming.log", __FILE__))
Streaming.start
logger.info("\nStarting streaming in #{Rails.env.to_s} mode.")
Why is the streaming process/worker using the default Redis host and port?
[streaming.1]: /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:236:in `rescue in establish_connection': Connection refused - Unable to connect to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
Switching from "Redis.current" in /initializer/redis.rb and using a "$redis" variable convention instead (as illustrated here http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html) fixed the connection problem.
The app was using redis gem version 2.2.2 at the time. It appears as though the Redis.current in this gem version won't be consistent across 'web' and 'worker' processes because Heroku runs these processes on separate threads. The documentation on the gem repo suggests that updating to gem to >= version 3 will enable Redis.current to run in multi-threaded environments:
https://github.com/redis/redis-rb/blob/master/CHANGELOG.md#300
I'm using Stalker to interact with beanstalkd on a production server. My jobs file looks like this:
gem 'stalker'
# config/jobs.rb with Rails
RAILS_ENV = ENV["RAILS_ENV"] || "development"
require File.expand_path("../environment", __FILE__)
job "mapeamento_paciente.importar" do |args|
mapeamento = Mapeamento::Paciente.find(args['id'])
importador = ImportadorPaciente.new(mapeamento)
importador.importar!
end
I'm trying to start stalker by issuing the command:
bundle exec stalk config/jobs.rb RAILS_ENV=production
But on loading the environment file, Rails tries to access the development database, instead of production, issuing an error. Does anybody knows how to solve this issue!?
Thanks!
RAILS_ENV=production bundle exec stalk config/jobs.rb