Last week RedisToGo was terminated on Herokum, leaving me with no choice but to find an alternative. I got a new subscription from Heroku: Heroku Redis.
Everything seems to work fine (all tasks/jobs) except things related to ActionCable.
[ActionCable] [#######] Registered connection (#########)
2022-08-17T00:40:23.213184+00:00 app[web.1]: #<Thread:0x00007e######/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.1.7/lib/action_cable/subscription_adapter/redis.rb:144 run> terminated with exception (report_on_exception is true):
2022-08-17T00:40:23.213206+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/redis-4.1.4/lib/redis/client.rb:268:in `rescue in io': Connection lost (ECONNRESET) (Redis::ConnectionError)
I spent the last few days trying all sort of trick, but nothing work.
My cable.yml file looks like:
production:
adapter: redis
url: <%= ENV['REDIS_URL'] %>
my redis.rb file looks like this:
uri = if Rails.env == 'production'
URI.parse(ENV["REDIS_URL"])
else
URI.parse("redis://localhost:6379")
end
Resque.redis = Redis.new(host: uri.host, port: uri.port, password: uri.password, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
Am I missing certain parameters that results in the error ?
I use Heroku Redis and here's what my cable.yml looks like:
development:
adapter: redis
url: redis://localhost:6379/1
channel_prefix: myapp_development
test:
adapter: redis
url: redis://localhost:6379/1
channel_prefix: myapp_test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: myapp_production
ssl_params:
verify_mode: <%= OpenSSL::SSL::VERIFY_NONE %>
If your tasks and jobs don't use Redis (if ActionCable is the only thing trying to use Redis) then your Redis might not actually be set up properly. Here's the documentation.
Check to make sure Heroku actually set a REDIS_URL env variable:
$ heroku config | grep REDIS
> REDIS_URL: redis://h:asdfqwer1234asdf#ec2-111-1-1-1.compute-1.amazonaws.com:111
Make sure your instance has a normal configuration:
https://devcenter.heroku.com/articles/heroku-redis#configuring-your-instance
Two other helpful sources:
How to solve the SSL error for Redis 6 on Heroku
ActionCable Redis adapter crashes with Heroku Redis 6
Not able to connect to RDS PostgreSQL 9.3 database from EC2 (elastic-beanstalk). Environment was created using the Elastic Beanstalk v3 CLI with PostgreSQL 9.3.5, Puma (Ruby 2.1), Rails 4.1.6. postgresql93-devel was successfully installed by yum through .ebextensions/postgres.config:
packages:
yum:
postgresql93-devel: []
SECRET_KEY_BASE has been added to Environment table through console.
Getting the following error on rake db:migrate during eb deploy:
rake aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
RDS_HOSTNAME, RDS_DATABSE, RDS_USER_NAME, RDS_PASSWORD: all verified in rails console by ssh'ing to ec2 box.
config/database.yml:
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5
production:
<<: *default
database: <%= ENV['RDS_DB_NAME'] %>
username: <%= ENV['RDS_USERNAME'] %>
password: <%= ENV['RDS_PASSWORD'] %>
hostname: <%= ENV['RDS_HOSTNAME'] %>
port: <%= ENV['RDS_PORT'] %>
Any thoughts?
It seems you have mistakenly written hostname instead of host in database.yml
I've switched away from Mongo_Mapper to Mongoid and am having trouble deploying to production, for some reason. I'm using NGINX, Rails 3.1, and Passenger. I keep getting this message, "Failed to connect to a master node at myusernamehere:27017 (Mongo::ConnectionFailure)".
defaults: &defaults
host: localhost
# slaves:
# - host: slave1.local
# port: 27018
# - host: slave2.local
# port: 27019
development:
<<: *defaults
database: s3uploadergen_development
test:
<<: *defaults
database: s3uploadergen_test
production:
host: localhost
port: 27017
database: mydbnamehere
username: myuserhere
password: mypasswordhere
I've triple-checked all settings and tried the ENV approach as well (adding the ENV variables to production.rb and calling them via the documented mongoid approach but had the same issue):
production:
host: <%= ENV['MONGOID_HOST'] %>
port: <%= ENV['MONGOID_PORT'] %>
username: <%= ENV['MONGOID_USERNAME'] %>
password: <%= ENV['MONGOID_PASSWORD'] %>
database: <%= ENV['MONGOID_DATABASE'] %>
Ideally, I want to just specify it either in production.rb or an initializer of some sort.
I'm assuming that by "documented mongoid approach" you mean setting the recommended "uri" param instead of all those different setttings. You might want to try it since it's the recommended way of doing it.
defaults: &defaults
persist_in_safe_mode: true
development:
<<: *defaults
host: localhost
database: app_development
test:
<<: *defaults
host: localhost
database: app_test
production:
<<: *defaults
uri: <%= ENV['MONGOHQ_URL'] %>
Note that I do use Heroku but I don't use the MongoHQ add on. I just use it directly, so I manually set my MONGOHQ_URL. Your uri would look something like:
mongodb://<user>:<password>#<the.db.host.com>:<port>/<database_name>
Looks to me like you can't connect to "localhost" based on the error (like maybe you need the full host name or IP or something?). Anything in your app logs?
Just make sure not to set "host" and "uri" on any of the ENV's because "host" will override the setting that is derived from the uri.
Greetings
I am trying to get Mongoid to work with my Rails app and I am getting
an error: "Mongoid::Errors::InvalidDatabase in 'Shipment bol should be
unique' Database should be a Mongo::DB, not NilClass"
I have created the mongoid.yml file in my config directory and have mongodb running as a daemon. The config file is like so:
defaults: &defaults
host: localhost
development:
<<: *defaults
database: ship-it-development
test:
<<: *defaults
database: ship-it-test
production:
<<: *defaults
host: <%= ENV['MONGOID_HOST'] %>
port: <%= ENV['MONGOID_PORT'] %>
database: <%= ENV['MONGOID_DATABASE'] %>
All of my specs fail with the above error. I am using rails 2.3.8.
Anyone have ideas?
Like explain on question : How can i generate mongoid.yml config in Rail 2.3.5?
The mongoid.yml doesn't works with Rails 2.3.x. It's load automatic only with Rails 3.
You need add an initializer with loading your file and use it to define your database.
By example you can add that in an initializer.
mongoid_conf = YAML::load_file(Rails.root.join('config/mongoid.yml'))[Rails.env]
Mongoid.configure do |config|
config.master = Mongo::Connection.new(mongoid_conf['host'],
mongoid_conf['port']).db(mongoid_conf['database'])
end
Also if your writing your own non rails script and you initialize your models first then you will get this error.
You need to configure the database before initializing the model.
I hit this when writing a gem that used mongoid internally
Test cases hit it as well so put the Mongoid.configure section in your test/helper.rb
I need to create one config option for my Rails application. It can be the same for all environments. I found that if I set it in environment.rb, it's available in my views, which is exactly what I want...
environment.rb
AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda
Works great.
However, I'm a little uneasy. Is this a good way to do it? Is there a way that's more hip?
For general application configuration that doesn't need to be stored in a database table, I like to create a config.yml file within the config directory. For your example, it might look like this:
defaults: &defaults
audiocast_uri_format: http://blablalba/blabbitybla/yadda
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
This configuration file gets loaded from a custom initializer in config/initializers:
# Rails 2
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")[RAILS_ENV]
# Rails 3+
APP_CONFIG = YAML.load_file(Rails.root.join('config/config.yml'))[Rails.env]
If you're using Rails 3, ensure you don't accidentally add a leading slash to your relative config path.
You can then retrieve the value using:
uri_format = APP_CONFIG['audiocast_uri_format']
See this Railscast for full details.
Rails 3 version of initialiser code is as follows (RAILS_ROOT & RAILS_ENV are deprecated)
APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
Also, Ruby 1.9.3 uses Psych which makes merge keys case sensitive so you'll need to change your config file to take that into account, e.g.
defaults: &DEFAULTS
audiocast_uri_format: http://blablalba/blabbitybla/yadda
development:
<<: *DEFAULTS
test:
<<: *DEFAULTS
production:
<<: *DEFAULTS
Rails >= 4.2
Just create a YAML file into config/ directory, for example: config/neo4j.yml.
Content of neo4j.yml can be somthing like below(For simplicity, I used default for all environments):
default: &default
host: localhost
port: 7474
username: neo4j
password: root
development:
<<: *default
test:
<<: *default
production:
<<: *default
in config/application.rb:
module MyApp
class Application < Rails::Application
config.neo4j = config_for(:neo4j)
end
end
Now, your custom config is accessible like below:
Rails.configuration.neo4j['host'] #=>localhost
Rails.configuration.neo4j['port'] #=>7474
More info
Rails official API document describes config_for method as:
Convenience for loading config/foo.yml for the current Rails env.
If you do not want to use a yaml file
As Rails official guide says:
You can configure your own code through the Rails configuration object with custom configuration under the config.x property.
Example
config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries = 3
config.x.super_debugger = true
These configuration points are then available through the configuration object:
Rails.configuration.x.payment_processing.schedule # => :daily
Rails.configuration.x.payment_processing.retries # => 3
Rails.configuration.x.super_debugger # => true
Rails.configuration.x.super_debugger.not_set # => nil
Official Reference for config_for method |
Official Rails Guide
Step 1: Create config/initializers/appconfig.rb
require 'ostruct'
require 'yaml'
all_config = YAML.load_file("#{Rails.root}/config/config.yml") || {}
env_config = all_config[Rails.env] || {}
AppConfig = OpenStruct.new(env_config)
Step 2: Create config/config.yml
common: &common
facebook:
key: 'asdjhasxas'
secret : 'xyz'
twitter:
key: 'asdjhasxas'
secret : 'abx'
development:
<<: *common
test:
<<: *common
production:
<<: *common
Step 3: Get constants anywhere in the code
facebook_key = AppConfig.facebook['key']
twitter_key = AppConfig.twitter['key']
I just wanted to update this for the latest cool stuff in Rails 4.2 and 5, you can now do this inside any of your config/**/*.rb files:
config.x.whatever = 42
(and that's a literal x in there, ie. the config.x. literally must be that, and then you can add whatever you want after the x)
...and this will be available in your app as:
Rails.configuration.x.whatever
See more here: http://guides.rubyonrails.org/configuring.html#custom-configuration
Just some extra info on this topic:
APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env].with_indifferent_access
".with_indifferent_access" allows you to access the values in the hash using a string key or with an equivalent symbol key.
eg.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda'
APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'
Purely a convenience thing, but I prefer to have my keys represented as symbols.
I use something similar to John for Rails 3.0/3.1, but I have erb parse the file first:
APP_CONFIG = YAML.load(ERB.new(File.new(File.expand_path('../config.yml', __FILE__)).read).result)[Rails.env]
This allows me to use ERB in my config if I need to, like reading heroku's redistogo url:
production:
<<: *default
redis: <%= ENV['REDISTOGO_URL'] %>
Rails 4
To create a custom configuration yaml and load it (and make available to your app) similar to how database_configuration.
Create your *.yml, in my case I needed a redis configuration file.
config/redis.yml
default: &default
host: localhost
port: 6379
development:
<<: *default
test:
<<: *default
production:
<<: *default
host: <%= ENV['ELASTICACHE_HOST'] %>
port: <%= ENV['ELASTICACHE_PORT'] %>
Then load the configuration
config/application.rb
module MyApp
class Application < Rails::Application
## http://guides.rubyonrails.org/configuring.html#initialization-events
config.before_initialize do
Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")
end
end
end
Access the values:
Rails.configuration.redis_configuration[Rails.env] similar to how you can have access to your database.yml by Rails.configuration.database_configuration[Rails.env]
Building on Omer Aslam's elegant solution, I decided to convert the keys into symbols. The only change is:
all_config = YAML.load_file("#{Rails.root}/config/config.yml").with_indifferent_access || {}
This allows you to then reference values by symbols as keys, e.g.
AppConfig[:twitter][:key]
This seems neater to my eyes.
(Posted as an answer as my reputation isn't high enough to comment on Omer's reply)
I like simpleconfig. It allows you to have per environment configuration.
see my response to Where is the best place to store application parameters : database, file, code...?
A variation to what you had in that it's a simple reference to another file. It sees that environment.rb isn't constantly updated and doesn't have a heap of app specific stuff in it.
Though not a specific answer to your question of 'is it the Rails way?', perhaps there'll be some discussion there about that.
I prefer accessing settings through the global application stack. I avoid excess global variables in local scope.
config/initializers/myconfig.rb
MyAppName::Application.define_singleton_method("myconfig") {YAML.load_file("#{Rails.root}/config/myconfig.yml") || {}}
And access it with.
MyAppName::Application.myconfig["yamlstuff"]
My way to load Settings before Rails initialize
Allows you to use settings in Rails initialization and configure settings per environment
# config/application.rb
Bundler.require(*Rails.groups)
mode = ENV['RAILS_ENV'] || 'development'
file = File.dirname(__FILE__).concat('/settings.yml')
Settings = YAML.load_file(file).fetch(mode)
Settings.define_singleton_method(:method_missing) {|name| self.fetch(name.to_s, nil)}
You could get settings in two ways:
Settings['email'] or Settings.email
My best way to custom config, with raise message when setting.yml is missing.
gets loaded from a custom initializer in config/initializers/custom_config.rb
setting_config = File.join(Rails.root,'config','setting.yml')
raise "#{setting_config} is missing!" unless File.exists? setting_config
config = YAML.load_file(setting_config)[Rails.env].symbolize_keys
#APP_ID = config[:app_id]
#APP_SECRET = config[:app_secret]
Create a YAML in config/setting.yml
development:
app_id: 433387212345678
app_secret: f43df96fc4f65904083b679412345678
test:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212
production:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212