0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

環境変数

0
Posted at

はじめに

Web開発をしていると、こんな記述を見かけることがあります。

ENV["DATABASE_URL"]
import.meta.env.VITE_API_BASE_URL

最初に見たときは、

「ENVって何?」
「なぜ普通の変数ではなく、わざわざ環境変数を使うの?」

と疑問に思いました。

この記事では、環境変数とは何なのかと、実務ではどのように使われているのかを初心者向けにまとめます。


1. 環境変数とは?

一言でまとめると

環境変数とは、アプリの外側からプログラムに設定値を渡す仕組みです。

例えば、Webアプリを動かすためには次のような情報が必要になります。

  • データベースの接続先
  • データベースのパスワード
  • APIキー
  • サーバーのポート番号
  • バックエンドAPIのURL
  • 開発環境なのか本番環境なのか

これらをすべてプログラムのコードに直接書くのではなく、コードとは別の場所で管理して、必要なときにプログラムから読み込むために環境変数を使用します。

イメージとしては次のようになります。

┌─────────────────────┐
│      環境変数        │
│                     │
│ DB_HOST=localhost   │
│ DB_USER=root        │
│ PORT=3000           │
└──────────┬──────────┘
           │
           │ 読み込む
           ▼
┌─────────────────────┐
│      Webアプリ       │
│                     │
│ Rails / Node.js     │
│ React など           │
└─────────────────────┘

なぜ環境変数が必要なのか?

大きく分けると理由は3つあります。

① 環境によって設定を変更するため

Webアプリでは一般的に、

開発環境(development)
↓
ステージング環境(staging)
↓
本番環境(production)

のように複数の環境があります。

例えば、RailsからMySQLに接続する場合を考えてみます。

開発中は自分のPCにあるMySQLを使用するため、

localhost

に接続します。

しかし、本番では本番サーバーにあるDBへ接続する必要があります。

環境 DBの接続先
開発環境 localhost
ステージング環境 ステージング用DB
本番環境 本番用DB

もし接続先をコードに直接書いてしまうと、環境が変わるたびにコードを書き換えなければいけません。

そこで、

ENV["DB_HOST"]

のようにしておけば、

プログラム
    │
    └── ENV["DB_HOST"]
             │
             ├─ 開発 → localhost
             ├─ staging → staging用DB
             └─ 本番 → production用DB

というように、同じコードのまま設定だけ変更できます。


② パスワードやAPIキーをコードに直接書かないため

例えば、次のようにAPIキーをコードへ直接書くのは危険です。

api_key = "sk-xxxxxxxxxxxxxxxx"

このコードをGitHubへpushすると、APIキーまでGitの履歴に残ってしまう可能性があります。

そこで、

api_key = ENV["API_KEY"]

とします。

実際のAPIキーはコードとは別に、

API_KEY=xxxxxxxxxxxxxxxx

として管理します。

このように、

「コードとして公開してよいもの」と「秘密にする設定値」を分離できる

ことも環境変数を使う大きな理由です。


③ 設定変更のたびにコードを書き換えないため

例えば、Webサーバーのポート番号を変更するとします。

コードに直接、

port = 3000

と書いてしまうと、3000から8080に変更したい場合にコードを変更する必要があります。

環境変数なら、

port = ENV["PORT"]

としておき、

PORT=3000

を、

PORT=8080

に変更するだけで済みます。


2. 基本的な使い方

ここからは、実際のWeb開発を想定して環境変数を見ていきます。

今回は、

フロントエンド:React + TypeScript
バックエンド:Ruby on Rails
DB:MySQL

という構成を例にします。


使用例① RailsからMySQLへ接続する

RailsからMySQLへ接続するためには、

DBの場所
ユーザー名
パスワード
データベース名

などの情報が必要です。

例えば環境変数として次のように設定します。

DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_app_development
DB_USER=root
DB_PASSWORD=password

Railsではこれらを、

ENV["環境変数名"]

で取得できます。

例えばconfig/database.ymlでは次のように利用できます。

development:
  adapter: mysql2
  encoding: utf8mb4
  host: <%= ENV["DB_HOST"] %>
  port: <%= ENV["DB_PORT"] %>
  database: <%= ENV["DB_NAME"] %>
  username: <%= ENV["DB_USER"] %>
  password: <%= ENV["DB_PASSWORD"] %>

ここで、

ENV["DB_HOST"]

は、

「OSに設定されているDB_HOSTという環境変数の値を取得する」

という意味です。

例えば、

DB_HOST=localhost

なら、

ENV["DB_HOST"]

の結果は、

localhost

になります。

処理の流れは、

環境変数

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=xxxx
       │
       ▼
config/database.yml
       │
       ▼
Rails
       │
       ▼
MySQL

というイメージです。


使用例② ReactからRails APIへアクセスする

ReactとRailsを分離したWebアプリでは、ReactからRailsのAPIへリクエストを送ることがあります。

例えば開発環境のRailsが、

http://localhost:3000

で動いているとします。

.envに、

VITE_API_BASE_URL=http://localhost:3000

と設定します。

Reactでは、

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;

fetch(`${apiBaseUrl}/users`);

のように利用できます。

すると実際には、

fetch("http://localhost:3000/users");

と同じようなリクエストになります。


