Capistrano Devise.secret_key not set - ruby-on-rails

When I try to deploy with Capistrano it gets to assets:precompile and I get this message:
01:08 deploy:assets:precompile
01 ~/.rvm/bin/rvm default do bundle exec rake assets:precompile
01 rake aborted!
01 Devise.secret_key was not set. Please add the following to your Devise initializer:
01
01 config.secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
01
01 Please ensure you restarted your application after installing Devise or setting the key.
I don't want to add my secret key into devise.rb because I don't want it in version control. I am using an environment variable for secret_key_base which Devise.secret_key is supposed to fall back on. In fact, when I ssh into the server, manually navigate to the failed release and go into the rails console I find that Devise.secret_key works fine. It seems the only time it doesn't work is during the Capistrano deploy.
Edit: I can also manually run bundle exec rake assets:precompile just fine through ssh. The problem just seems to be Capistrano, but my environment variables are in /etc/environment so they should be loaded.

You need to declare the ENV variable in your capistrano production file.
Set an env variable on your computer(or the computer, or virtual machine where deploy is being called), then add the following code to your capistrano production file.
in config/deploy/production.rb
set :default_env, {
"SECRET_KEY_BASE" => ENV['PRODUCTION_SECRET_KEY'],
....
}
You should always set env variable like this when using capistrano, because sometimes depending on the way you have capistrano set up, env variables on the server will not work, you could be using a different user to deploy, or you could be using rbenv or rvm. Whatever the reason, this is the best way to set env variables when using capistrano. And you don't have to set them on the server or keep them in version control.

Reason
Capistrano use non-login, non-interactive shell modes, which doesn't load you environment variables.
When you do ssh to server, it uses login, interactive shell modes, which loads your environment variables
Solution
Use another way to set environment variables. I often use Figaro and it works with Capistrano.
To prevent sensitive information are included in Git, add config/application.yml to Capistrano's linked_files and fill correct sensitive information to <shared directory>/config/application.yml on server

Related

How Do I Fix "Missing secret_key_base for 'production' environment" Deploying With Capistrano Rails 5.2

I have to deploy a Rails API to AWS EC2.
I'm following this tutorial: https://gorails.com/deploy/ubuntu/18.04#ruby
But I'm getting stuck on:
01 $HOME/.rbenv/bin/rbenv exec rake db:migrate
01 rake aborted!
01 ArgumentError: Missing secret_key_base for 'production' environment, set this string with rails credentials:edit
when cap production deploy
How should I generate the key?
Where should I put it?
What I do I have to config to this get working?
Need details that I not finding anywhere.
Thanks in advance!
Solved by rails new app
Copying master.key and credentials.yml.enc to my app
Commiting to repo
Added this line to config/deploy.rb:
set :linked_files, %w{config/master.key}
copy manualy the key to my ec2 on path/to/app/shared/config/master.key
And this problem was solved

Can Rails avoid picking VERSION environment variable in production

I want to host a Ruby on Rails application in a server with CentOS Linux release 7.4.1708 (Core).
Every time I SSH into the server I get an environment variable VERSION with value 7 by default.
When I try to run bundle exec rake db:migrate, Version=7 is automatically being picked by Rails and I get the following error:
ActiveRecord::UnknownMigrationVersionError:
No migration with version number 7
If I manually deploy the Rails app, I can unset VERSION and run the bundle exec rake db:migrate.
But unset VERSION is not working somehow with Capistrano auto deployment.
So, I am looking for a work around to run migrate task with Capistrano.
Is there an option in Rails where we can specify migrate task not to look for VERSION environment variable in production.
If you cant change the rails behaviour you could find from where the VERSION env variable comes, use env with different users to check if that env variable exists for your specific user only or if it is global. There not exists a VERSION environment variable for CentOS 7 by default, so it must have been added manually or by configuration, check systemd services and init scripts, /etc/environment, /etc/profile.d... etc

rails 5 unable to deploy with capistrano

I went and made some changes to my database and models. now when I run:
cap production deploy
I get an error:
PG::DuplicateTable: ERROR: relation "ideas" already exists
If this were on my local computer I would just reset the db:
rails db:migrate:reset
but since I am using capistrano I don't really know what cap task would help here? If there is one?
I did attempt to use the capistrano-rails-collection gem which has a method
cap production rails:rake:db:reset
Rails 5 made changes to what you can run in a production environment. So now I get an error like this.
01 rake aborted!
01 ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
01 If you are sure you want to continue, run the same command with the environment variable:
01 DISABLE_DATABASE_ENVIRONMENT_CHECK=1
I am not clear on how I would run cap with an environment variable so either I need a way to fix the initial error from the deploy command or I need to know how to run a cap task with this environment variable set. Open to other options though.

