Deploying to Heroku, Rails app - ruby-on-rails

I am trying to deploy my rails app to heroku. The app is uploaded but does not run properly for some reason. When I type
heroku run rake db:migrate
I get an error saying
ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
I am using puma for the server and I will post some of the files that might cause the problem... Please ask for anything that might cause this error!
config/database.ymi
production:
adapter: postgresql
host: localhost
encoding: unicode
database: FastOrder_production
pool: 5
username: <%= ENV['FASTORDER_DATABASE_USER'] %>
password: <%= ENV['FASTORDER_DATABASE_PASSWORD'] %>
template: template0
url: <%= ENV["DATABASE_URL"] %>
pool: ENV['RAILS_MAX_THREADS']
config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end

You should create your db first:
heroku run rake db:create
Also, check this Heroku doc about DB connections: https://devcenter.heroku.com/articles/concurrency-and-database-connections

use
production:
pool: <%= ENV["DB_POOL"] || ENV['RAILS_MAX_THREADS'] || 5 %>
Now you can set the connection pool size by setting a config variable on Heroku. For instance if you wanted to set it to 10 you could run:
$ heroku config:set DB_POOL=10
This doesn’t mean that each dyno will now have 10 open connections, but only that if a new connection is needed it will be created until a maximum of 10 have been used per Rails process.

Related

ActiveRecord::ConnectionNotEstablished - No connection pool for X