本番環境になったら?

本番ではRailsが、

https://api.example.com

で公開されているとします。

本番側の環境変数を、

VITE_API_BASE_URL=https://api.example.com

に変更します。

Reactのコードは、

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;

fetch(`${apiBaseUrl}/users`);

のままです。

つまり、

【開発環境】

React
  │
  ▼
VITE_API_BASE_URL
  │
  ▼
http://localhost:3000
  │
  ▼
Rails


【本番環境】

React
  │
  ▼
VITE_API_BASE_URL
  │
  ▼
https://api.example.com
  │
  ▼
Rails

となります。

コードを書き換えなくても、環境変数だけでアクセス先を変更できる

というのが重要なポイントです。


使用例③ APIキーを管理する

外部APIを利用する場合も環境変数がよく使われます。

例えば、

API_KEY=xxxxxxxxxxxxxxxx

という環境変数を用意します。

Rails側では、

api_key = ENV["API_KEY"]

として取得できます。

こうすることで、

api_key = "xxxxxxxxxxxxxxxx"

のように秘密情報をコードへ直接書かなくて済みます。


.envファイルとは?

環境変数を勉強していると、

.env

というファイルもよく登場します。

例えば、

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=password

API_KEY=xxxxxxxx

VITE_API_BASE_URL=http://localhost:3000

のような内容です。

ここで注意したいのが、

環境変数と.envは同じものではありません。

.envは、

環境変数として設定したい値を書いておくためによく使われるファイル

です。

イメージとしては、

.env
 │
 │ 読み込み
 ▼
環境変数
 │
 │ 取得
 ▼
プログラム

となります。


.envをGitHubにpushしない

.envには、

DB_PASSWORD=xxxxxxxx
API_KEY=xxxxxxxx
SECRET_KEY=xxxxxxxx

などの秘密情報が入ることがあります。

そのため通常は.gitignoreに、

.env

と書いてGitの管理対象から外します。

.env
 ↓
.gitignoreで除外
 ↓
GitHubにはpushされない

という状態にします。


.env.exampleとは?

会社のリポジトリでは、

.env.example

というファイルを見ることがあります。

例えば、

DB_HOST=
DB_PORT=
DB_NAME=
DB_USER=
DB_PASSWORD=

API_KEY=

のようになっています。

これは、

「このアプリを動かすためには、これらの環境変数を設定してください」

と他の開発者に伝えるためのファイルです。

例えば、新しくプロジェクトに参加したエンジニアは、

cp .env.example .env

などでファイルをコピーして、

DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_app_development
DB_USER=root
DB_PASSWORD=自分の開発環境の値

のように設定します。

そのため、

.env
→ 実際の値
→ Git管理しないことが多い

.env.example
→ 必要な環境変数の一覧
→ Git管理する

という違いがあります。


実務でよく見る環境変数

実際のリポジトリでは、例えば次のような名前を見ることがあります。

環境変数 用途
DATABASE_URL DBへの接続情報
DB_HOST DBサーバーの場所
DB_USER DBのユーザー名
DB_PASSWORD DBのパスワード
PORT Webサーバーのポート番号
RAILS_ENV Railsの実行環境
NODE_ENV Node.jsの実行環境
API_KEY 外部APIの認証情報
SECRET_KEY_BASE Railsで利用される秘密情報
REDIS_URL Redisへの接続先
VITE_API_BASE_URL Reactから接続するAPIのURL

プロジェクトによって名前は異なりますが、

DB_
API_
SECRET_
TOKEN
KEY
PASSWORD
URL
HOST
PORT

などが含まれていたら、

「これは環境変数として管理する設定値かもしれない」

と考えると、コードを読みやすくなります。


実務で環境変数を見つけたら確認すること

実務のリポジトリで、

ENV["SOMETHING"]

を見つけたら、まず次の3つを確認すると理解しやすいです。

① 何のための値なのか?

例えば、

ENV["DATABASE_URL"]

なら、

DBへ接続するための情報かな?

と考えます。


② 秘密情報なのか?

例えば、

PASSWORD
TOKEN
API_KEY
SECRET

などが含まれていたら、秘密情報である可能性があります。

その場合、むやみに、

GitHub
Slack
AIチャット
スクリーンショット

などへ貼り付けないよう注意します。


③ どの環境の値なのか?

同じ環境変数でも、

development
staging
production

で値が違うことがあります。

例えば、

DATABASE_URL

だけを見ても、

ローカルDBなのか?
ステージングDBなのか?
本番DBなのか?

を確認することが重要です。


まとめ

環境変数を一言でまとめると、

アプリの外側からプログラムへ設定値を渡すための仕組み

です。

Web開発では主に、

  • DBの接続情報
  • APIキー
  • パスワード
  • APIのURL
  • ポート番号
  • 開発・本番などの環境設定

などに使用されます。

特に重要なのは、

コード
        と
環境ごとの設定・秘密情報

を分離できることです。

最初は、

ENV["DATABASE_URL"]

のようなコードを見ると難しく感じますが、

DATABASE_URLという名前の設定値を外から取得している」

と考えるとかなり読みやすくなります。

実務で環境変数を見つけたときは、

「何の値なのか」「秘密情報なのか」「どの環境向けなのか」

の3つを確認していきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?