I'm deploying a Rails app that uses PostgreSQL and HSTORE.
To deploy it, I'm ussing rubber.
Everything works, except for HSTORE not being properly enabled. When the migration that contains execute("CREATE EXTENSION hstore") runs, I get the following errors:
** [out :: production.---]
** [out :: production.---] -- execute("CREATE EXTENSION hstore")
** [out :: production.---]
** [out :: production.---] rake aborted!
** [out :: production.---] An error has occurred, this and all later migrations canceled:
** [out :: production.---]
** [out :: production.---] PG::Error: ERROR: permission denied to create extension "hstore"
** [out :: production.---] HINT: Must be superuser to create this extension.
The script that creates the postgres instance has this code:
create_user_cmd = "CREATE USER #{env.db_user} WITH NOSUPERUSER CREATEDB NOCREATEROLE"
so I think the problem might be related to the NOSUPERUSER attribute being set here.
Is there any way to enable hstore using rubber while keeping most of the generated files unchanged?
The problem is that rubber creates the DB user as NOSUPERUSER. My workaround is to create tasks that run before and after capistrano's deploy:migrate that will change the user to SUPERUSER and back.
Here's the code:
namespace :rubber do
namespace :project do
before "deploy:migrate", "rubber:project:add_pg_superuser_and_enable_hstore"
after "deploy:migrate", "rubber:project:remove_pg_superuser"
task :add_pg_superuser_and_enable_hstore,
:roles => [:postgresql_master, :postgresql_slave] do
alter_user_cmd = "ALTER USER #{rubber_env.db_user} SUPERUSER"
create_hstore_cmd = "CREATE EXTENSION IF NOT EXISTS hstore;"
rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
sudo -i -u postgres psql -c "#{alter_user_cmd}"
sudo -i -u postgres psql -c "#{create_hstore_cmd}"
ENDSCRIPT
end
task :remove_pg_superuser, :roles => [:postgresql_master,
:postgresql_slave] do
alter_user_cmd = "ALTER USER #{rubber_env.db_user} NOSUPERUSER"
rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
sudo -i -u postgres psql -c "#{alter_user_cmd}"
ENDSCRIPT
end
end
end
Another option is to not have a postgres superuser involved when deploying but create a template (or use the default one) and install the extension on the template. Then when you create a database it will have the extension installed.
Good answers here and here.
Related
I'm experiencing a really strange issue where rails won't execute migrations on my machine. I'm using Rails 4.2.5, Ruby 2.3.1p112, and Postgres 9.5.3 on OS X 10.11.6.
The database creates/migrates and functions properly at Heroku and on another Mac with the same versions of everything.
If I import the database from Heroku or the other machine I get a pending migration error when running rails s, even when I'm on the same exact source version.
Running a db:schema tells me:
You have 23 pending migrations:
20160627035230 DeviseCreateUsers
20160627035442 CreatePages
20160627055031 AddHeroToPages
20160627061237 AddAdministratorToUser
20160627061943 AddNameToUser
20160628042547 CreateSchools
20160628042702 CreateLicenses
20160628042841 JoinUsersAndSchools
20160628043323 AddJoinCodeToSchools
20160630012028 AddExpiryToLicenses
20160630024743 CreatePurchases
20160630043846 AddOmniauthToUsers
20160704003626 CreateMyIndustries
20160704010403 CreateMyCareers
20160704013913 CreateMyQuestions
20160704074916 AlterMyQuestionsDrop
20160704075947 AlterMyQuestionsChange
20160705071702 CreateUserAttributes
20160710235339 CreateAccessabilities
20160711000000 AddToAccessabilities
20160711044815 CreateMedia
20160711045327 AddLocaleToMedium
20160814010549 CreateInvoices
Run `rake db:migrate` to update your database then try again.
Running the migration then tells me:
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:migrate
ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:dump
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Listing tables in psql only shows the schema_migrations:
20:09 $ rails db
psql (9.5.3)
Type "help" for help.
mytalents_development=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------------
public | schema_migrations | table | aidancornelius
(1 row)
mytalents_development=#
I also seem to get strange errors with db:migrate:up
20:11 $ rake db:migrate:up
rake aborted!
ActiveRecord::UnknownMigrationVersionError:
No migration with version number 0
/usr/local/lib/ruby/gems/2.3.0/gems/activerecord-4.2.5/lib/active_record/migration.rb:939:in `run'
/usr/local/lib/ruby/gems/2.3.0/gems/activerecord-4.2.5/lib/active_record/migration.rb:834:in `run'
/usr/local/lib/ruby/gems/2.3.0/gems/activerecord-4.2.5/lib/active_record/railties/databases.rake:82:in `block (3 levels) in <top (required)>'
/usr/local/lib/ruby/gems/2.3.0/gems/rake-11.2.2/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:migrate:up
(See full trace by running task with --trace)
Does anyone have any insight about what might be going on here? Other projects in Rails 4 and Rails 5 work on this machine, but this one just won't.
Thanks in advance for any suggestions!
I bet this is an issue with Postgres Schemas. I had similar problem, but in my case migrations were working on my local machine and not on Heroku. It was caused by different settings to schema_search_path. On my local machine it was '"$user",public' but '"$user", public'" on Heroku and this additional space was breaking everything.
In your case you need to check what is your schema_search_path on your machine. Maybe you should set it to just "public" in database.yml file. You can check it with SHOW search_path query.
The sequence of rails migration files (and migration process) is the most important part, so you can try to migrate the first migration file using:
rake db:migrate VERSION=20160627035230
then use just db:migrate or db:migrate Version=20160814010549
After update to rubber 3.1.0 and using postgres 9.3 on a 3.2.22 rails app i'm trying to deploy on Ec2 is showing this on the log:
** [out :: app01.foo.com] PG::ConnectionBad: FATAL: no pg_hba.conf entry for host "172.35.45.216", user "foo", database "foo_production", SSL on
** [out :: app01.foo.com]
** [out :: app01.foo.com] FATAL: no pg_hba.conf entry for host "172.35.45.216", user "foo", database "foo_production", SSL off
someone got the same problem?
I have installed a ubuntu 12.04 remote server with elasticsearch.
I have installed elasticsearch with:
sudo apt-get update
sudo apt-get install openjdk-7-jre-headless -y
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.20.6.deb
sudo dpkg -i elasticsearch-0.20.6.deb
sudo service elasticsearch start
I get with sudo elasticsearch status:
* ElasticSearch Server is running with pid 2483
My elasticsearch remote server is working fine:
ubuntu12#juan:~/Escritorio/myapp$ curl http:/111.111.111.111:9200
{
"ok" : true,
"status" : 200,
"name" : "Hogan, Harold \"Happy\"",
"version" : {
"number" : "0.20.6",
"snapshot_build" : false
},
"tagline" : "You Know, for Search"
}
or with my subdomain:
ubuntu12#juan:~/Escritorio/myapp$ curl http://elasticsearchserver.mydomain.com:9200
{
"ok" : true,
"status" : 200,
"name" : "Hogan, Harold \"Happy\"",
"version" : {
"number" : "0.20.6",
"snapshot_build" : false
},
"tagline" : "You Know, for Search"
}
I can restart, start and stop elasticsearhc server.
sudo service elasticsearch restart
* Stopping ElasticSearch Server [ OK ]
* Starting ElasticSearch Server [ OK ]
I have a tire.rb file in config/initializer/ folder with the next code:
if Rails.env == 'production'
Tire.configure do
url "http://elasticsearchserver.mydomain.com:9200"
end
end
This is my capistrano task to reindex:
after "deploy:finalize_update", "deploy:elasticsearch:index_classes"
namespace :deploy do
namespace :elasticsearch do
desc 'run elasticsearch indexing via tire'
task :index_classes do
run "cd #{deploy_to}/current && bundle exec rake environment tire:import CLASS=Object FORCE=true "
end
end
end
I'm using mongodb as database, so I have not make migrations before reindexing.
This is capistrano error:
2013-04-06 14:25:50 executing `deploy:elasticsearch:index_classes'
#
#
** [out :: 111.111.111.111] Skipping index creation, cannot connect to Elasticsearch
** [out :: 111.111.111.111]
** [out :: 111.111.111.111] (The original exception was: #<Errno::ECONNREFUSED: Connection refused - connect(2)>)
** [out :: 111.111.111.111]
** [out :: 111.111.111.111] [IMPORT] Deleting index 'cvs'
** [out :: 111.111.111.111]
** [out :: 111.111.111.111] rake aborted!
** [out :: 111.111.111.111] Connection refused - connect(2)
** [out :: 111.111.111.111]
#
#
I have uploaded to production server the tire.rb file and I have tried:
bundle exec rake environment tire:import CLASS=Object FORCE=true
and I get the same result:
Skipping index creation, cannot connect to Elasticsearch
(The original exception was: #<Errno::ECONNREFUSED: Connection refused - connect(2)>)
[IMPORT] Deleting index objects'
rake aborted!
Connection refused - connect(2)
What am I doing wrong? How can I fix connection between tire/rails app and my elasticsearch server?
I think you just had the syntax wrong in your config/initializers/tire.rb,
see below
Tire.configure do
url "http://localhost:9200"
#you can uncomment the next line if you want to see the elasticsearch queries in their own seperate log
#logger "#{Rails.root}/log/es.log"
end
This is the syntax that it's working fine for me inside of tire.rb file
require 'tire'
Tire.configure { url "http://myremoteserver.com:9200" }
and now it's working fine!
Thank you!
I'm new to Capistrano and having trouble debugging an error. Searching suggests this error could be an environment issue of picking up the wrong version of ruby (it's almost certainly not the referenced file as it works fine in test). Using a Capistrano task to dump the ruby version everything looks fine. Running the commands directly on the server works fine, too. I'm using rbenv on the server.
The error:
* executing `deploy:assets:precompile'
* executing "cd /home/deployer/apps/happenate/releases/20120424002545 && bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"
servers: ["happenate.com"]
[happenate.com] executing command
** [out :: happenate.com] rake aborted!
** [out :: happenate.com] /home/deployer/apps/happenate/releases/20120424002545/config/initializers/session_store.rb:3: syntax error, unexpected ':', expecting $end
** [out :: happenate.com] ...sion_store :cookie_store, key: '_happenate_session'
** [out :: happenate.com] ^
Definitely some sort of ruby environment issue. After cleaning everything up with a proper rbenv environment, the error is gone.
I was having a failed: "sh -c 'cd /var/www error. Then fixed it by adding the following in deploy.rb...
set :default_environment, {
'PATH' => "/var/lib/gems/1.9.1/bin:$PATH"
}
Now I'm getting this new error.
** [out :: ip.address] Rails Error: Unable to access log file. Please ensure that /var/www/releases/20111208152807/log/production.log exists and is chmod 0666. The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.
** [out :: ip.address] mkdir -p /var/www/releases/20111208152807/public/assets
** [out :: ip.address] mkdir -p /var/www/releases/20111208152807/public/assets
** [out :: ip.address] mkdir -p /var/www/releases/20111208152807/public/assets
** [out :: ip.address]
** [out :: ip.address] mkdir -p /var/www/releases/20111208152807/public/assets
** [out :: ip.address] mkdir -p /var/www/releases/20111208152807/public/assets
** [out :: ip.address]
** [out :: ip.address] rake aborted!
** [out :: ip.address]
** [out :: ip.address] Permission denied - /var/www/releases/20111208152807/public/assets/manifest.yml
So I checked the permissions on manifest.yml and production.log with ls -lha and yes, they're owned by root.
The capistrano deployment is being done by a linux user (not root) that owns the /var/www directory. I'm guessing it's because whatever command is creating those files is giving them root ownership.
CLARIFICATION:
I know that probably just deploying using root will fix the problem but I don't want to use root.
You should never have web application files owned by root, They should be owned by a non privileged user. While the user varies between web servers and how your web server is set up generally the user is www-data (for Apache) or nobody (for Nginx).
And to remove your error you want to run the command mentioned in the error:
chmod 0666 /var/www/releases/20111208152807/log/production.log will set the file to read write permissions for every user.
Those permissions may be a bit permissive so you can restrict them if you feel the need.