Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

環境変数へのRubyistsガイド

開発中および本番環境でWebアプリを効果的に管理できるようにするには、環境変数を理解する必要があります。

これは必ずしもそうではありませんでした。ほんの数年前、環境変数を使用してRailsアプリを構成している人はほとんどいませんでした。しかし、その後、Herokuが発生しました。

Herokuは、開発者に12要素のアプリアプローチを紹介しました。 12要素のアプリマニフェストでは、導入が簡単なアプリを作成するための多くのベストプラクティスを示しています。環境変数に関するセクションは特に影響力があります。

12ファクターのアプリは、構成を環境変数に格納します(多くの場合、env varsまたはenvに短縮されます)。環境変数は、コードを変更せずにデプロイ間で簡単に変更できます。設定ファイルとは異なり、誤ってコードリポジトリにチェックインされる可能性はほとんどありません。カスタム構成ファイルやJavaシステムプロパティなどの他の構成メカニズムとは異なり、これらは言語やOSに依存しない標準です。

より多くのRubyistがこれまで以上に環境変数を使用しています。しかし、多くの場合、それは貨物のようになります。これらの機能を実際に理解せずに使用しています。

この投稿では、環境変数が実際にどのように機能するか、そしておそらくもっと重要なことに、それらがどのように機能しないかを示します。また、Railsアプリで環境変数を管理するための最も一般的な方法のいくつかについても説明します。始めましょう!

注:環境変数の保護については、こちらをご覧ください。

すべてのプロセスには独自の環境変数のセットがあります

サーバーで実行するすべてのプログラムには、少なくとも1つのプロセスがあります。そのプロセスは、独自の環境変数のセットを取得します。それらを取得すると、そのプロセス以外では変更できません。

初心者が犯す理解できる間違いは、環境変数がどういうわけかサーバー全体であると考えることです。 Herokuのようなサービスでは、環境変数を設定することは、ディスク上の構成ファイルを編集することと同じように見えます。しかし、環境変数は構成ファイルのようなものではありません。

サーバーで実行するすべてのプログラムは、起動した時点で独自の環境変数のセットを取得します。

環境変数へのRubyistsガイド すべてのプロセスには独自の環境があります。

環境変数はプロセスとともに消滅します

環境変数を設定し、再起動して、それがなくなったことに気付いたことがありますか?環境変数はプロセスに属しているため、プロセスが終了するたびに、環境変数はなくなります。

これは、1つのIRBセッションで環境変数を設定し、それを閉じて、2番目のirbセッションで変数にアクセスしようとすることで確認できます。

環境変数へのRubyistsガイド プロセスがシャットダウンすると、その環境変数は失われます

これは、サーバーの再起動時、またはシェルの終了時に環境変数を失う原因となるプリンシパルと同じです。それらをセッション間で保持する場合は、.bashrcなどの何らかの構成ファイルに保存する必要があります。 。

プロセスはその親から環境変数を取得します

すべてのプロセスには親があります。これは、すべてのプログラムを他のプログラムで開始する必要があるためです。

bashシェルを使用してvimを起動する場合、vimの親はシェルです。 Railsアプリがimagemagickを使用して画像を識別する場合、identifyの親 プログラムがRailsアプリになります。

環境変数へのRubyistsガイド 子プロセスは親からenv変数を継承します

以下の例では、IRBプロセスで$MARCO環境変数の値を設定しています。次に、バックティックを使用して、その変数の値をシェルアウトしてエコーします。

IRBは先ほど作成したシェルの親プロセスであるため、$MARCO環境変数のコピーを取得します。

環境変数へのRubyistsガイド Rubyで設定された環境変数は子プロセスに継承されます

親は子供に送信される環境変数をカスタマイズできます

デフォルトでは、子は親が持つすべての環境変数のコピーを取得します。ただし、これは親が制御できます。

コマンドラインから、envプログラムを使用できます。また、bashには、親に設定せずに子にenv変数を設定するための特別な構文があります。

環境変数へのRubyistsガイド envコマンドを使用して、親に設定せずに子の環境変数を設定します

Rubyの内部からシェルアウトしている場合は、ENVハッシュを散らかすことなく、カスタム環境変数を子プロセスに提供することもできます。 systemで次の構文を使用するだけです 方法:

環境変数へのRubyistsガイド カスタム環境変数をRubyのシステムメソッドに渡す方法

子供は親の環境変数を設定できません

子供はコピーしか受け取れないので 親の環境変数のうち、子が行った変更は親に影響を与えません。

環境変数へのRubyistsガイド 環境変数は「参照」ではなく「値で渡される」

ここでは、バックティック構文を使用してシェルアウトし、環境変数を設定しようとします。変数は子に設定されますが、新しい値は親にバブルアップしません。

環境変数へのRubyistsガイド 子プロセスは親の環境変数を変更できません

環境への変更は実行中のプロセス間で同期されません

以下の例では、IRBの2つのコピーを並べて実行しています。 1つのIRBセッションの環境に変数を追加しても、他のIRBセッションには影響しません。

環境変数へのRubyistsガイド 1つのプロセスに環境変数を追加しても、他のプロセスの環境変数は変更されません

シェルは環境変数システムのUIにすぎません。

システム自体はOSカーネルの一部です。つまり、シェルには環境変数に対する魔法の力がありません。実行する他のすべてのプログラムと同じルールに従う必要があります。

環境変数はシェル変数と同じではありません

最大の誤解の1つは、シェルが独自の「ローカル」シェル変数システムを提供するために発生します。ローカル変数を使用するための構文は、多くの場合、環境変数の場合と同じです。そして、初心者はしばしば2つを混同します。

ただし、ローカル変数は子にコピーされません。

環境変数へのRubyistsガイド 環境変数はシェル変数と同じではありません

例を見てみましょう。まず、MARCOという名前のローカルシェル変数を設定します。これはローカル変数であるため、子プロセスにはコピーされません。そのため、Rubyで印刷しようとすると、機能しません。

次に、exportコマンドを使用して、ローカル変数を環境変数に変換します。これで、このシェルが作成するすべての新しいプロセスにコピーされます。これで、Rubyで環境変数を使用できるようになりました。

環境変数へのRubyistsガイド ローカル変数は子プロセスでは使用できません。エクスポートは、ローカル変数を環境変数に変換します。

実践における環境変数の管理

これはすべて現実の世界でどのように機能しますか?例を見てみましょう:

1台のコンピューターで2つのRailsアプリを実行しているとします。 Honeybadgerを使用して、これらのアプリの例外を監視しています。しかし、問題が発生しました。

HoneybadgerAPIキーを$HONEYBADGER_API_KEY環境変数に保存したいとします。ただし、2つのアプリには2つの別々のAPIキーがあります。

1つの環境変数に2つの異なる値を設定するにはどうすればよいですか?

今ではあなたが答えを知っていることを願っています。 env varsはプロセスごとであり、私の2つのrailsアプリは異なるプロセスで実行されるため、それぞれが$HONEYBADGER_API_KEYに対して独自の値を持つことができない理由はありません。

今、唯一の問題はそれをどのように設定するかです。幸いなことに、これを本当に簡単にするいくつかの宝石があります。

フィガロ

RailsアプリにFigarogemをインストールすると、config / application.ymlに入力した値はすべて、起動時にrubyENVハッシュに読み込まれます。

宝石をインストールするだけです:

# Gemfile
gem "figaro"

そして、application.ymlへのアイテムの追加を開始します。このファイルを.gitignoreに追加して、誤ってシークレットをコミットしないようにすることが非常に重要です。

# config/application.yml

HONEYBADGER_API_KEY: 12345
ドテンブ

dotenv gemは、.envから環境変数をロードし、YAMLを使用しないことを除いて、Figaroと非常によく似ています。

宝石をインストールするだけです:

# Gemfile

gem 'dotenv-rails'

そして、構成値を.envに追加します。また、誤ってgithubに公開しないように、ファイルをgitで無視するようにしてください。

HONEYBADGER_API_KEY=12345

その後、RubyENVハッシュの値にアクセスできます

ENV["HONEYBADGER_API_KEY"]

次のように、事前定義されたenv変数のセットを使用してシェルでコマンドを実行することもできます。

dotenv ./my_script.sh

Secrets.yml?

ごめん。 Secrets.ymlは、クールではありますが、環境変数を設定しません。したがって、これは実際にはFigaroやdotenvのような宝石の代わりにはなりません。

プレーンな古いLinux

基本的なLinuxコマンドを使用して、アプリごとに固有の環境変数のセットを維持することもできます。 1つのアプローチは、サーバーで実行されている各アプリを異なるユーザーが所有することです。その後、ユーザーの.bashrcを使用して、アプリケーション固有の値を格納できます。


  1. 環境変数の保護

    前回の記事「環境変数に関するRubyistのガイド」では、環境変数システムがどのように機能するかを示し、いくつかの一般的な神話を打ち破りました。しかし、ある有益な読者が指摘したように、セキュリティについてはあまり言及していませんでした。 秘密のAPIキーやその他の貴重な情報を保存するためにenvvarsを使用することが一般的になっているため、セキュリティへの影響を理解することが重要です。見てみましょう: 最悪のシナリオ ハッカーがrootとして、またはWebアプリケーションを所有するユーザーとしてサーバーにアクセスしたと想像してみてください。その場合、高度に暗号化されていない他のすべてのも

  2. Rubyで環境変数を使用する方法

    環境変数はキーと値のペアであり、次のようになります。 KEY=VALUE これらの変数を使用して、コンピューター内のすべてのプログラム間で構成オプションを共有します。 そのため、それらがどのように機能するか、およびENVを使用してRubyプログラムからそれらにアクセスする方法を学ぶことが重要です。 特別な変数。 環境変数の例 : デフォルトのエディターの構成 宝石の場所をRubyに伝える(GEM_PATH / GEM_HOME ) APIキーを、ソース管理(git)にコミットせずにアプリケーションに渡す オペレーティングシステムがバイナリファイル(Windowsでは.exe)を検