web-dev-qa-db-fra.com

Où placer les variables d'environnement lors de l'utilisation de nginx et de Passenger sur Ubuntu

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 exports 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.

26
Tyler DeWitt

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.

10
leenasn

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.

7
ybakos

(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 Sudos 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.

6
Alex North-Keys

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

5
Subhas

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" "$@"
4
Teddy

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.

2
joshaidan

Vous devriez lire cette réponse à une autre question, cela vous aidera:

https://stackoverflow.com/a/11765775/1217298

2
Gustavo Lobo

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

1
Marsio

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
1
Jeff Davenport

É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
...
}
1
rbinsztock

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.

0
rakeshpatra

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
0
Tyler DeWitt