J'essayais de mettre en place un système similaire à heroku dans lequel je stockais les clés secrètes dans des variables d'environnement, puis y accédais depuis mon application Rails, comme suit:
secret = ENV['EMAIL_PASSWORD']
Je sais que heroku vous permet de faire heroku config:add EMAIL_PASSWORD=secret
, et je voulais faire quelque chose comme ça pour ma propre boîte Ubuntu exécutant nginx and Passenger.
Devrais-je ajouter ces variables en tant que export
s dans .bashrc
ou .bash_login
afin que, lors du redémarrage du système, ces variables soient automatiquement définies?
Je ne sais pas quand chacun de ces fichiers sera lu.
Vous pouvez utiliser dotenv gem qui charge le fichier .env en tant que variables d'environnement. Vous pouvez générer le fichier .env pour différents environnements, sans que cela soit nécessaire, mais ne le fassiez pas dans votre référentiel.
N'oubliez pas que nginx peut ne pas fonctionner dans le même environnement que vous et, généralement (prononcé "Apache"), nous ajoutons env-vars dans le fichier de configuration du serveur via SetEnv. Cependant, nginx ne possède pas une telle fonctionnalité ... ni n'en a besoin, je crois.
Sudo -E /usr/local/sbin/nginx
Lorsque vous exécutez nginx, vous devez être conscient de vos propres variables utilisateur.
Ou consultez la commande env
( voir ici ):
env EMAIL_PASSWORD=secret
Pour répondre à votre question, vous devriez utiliser des instructions export
dans vos fichiers de configuration Shell.
(c'est probablement une surpuissance, mais peut-être que ça va être utile)
Quelques points à garder à l'esprit:
Les variables d’environnement sont quelque peu publiques et peuvent être vues par d’autres processus aussi facilement qu’en ajoutant une option à la commande ps(1)
(comme ps e $$
en bash) ou en regardant /proc/*/environ
, bien que les deux soient limités au moins au même utilisateur (ou à la même racine) systèmes. Ne comptez pas sur leur confidentialité si vous disposez d'une autre option assez facile.
~/.bashrc
n'est pas le bon endroit pour les variables d'environnement, car elles peuvent être calculées une fois lors de la connexion dans ~/.bash_login
, ~/.bash_profile ou ~/.profile
, selon votre utilisation, et transmises à tous les shells descendants. En revanche, les actions ~/.bashrc
ont tendance à être recalculées à chaque appel du shell (sauf si explicitement désactivé).
Mettre du code bash dans le ~/.profile
peut dérouter d'autres shells descendants et des outils non-shell essayant de lire ce fichier. Par conséquent, ~/.bash_login
ou -_profile spécifiques à bash contiennent les éléments spécifiques à bash et utilisent . ~/.profile
pour les opérations plus générales. (LESS, EDITOR, VISUAL, LC_COLLATE, LS_COLORS, etc.), est plus convivial avec les autres outils.
Les variables d'environnement dans ~/.profile
doivent être dans l'ancien formulaire Bourne Shell (VAR=value ; export VAR
). Sous Linux, cela n’est généralement pas critique, mais sur d’autres Unixen, cela peut poser un gros problème quand une ancienne version de "sh" essaie de les lire.
Certaines sessions X ne liront que ~/.profile
, pas ~/.bash_login
ou les autres mentionnées ci-dessus. Certains chercheront un fichier ~/.xsession
qui devra être modifié pour avoir . $HOME/.profile
s'il ne le fait pas déjà.
Les paramètres à l'échelle du système seraient mis à la place de quelque chose comme /etc/profile.d/similar-to-heroku.sh
. Notez que le ".sh" est uniquement présent car le fichier sera utilisé avec "." ou "source" - Les scripts de shell devraient jamais avoir des extensions de nom de commande quelle que soit leur forme Unix/Linux.
Comme le fait remarquer ybakos, la plupart des variables d’environnement sont supprimées lorsqu’une Sudo
s devient racine. Des problèmes similaires apparaissent dans les crontabs, les tâches, etc. En cas de doute, l'ajout de env | sort > /tmp/envvars
ou d'un script similaire peut vraiment aider au débogage.
Sachez que dans certaines distributions, les scripts de démarrage de Shell sont tellement contournés qu'ils finissent par défier l'ordre indiqué dans la page de manuel bash (1). Chaque fois que vous trouvez un utilisateur par défaut ~/.profile
recherchant $ BASH ou $ BASH_VERSION, vous pouvez vous trouver dans l'un de ces environnements, euh ... "intéressants", et vous devrez peut-être les lire pour déterminer où va le flux de contrôle (ils devrait utiliser un ~/.bash_profile
ou ~/.bash_login
spécifique à Bash, qui inclut le plus générique ~/.profile
par référence, laissant ainsi le programme exécutable bash faire le travail au lieu de devoir écrire des vérifications $ BASH dans le code Shell).
~/.bash_profile
(ou ~/.bash_login
) peut certainement inclure . ~/.bashrc
, mais les variables d'environnement appartiennent au ~/.bash_profile
(si spécifique à bash) ou au ~/.profile
qu'il contient (si vous utilisez ce mécanisme et que vous avez des envvars pour tout le reste), comme le dit DeWitt , rappelez-vous simplement de mettre le . ~/.bashrc
APRES le . ~/.profile
du .bash_profile et d’autres variables d’environnement, afin que le login et tous les autres appels du ~/.bashrc
puissent s’appuyer sur les envvars déjà définis. Un exemple ~/.bash_profile
:
# .bash_profile
[ -r ~/.profile ] && . ~/.profile # envvars
[ -r ~/.bashrc ] && . ~/.bashrc # functions, per-tty settings, etc.
#---eof
Le [ -r ... ] && ...
fonctionne dans tous les descendants de Bourne Shell et ne provoque pas d’erreurs ou d’abandons si le fichier .profile est manquant (j’ai personnellement une configuration ~/.profile.d/*.sh
, mais cela reste un exercice entièrement facultatif).
Notez que bash ne lit que le premier fichier de ces trois qu'il trouve:
~/.bash_profile
~/.bash_login
~/.profile
... donc, une fois que vous avez celui-ci, l'utilisation des deux autres est entièrement sous le contrôle de l'utilisateur, du point de vue de bash.
Ceci est documenté dans nginx . Il supprime toutes les variables d'environnement sauf TZ
lors de l'exécution des travaux. Si vous souhaitez ajouter une variable d’environnement, ajoutez ce qui suit au top de la configuration nginx:
# The top of the configuration usually has things like:
user user-name;
pid pid-file-name;
# Add to this:
env VAR1=value1;
env VAR2=value2;
# OR simply add:
env VAR1;
# To inherit the VAR1 from whatever you set in bash
La variable export
normale ou tout ce que vous faites dans bash n'a aucune garantie de transmission à nginx, en raison de la façon dont les scripts init sont écrits (nous ne savons pas s'ils utilisent Sudo avec un environnement propre, etc.). Je préférerais donc les placer dans le fichier de configuration nginx lui-même, plutôt que de dépendre du shell pour le faire.
Modifier: lien de réparation
J'ai un script dans le dossier /usr/local/bin
qui définit des envs vars puis exécute Ruby. Je définis le chemin d'accès à Ruby dans mon fichier de configuration (Apache, pas Nginx) vers ce fichier dans /usr/local/bin
.
exemple:
#!/bin/sh
# setup env vars here
export FOO=bar
export PATH_TO_FOO=/bar/bin
export PATH=$PATH:PATH_TO_FOO
# and execute Ruby with any arguments passed to this script
exec "/usr/bin/Ruby" "$@"
Je les ai mis dans ma configuration nginx, en particulier dans la définition du serveur de l'application à l'aide de la commande passenger_env_var
:
serveur { nom_serveur www.foo.com; root /webapps/foo/public; passenger_enabled sur; passagers_env_var DATABASE_USERNAME foo_db; passagers_env_var DATABASE_PASSWORD secret; passagers_env_var SECRET_KEY_BASE the_secret_keybase; }
Cela fonctionne pour moi. Voir le dossier phusion passager docs pour plus d’informations.
Vous devriez lire cette réponse à une autre question, cela vous aidera:
J'utilise rbenv en tant que gestionnaire de version. Une bonne solution pour stocker les variables d’environnement du projet consistait à installer le plug-in rbenv-vars et à les placer dans le fichier .rbenv-vars
.
Voici un article utile:
Déploiement de variables ENV d'application avec Rbenv, Passenger et Capistrano
Pour ceux qui luttent contre cela qui utilisent RVM. Assurez-vous que votre fichier d'environnements par défaut inclut les fichiers .bashrc et .profile de votre utilisateur.
file: $rvm_path/environments/default
pour trouver le chemin, exécutez cette commande:
ls -lah `whereis rvm`/environments/default
ajoutez ces deux lignes avant la première ligne de ce fichier:
source $HOME/.bashrc
source $HOME/.profile
Édité:
Ok désolé je l'ai lu trop vite, vous pouvez vérifier comment enregistrer vos variables ENV ici:
https://help.ubuntu.com/community/EnvironmentVariables
http://www.cyberciti.biz/faq/set-environment-variable-linux/
Si vous utilisez Nginx en tant que serveur sur votre ordinateur local, vous pouvez définir votre variable env dans votre fichier de configuration nginx.
location / {
...
fastcgi_param EMAIL_PASSWORD secret; #EMAIL_PASSWORD = secret
...
}
Le meilleur endroit pour conserver les variables env pour votre projet est /etc/profile.d/YOUR_FILE.sh, Ici vous pouvez trouver la documentation qui explique en détail où conserver les variables env pour différents scénarios.
Au cas où quelqu'un aurait eu le même type de question que moi, voici un petit article sympa sur les différents fichiers .bash*
: http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html
En résumé:
Pour la plupart: .bash_profile
est lu lorsque vous vous connectez à l'ordinateur et .bashrc
est lu lorsque vous démarrez un nouveau terminal. Pour Mac OSX, .bash_profile
est lu avec chaque fenêtre de terminal que vous démarrez.
La procédure recommandée consiste donc à créer .bashrc
à partir de .bash_profile
afin que toutes les variables soient définies lorsque vous vous connectez à l'ordinateur. Ajoutez simplement ceci à .bash_profile
:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi