Capistrano and environment variables
Solution 1
You might be best looking at the difference between ENVIRONMENT VARIABLES
and SHELL VARIABLES
When you fire SSH, your app will load the SHELL variables which are defined in your .bashrc
file. These only exist for the life of the shell, and therefore, we don't use them as much as ENV
vars
You may be better putting the ENV
vars in:
/etc/environment
Like this:
export ENVIRONMENT_VAR=value
This will make the variables available throughout the system, not just in different shell sessions
Update
Have you tried
Capistrano: Can I set an environment variable for the whole cap session?
set :default_env, {
'env_var1' => 'value1',
'env_var2' => 'value2'
}
Solution 2
Although this has been answered, I'm going to leave this here in case anyone else is in the same situation I was.
Capistrano does load .bashrc
. But if you'll notice at the top of the file there is this:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
The solution was simply to put any setup above this and Capistrano works how I want.
This solution was also noted at this GitHub issue.
Solution 3
In order to debug the issue update config/deploy.rb
with a simple task:
namespace :debug do
desc 'Print ENV variables'
task :env do
on roles(:app), in: :sequence, wait: 5 do
execute :printenv
end
end
end
now run cap staging debug:env
. You should be able to see effective configuration of ENV
variables.
The order and names of files are dependent on your distribution, e.g. on Ubuntu the sourcing sequence is following:
/etc/environment
/etc/default/locale
/etc/bash.bashrc
~/.bashrc
When ~/.bashrc
contains first lines like this, any code afterwards won't be sourced:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
To understand how capistrano
loads ENV variables this chart (source) might be helpful.
Most likely the ~/.bash*
file is not loaded due to non-interactive session.
Solution 4
You need to set environment variables in the /etc/environment
file to make them available to all users and process within a system. Environment variables in the .bashrc
or .bash_profile
files are only available within a shell session and not for automatically spawned processes and services.
I made a Capistrano library (capistrano-env_config
) some time ago for managing and syncing environment variables across a cluster which works exactly by modifying the /etc/environment
file. It's easy to use and is similar to how you can set environment variables with the Heroku toolbelt. Here are some examples:
cap env:list
cap env:get[VARIABLE_NAME, VARIABLE_NAME, ...]
cap env:unset[VARIABLE_NAME, VARIABLE_NAME, ...]
cap env:set[VARIABLE_NAME=VALUE, VARIABLE_NAME=VALUE, ...]
cap env:sync
Rahul Sekhar
Updated on July 09, 2022Comments
-
Rahul Sekhar almost 2 years
I've switched to using environment variables for configuration and it works very well - except when I have to deploy or run tasks with capistrano.
Capistrano 3 seems to execute each command prefixed with
/usr/bin/env
which erases any environment variables I've set through.bashrc
.EDIT - on doing some more reasearch, this might not be the issue, the issue might be because capistrano executes as a non-login, non-interactive shell and does not load
.bashrc
or.bash_profile
. Still stuck, though.What would be the best way of making sure the environment vars are set when capistrano executes its tasks?
-
Rahul Sekhar about 10 yearsI need the variables to be set for a single user, but available to processes run. I've got
export FOO=BAR
in .bashrc and this works fine in SSH. Just not in Capistrano. -
Richard Peck about 10 yearsHmmmmmmmm - let me have a look! Thanks for reply
-
Rahul Sekhar about 10 yearsdefault_environment seems to have no effect, strangely enough. I'm running a test task that echoes a test env variable and
BASH_VERSION
.BASH_VERSION
is shown, the test variable is blank -
Richard Peck about 10 yearsIs the env var in your
/etc/environment
or.bashrc
? -
Rahul Sekhar about 10 yearsIn
.bashrc
. I need these env vars to be applied only for a one user. -
Richard Peck about 10 yearsSorry, I was just checking :) So it loads the bash_version? Did you set that specifically though?
-
Rahul Sekhar about 10 yearsNo, I didn't set that. I was just using that as a control test.
-
Richard Peck about 10 yearsOkay -
bash_version
will likely be an ENV var set in the system. You're trying to loadSHELL
vars -
Rahul Sekhar about 10 yearsAh, it seems capistrano3 uses
default_env
, notdefault_environment
(github.com/capistrano/capistrano/pull/564). And that seems to work. Less than ideal, but it'll work for me :) -
Richard Peck about 10 yearsNICE - so this sets SHELL vars when you deploy? Capistrano the most ridiculous software I've used for non-documentation
-
Rahul Sekhar about 10 yearsHahah, indeed. And yes, it prefixes each command with
VAR=VAL FOO=BAR ...
-
rolebi about 9 yearsWorks like a charm, less complicated than the above solutions.
-
ryan2johnson9 over 8 years"just use ENV variables" they say!! What a pain to put them in 3 places! If the sole reason for it is to prevent putting secrets in source control files, why not just add them to a config file that is not in source control?
-
odigity over 8 yearsI've since abandoned everything I previously built for that project and started over with entirely new and better tech: Docker, Thin, Sinatra, Sequel, and etcd. Working on a tool right now to store/retrieve production secrets to/from etcd. No more Rails, Puppet, Capistrano, SSH, env vars, and all that other clunky garbage. I'm not even done, and already the difference has been like night and day.
-
Steven Chanin almost 8 yearsThis helped me with a Rails 4.2 app and Capistrano3. Rails was looking for things like the database password and secret_key_base to be set by ENV variables ... which I had added to the end of my
bashrc
file ... but those weren't bound so everything was crashing towards the end of the deploy. -
Disha almost 8 years3. Set my env vars in /etc/init/puma.conf's "script" section. (So they exist when Puma/Rails starts.) - This did the trick for me! Thanks a ton!
-
zx1986 over 6 yearshow could I puts these in a .env file?
-
Alexander over 6 yearsThis helped me after spending hours trying to find the right solution. Thank you very much!
-
Hassan Akram almost 6 yearsI think we don't add
export
in/etc/environment
. -
Abdullah Aden over 3 yearsThanks! I have moved all my customer config to the top of .bashrc file.
-
simo about 2 years@RichardPeck putting the env var in
/etc/environment
did not work for capistrano deploy user, what could be the issue?