Capistrano Net::SSH.start deprecating watning - ruby-on-rails

Just upgraded to the latest capistrano and my rails deployments are all printing this warning -
/home/vivek/.rvm/gems/ruby-2.4.1/gems/sshkit-1.14.0/lib/sshkit/backends/connection_pool.rb:59:in `call': Passing nil, or [nil] to Net::SSH.start is deprecated for keys: user
Everything seems to be working.
I upgraded from 3.5.0 to the current release (3.91.). Is there anything that needs to be changed in deploy.rb?

When declaring your servers in e.g. config/deploy/production.rb, make sure to explicitly set a username. My guess is that you don't have one specified, hence the warning.
For example:
server "example.com", user: "deploy", roles: %w[app web]
You can test that the username is being accepted by running:
$ cap production doctor:servers
Servers (1)
deploy#example.com [:app, :web]
The username for each server can also be overridden globally via :ssh_options. If you set :ssh_options, make sure those options don't include something like user: nil.
You can inspect the value of :ssh_options by running:
$ cap production doctor:variables

Related

What could cause SameSite cookie to be overriden in AWS when set by Rails?

SameSite has finally effected us and it's been a doozy for me.
First I followed this thread: https://github.com/rails/rails/pull/28297, and updated rake and my session_store to set SameSite=none, secure.
That led me to updating puma so that I could run rails locally to test it, and all was well except that our CI/CD failed because having SameSite/Secure in the test environment failed. That was fine enough that I just don't set it to run during automated tests.
So I just did this to make sure that it existed on prod and staging, but wouldn't effect dev/test:
# session_store.rb
if Rails.env.production? || Rails.env.staging?
Rails.application.config.session_store(:cookie_store, key: '_c3_session', same_site: :none, secure: true)
else
Rails.application.config.session_store(:cookie_store, key: '_c3_session')
end
But once that deployed to staging it actually stopped the cookie from coming down at all, so we could not log in.
Finally I installed this gem: https://github.com/pschinis/rails_same_site_cookie. I ran through it locally on http and https and it worked exactly as expected, so I deployed it and it made it through the tests just fine.
Once deployed, the cookie is coming down but is not coming down as SameSite=none or Secure. So I'm left to believe that somewhere somehow in our Elastic Beanstalk config is something overriding this. But no one on my team has been able to give me any direction.
puma -> 4.3.3
rails -> 5.2.6.2
rack -> 2.1.2
Any thoughts?

Rails multi env credentials with Capistrano in production environment: How to set it up?

How to set the RAILS_MASTER_KEY to production server?
i am using Capistrano to deploy (to a nginx/passenger) a rails 6 app (ruby 2.7.0). To let the production app access the credentials I am trying to provide it with the master.key
I can get the key the local env (development) master key to the shared/config folder of the server. Still, deploying the app ultimately fails.
To get there :
step 1 in the local environment, I generate a master key for the production environment and add the relevant variables. I have tried with the master key as well.
step 2 I manually add that key to the server shared/config/master.key file
I get the following response from Capistrano deploy command:
ActiveSupport::EncryptedFile::MissingKeyError: Missing encryption key to decrypt file with. Ask your team for your master key and write it to /home/deploy/tribe/releases/20200130135612/config/credentials/production.key or put it in the ENV['RAILS_MASTER_KEY'].
Assuming this might be a timing issue, I am also updating the current/config folder with the same key and receive the same response.
Obviously I do not get the master key where it should.
the Capistrano link file task is the following
append :linked_files, "config/master.key"
set :linked_files, %w{config/master.key}
namespace :deploy do
namespace :check do
before :linked_files, :set_master_key do
on roles(:app), in: :sequence, wait: 10 do
unless test("[ -f #{shared_path}/config/master.key ]")
upload! 'config/master.key', "#{shared_path}/config/master.key"
end
end
end
end
end
what I did is I added linked not just master.key but also production.key because log was complaining about production.key, not master
this is added in my deploy.rb
set :linked_files, %w{config/credentials/production.key}
now capistrano works and has no issues with secrets

How to access environment variables during Capistrano deploy?

I have my rails (4.2) app running through Passenger (5.0.28) + Apache (2.4.7) on an Ubuntu (14.02) system, ruby (2.3.0) managed with rbenv . I deploy with Capistrano (3.4.0).
All my environment variables are set in a very simple profile.d script.
#!/bin/sh
export VAR1=VAL1
export VAR2=VAL2
This works like a charm. My app ENV has all the correct variables, Secrets.yml is properly populated... everything works EXCEPT for when deploying with Capistrano over ssh.
In my deploy.rb I have the following that I think is relavant:
set :ssh_options, {
forward_agent: true,
paranoid: true,
keys: "~/.ssh/id_rsa.pub"
}
Capistrano docs being incredibly limited and ssh\server config not my strong point I can't seem to figure out why my ENV variables aren't seen by Capistrano. If I run puts ENV.inspect during the deploy flow, I get things such as "TERM_PROGRAM"=>"Apple_Terminal" and my local machine user info and whatnot. Why isn't Capistrano using the remote environment? How can I amend my configuration either server side or in my deploy script to fix this?
Thanks for the help.
First I think some clarification of terminology and Capistrano's execution model is needed.
Capistrano is a program that runs on your local machine. So ENV within Capistrano sees your local environment, not the server's. There is no way for Capistrano to "see" the remote ENV with plain Ruby code because the Ruby code that makes up Capistrano is not executing there.
What Capistrano does do is use SSH to send commands to the server to be executed there. Commands like mkdir, bundle install, and so on.
To see this illustrated, add a Capistrano task to your deployment flow that does this:
task :puts_remote_env do
on roles(:all) do
remote_env = capture("env")
puts remote_env
end
end
This will run the env command on the remote server, capture the result, and print it to your console.
I hope this makes it more clear how Capistrano works.
So, as you can see from the puts_remote_env output, the variables defined in your profile.d script are not there. Why?
It is because Capistrano is using a non-login, non-interactive SSH session. In that SSH session, your profile.d script is not being evaluated. This is explained in detail in the Capistrano FAQ: http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/
You need to find another way to set those variables other than profile.d script.
You could specify them in your Capistrano configuration itself (e.g. production.rb) like this:
set :default_env, { var1: "val1", var2: "val2" }
Capistrano will then explicitly set up that environment when it executes SSH commands.
Or you could use a tool like dotenv, which allows Rails to read variables variables from a special file instead of relying on the execution environment.
Or you could experiment with different dot file locations to see if there are some that are still evaluated even in a non-login, non-interactive session. On Ubuntu, I've had success exporting variables at the very top of ~/.bashrc.

How to set a default shell or sudo to a user in capistrano 3

I'm currently in the process of moving from Capistrano 2.x to 3.x for a rails application and running into the following issue. The general setup on the server contains a deploy user that should be the one responsible for deploying, however when a user goes to deploy, they connect to the server with their own user name.
In Capistrano 2.x, I was able to accomplish this using the default_shell option.
set :default_shell, "sudo -u deploy /bin/sh"
This does not work in Capistrano 3.x. Is there any way to either set the shell, or sudo to the deploy user in a before hook?
Things I have tried:
Setting the :default_shell option does not work as mentioned.
I tried sudo-ing to the user in a before hook. Something like sudo -s -u deploy, which works fine outside of capistrano. My user is set up for password-less sudo to the deploy user by the way. But in Capistrano it runs the command and then just hangs.
Per this SO question, it seems possible to prepend sudo -u deploy to every command, but this doesn't seem to fully work. A couple commands in, the deploy still aborts with an exception executing as my user on a Permission denied.
I can individually map some commands as SSHKit.config.command_map[:git] = 'sudo -u deploy git', but this does not seem like the best method and I do not have a list of all the commands that I would need to map.
UPDATE:
Per my third attempt, mapping all of the commands generally seems to work.
SSHKit.config.command_map = Hash.new do |hash, command|
hash[command] = "sudo -u deploy #{command}"
end
But not completely. One of the first things capistrano does is run git:check which uploads the file /tmp/git-ssh.sh. But this file gets created with my user, not the deploy user.
If you just need to change the deployment user, in capistrano 3 it's a lot easier. Assuming you have this file structure:
config
|__deploy
|__production.rb
|__staging.rb
Capfile
Then in your production.rb or staging.rb (depending on what environment you're deploying to):
set :user, 'deploy'
server 'example.com', user: fetch(:user)

Nothing happens when doing "mina setup"

I'm trying to set up Mina for deploying my Rails app. Unfortunately, when running mina setup or mina deploy, I get to the password prompt, and then nothing happens anymore.
I can manually ssh with the given user and password, so this shouldn't be a problem. But I have no idea, where mina's stuck:
josh#macbuech:~/Documents/Work/MuheimWebdesign/base (features/deployment *)$ mina deploy --verbose
base#josh.ch's password:
-----> Mina: SIGINT received.
Elapsed time: 61.00 seconds
Interestingly, yesterday it was suddenly able to connect (one of a dozen retries worded, I guess):
josh#macbuech:~/Documents/Work/MuheimWebdesign/base (features/deployment *)$ mina deploy --verbose
base#josh.ch's password:
stdin: is not a tty
jailshell: line 3: cd: /var/www/base.josh.ch: No such file or directory
! ERROR: not set up.
The path '/var/www/base.josh.ch' is not accessible on the server.
You may need to run 'mina setup' first.
! Command failed.
Failed with status 15
Then, I couldn't connect to my server anymore (neither by using mina nor plain ssh). I had to call support, and they did something that re-enabled ssh for me. Mina still doesn't work.
In config/deploy.rb, I only added set :user ... and changed :domain, :deploy_to and :repository.
set :domain, 'josh.ch'
set :user, 'base'
set :deploy_to, "/var/www/base.josh.ch"
set :repository, 'git://jmuheim/base'
set :branch, 'master'
Any idea? I'd rather not switch back to Capistrano... Thank you.
This is an old question but this is for any future Googlers that stumble across this. I had the issue described in the question, mina hanging after password entry. Looking around in the issues section of the mina git repo lead me to the fix, albeit a silly one.
In your deploy.rb file put this setting:
set :term_mode, nil
Have you tried run:
mina init
after install gem?
Can you show your deploy.rb?
I didn't have any luck with password authentication. But with public key SSH authentication, it's working fine.
HOW TO: https://www.debian-administration.org/article/530/SSH_with_authentication_key_instead_of_password

Resources