I can't make my sinatra/ruby app hosted on heroku works as desired. I fiddled with some setup trying to resolve this issue but so far no results.
ActiveRecord::ConnectionNotEstablished - No connection pool for User:
2015-06-25T14:26:11.736854+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:566:in `retrieve_connection'
2015-06-25T14:26:11.736856+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:113:in `retrieve_connection'
2015-06-25T14:26:11.736858+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:87:in `connection'
User is one of my ActiveRecords table and the app fails because I try to query it.
I use sinatra with puma backup. Here is my Procfile:
web: ruby app/my-server.rb -s puma
I was also checking how many open connections there is using:
select count(*) from pg_stat_activity where pid <> pg_backend_pid() and usename = current_user;
but its says 0 every time.
I'm hosting the app on free plan and dev plan of herokupostgres.
I also noticed that the problem occurs when there are 2 quick calls to api at short interval of time. Like there was only 1, not 5 connections available, because 1st call succeds and the second one fails. In my database.yml I setup pool to 5.
I'm on Rails 4.2.1 and Postgres 9.4
Here is my database.yml aswell:
default: &default
adapter: postgresql
encoding: utf8
pool: 5
timeout: 5000
production:
<<: *default
host: my_db_address
port: 5432
database: my_db_name
username: my_db_user_name
password: my_db_password
< test and development ommited >
Do I miss some configuration or does free heroku plan chokes on it?
Please check how your sinatra app established the connection
configure :production, :development do
db = URI.parse(ENV['DATABASE_URL'] || 'postgres://localhost/mydb')
pool = ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5
ActiveRecord::Base.establish_connection(
adapter: db.scheme == 'postgres' ? 'postgresql' : db.scheme,
host: db.host,
username: db.user,
password: db.password,
database: db.path[1..-1],
encoding: 'utf8',
pool: pool
)
end
Make sure you have proper settings for pool, also make sure you have a heroku config for DB_POOL or MAX_THREADS.
heroku config:set DB_POOL=5
or
heroku config:set MAX_THREADS=5

Capistrano Rails deployment with Nginx and Passenger: database credentials being ignored

I'm trying to deploy my first Rails 4 app on an EC2 instance with Capistrano 3. I've followed several tutorials on how to setup the web server with Nginx and Passenger on Ubuntu. I also have a RDS instance for the database with MySQL. But when I try to run cap deploy it gives me an error at the assets:precompile phase:
INFO [d5d05621] Running ~/.rbenv/bin/rbenv exec bundle exec rake assets:precompile as deploy#[EC2 PUBLIC IP]
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as deploy#[EC2 PUBLIC IP]: rake exit status: 1
rake stdout: Nothing written
rake stderr: rake aborted!
Mysql2::Error: Access denied for user 'root'#'[EC2 PRIVATE IP]' (using password: NO)
From what I understand, it's trying to connect to the database on localhost with the credentials from the development environment.
Here is what my database.yml file looks like:
development:
adapter: mysql2
encoding: utf8
pool: 5
socket: /tmp/mysql.sock
username: root
password:
database: Store_development
production:
adapter: mysql2
encoding: utf8
database: Store_production
username: <%= ENV['STORE_DATABASE_USERNAME'] %>
password: <%= ENV['STORE_DATABASE_PASSWORD'] %>
host: [RDS INSTANCE ENDPOINT]
port: 3306
pool: 5
timeout: 5000
I looked all over to search for all the places where I could specify the environment, and I ended up having something like this. In my deploy/production.rb I have:
set :stage, :production
set :rails_env, :production
I also have this in the http section of /etc/nginx/nginx.conf on my server:
passenger_app_env production;
And this in the virtual host configuration in /etc/nginx/sites-available
passenger_enabled on;
rails_env production;
And finally I have this in the .bashrc of the deploy user:
export RAILS_ENV=production
Am I missing something to make the deploy work for the production environment and connect to the RDS instance with the credentials from the database.yml file? Or is it something else?
Make sure that the STORE_DATABASE_USERNAME and STORE_DATABASE_PASSWORD environment variables are set on the server and visible to your Rails app. When you SSH into the EC2 instance and run the following do you get the expected values?
echo $STORE_DATABASE_USERNAME
echo $STORE_DATABASE_PASSWORD
If not, add exports for these to the .bashrc of the deploy user:
export STORE_DATABASE_USERNAME=< your username >
export STORE_DATABASE_PASSWORD=< your password >

Rails trying to connect to unconfgured MySQL on request

Seeing a weird problem starting a Unicorn server - bundle exec ruby unicorn_rails.rb starts okay, but when I visit a URL, it shows:
Mysql2::Error (Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2))
So it seems unicorn isn't connecting to the remote server that's configured in database.yml (as it's trying to connect locally), despite other commands, e.g. bundle exec rails console, working fine. It seems to be ignoring that setting even though the environment is set right. This was working before, but something has broken it.
I put the full stack trace here:
https://gist.github.com/mahemoff/6029630
database.yml:
staging:
adapter: mysql2
database: slide_staging
host: 192.168.1.255
port: 3306
pool: 5
username: deploy
password: <%= ENV['DB_PASS'] || "notconfiguredyet" %>
timeout: 5000
reconnect: true
It might be linked to the unicorn configuration..
Especially if you preload the app.
Do you have these lines inside?
before_fork do |server, worker|
# the following is highly recomended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
# the following is *required* for Rails + "preload_app true",
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
I finally solved this. It turns out the Rails environment was being overridden, as I'd introduced a config snippet that included a bug, using Rails.env = 'test' instead of Rails.env=='test'. I figured it out after noticing my development mode was running in test environment even though ENV['RAILS_ENV'] was correctly set to development.

Rails database.yml configuration with different sockets on dev, test and production

So I am developing locally using Rails 3.2 and mysql. My local machine is a Mac and my database.yml for development is:
development:
adapter: mysql2
database: dbname
encoding: utf8
host: localhost
port: 3306
timeout: 5000
socket: /tmp/mysql.sock
And for test it's
test:
adapter: mysql2
database: dbname
encoding: utf8
host: localhost
port: 3306
timeout: 5000
socket: /var/lib/mysql/mysql.sock
Test and production servers are on CentOS and the socket works correctly when deploying to them. However I just went to do a manual rake and got the
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
My site works, but I'm curious if I'm should be handling database.yml separately for deployment since it's somehow looking at development when I run rake?
Looked for a suggestion and didn't see the same issue, apologize in advance if I missed it.
You can specify the Rails environment when you run the Rake task.
rake db:migrate RAILS_ENV=production
I can think of three alternatives:
Change your database.yml and just don't version in the changes
Use capistrano and its shared folder to handle different database.yml
Use an environment variable i.e. ENV['TEST_SOCKET']

"rails server" using the wrong database

I recently switched a relatively new rails app from sqlite3 to Amazon RDS and configured my database.yml file to use the RDS database in the production environment only.
But now, whenever I try to do any local action on my database (e.g. rails server, rails console, rake db:migrate, etc.) it does that action to the production DB on Amazon's servers rather than my local sqlite3 DB, which is my development DB.
# database.yml
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: mysql2
host: mydb.mydbhost.us-east-1.rds.amazonaws.com
reconnect: false
database: mydb
username: myusername
password: mypassword
What am I doing wrong?
UPDATE: Here's my environment.rb file:
# environment.rb
# Load the rails application
require File.expand_path('../application', __FILE__)
# Heroku environment variables for local use
heroku_env = File.join(Rails.root, 'config', 'heroku_env.rb')
load(heroku_env) if File.exists?(heroku_env)
# Initialize the rails application
Myapp::Application.initialize!
your not using productions settings
try
rails s -e production
or
RAILS_ENV=production rails s
RAILS_ENV=production rake db:migrate
Figured out the problem after taking a day to get away from it. It's a silly mistake on my part, but I thought I'd post the solution in case someone else encounters a similar issue.
As you can see from my environment.rb file above, I have a heroku_env.rb file, which contains all of my heroku-specific environment variables on my local machine for development purposes. In that file, I declared a ENV['DATABASE_URL'] variable, which links to my Amazon RDS database. Deleting this from the file solved the problem!
Thanks to everyone who offered answers to help!

Resources