Rake not using the same environment value as phusion passenger setting

In my vhost, I have:
<Directory /var/www/prod/myapp/myapp/public>
...
RailsEnv production
...
</Directory>
and while any code dependent on it being production is correctly running there in the app itself (ex: display the Google Analytics code if Rails.env.production?), when I run rake about from /var/www/prod/myapp/myapp, I get:
Application root /var/www/prod/myapp/myapp
Environment development
Database adapter mysql2
which means that I have to prefix any deployment related rake stuff with RAILS_ENV=production. Granted, it's all in a deployment script at this point so it doesn't matter much, but why isn't Rake aware that it's production? Shouldn't the Passenger setting be enough? And if not, how do I fix it so I won't need to specify the environment manually?
Side-note: I am running the development instance of the app on the same box, with Environment set to development in its corresponding vhost configuration.
EDIT: Phusion Passenger version 4.0.20
rake is entirely unaware of passenger's configuration. It doesn't even know that you're using passenger. Since it isn't launched by passenger, it would have to (assuming it knew you were using apache/passenger) parse the apache config files to find this out, which would get pretty complicated, especially in the presence of multiple apps.
You could set this in one of your shell's startup files, however that doesn't sound like a good idea if you have multiple environments on the same machine.
You could stick
ENV['RAILS_ENV']='production'
At the top of one of Rails' startup files - boot.rb seems to do the trick. This would make passenger's setting ineffective though, and obviously you would only want to do this on the production deploy of your script.
Personally (especially on a machine with multiple environments in action) I'd stick to typing RAILS_ENV=production.
but why isn't Rake aware that it's production?
Because rake and all rails related commands internally do this
ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development"
which means that if you didnt have RAILS_ENV or RACK_ENV environment, then it will use development environment by default.
Shouldn't the Passenger setting be enough?
NO. Passenger setting is just for making your app up/live in desire or say virtual environment. It doesn't change any system configuration.
And if not, how do I fix it so I won't need to specify the environment manually?
That's very easy. Just set environment variable. If you are using bash (normally people do) you can simple do this
echo "export RAILS_ENV=production" >> ~/.bashrc ; source ~/.bashrc
This will make your server as rails production server, so if you run rails c or rake db:migrate etc or any rails or rake command it will run in production server for all available applications.
I am running the development instance of the app on the same box, with Environment set to development in its corresponding vhost configuration.
This is a problem. If you set the above environment variable, then whenever you run any code like rake db:migrate inside this app ..that will run in production environment. To avoid this either you dont set environment variable or specify environment on every command. There is one hack available . Include this line at the top of config/boot.rb
ENV["RACK_ENV"] = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development"
Future reading : How can I make a custom environment in rails a default environment?

rails3 app ENV not being recognized as production

I set up my rails app on my linode VPS, phusion passenger is installed and working, so is mysql (I know this cause my friend currently is running 2 production apps on it with the same set up). The VPS is running Ubuntu 10.10 and I'm using apache2 with passenger.
I SFTP'd the app to the server, bundle updated, set up my virtual host and specified RailsEnv to be production and paths are all accurate.
I then restarted the server (as root) with
apachectl -k restart
tried to rake db:migrate and it didn't do anything, so I figured it was because the environment didn't get changed, which is exactly what happend. If I go into the rails console and type Rails.env it gives me development.
I have no idea why, I did everything that should set it to production? Anyone know what I may have missed? Is there somewhere in the app where I'm supposed to change something to say production environment? I thought that only had to be done in rails 2.x
Thanks in advance for any and all help.
The RailsEnv setting is only for Passenger's use. It doesn't affect the commands you type in the shell.
Use
RAILS_ENV=production rake db:migrate
and
RAILS_ENV=production rails console
Or set the RAILS_ENV environment variable in your login shell to production so that you don't have to append RAILS_ENV=production to the commands you issue:
export RAILS_ENV=production
(exact command may vary depending on which shell you use; the above works in bash)
You were on the right track; all you need to do to actually run the app in production mode is set the RailsEnv as you did, assuming you are running the app using Passenger. However, to run the database migrations you need to tell Rails what environment to run within.
The rails console command defaults to the 'development' environment by default. The same goes for running database migrations.
To run the migrations on your production environment you need to run the command as such:
RAILS_ENV=production rake db:migrate
And to run the console in production mode, you need to run the console using the command:
rails console production
If you want this variable to be set automatically, put RAILS_ENV=productionat the end of your ~/.bashrc file. (This only works with a bash terminal)
Then open a new terminal, or restart your ssh connection.

Resources