Q1デプロイの 3 段階のうち、app.js と必要なファイルを、公開サーバーで実行できる形に揃える段階はどれですか。
デプロイと環境変数 — 手元で動いたものを公開するまで
この記事は、プログラミングやバイブコーディングをする上で最低限身につけたほうがよい IT の実践的な知識を 1 から身につける「IT 基礎知識講座の一部」です。
手元で動いたのに公開すると動かない原因は、コードの外側にあります。ビルド・配置・公開の 3 段階と、環境ごとに値を切り替える環境変数を図解で確かめます。
この記事は、手元で動いたアプリを公開するまでの手順であるデプロイと、公開先ごとに値を切り替える環境変数を扱います。
同じ app.js が、自分のパソコンと公開サーバーの 2 か所で動きます。
手元では動いたのに公開先では動かないとき、原因はコードの外側にあります。
この 2 つの場所の違いが、公開したら動かない理由です。
デプロイは、ビルド・配置・公開の 3 段階でできている
公開サーバーに置いて誰でも使える状態にする作業がデプロイで、その中身はビルド・配置・公開の 3 段階です。
1 段階目がビルド(build。app.js と必要なファイルを、公開サーバーで実行できる形に揃える作業)で、できあがったファイル一式が成果物(build output)です。
手元だけで使う設定のファイルは成果物に入らず、手元に残ります。
公開サーバーに届くのは、まとめたあとの成果物だけです。
前の成果物に戻すのがロールバック(rollback)です。
deploy は配置だけを指すことも、3 段階すべてを指すこともあります。
CI/CD(Continuous Integration / Continuous Delivery。コードを記録するたびに、この 3 段階を自動で行う仕組み)という言い方も出てきますが、自動になるだけで段階は同じです。
デプロイは 3 つの作業をまとめた呼び方
デプロイとは、揃える・送る・受け付ける、の 3 つを続けて行うことです。
揃えるのがビルド、送って起動するのが配置、URL の要求を受け付けるのが公開で、手元だけで使う設定のファイルはまとめる対象に入らないので公開サーバーには届きません。
開発環境と本番環境 — 同じコードでも、コードの外側にあるものが違う
手元で動いた app.js が公開サーバーで動かないのは、コードが変わったからではありません。
環境(environment。app.js を動かすために揃っている、コンピュータ・OS・実行環境・データベース・設定の値の一式)が違うからです。
「開発環境とは」の記事の開発環境は道具の組み合わせ、ここでの開発環境はその道具で動かす場所です。
- 動かす app.js は、どちらの環境でも同じ 1 つ
- 自分で入れた node
- 同じパソコンの中にあるデータベース
- エラーの中身を画面に出す設定
- サーバーに入っている node
- 別のサーバーにあるデータベース
- エラーを画面に出さず記録に残す設定
外枠の中に 2 つの環境があり、動かす app.js はどちらも同じ 1 つです。
同じなのはコードだけで、開く URL もデータベースの場所も API キーも別のものです。
| 手元で通っていた前提 | 公開サーバーでは | 公開したときに起きること |
|---|---|---|
| 接続先は localhost:5432 | その名前のデータベースは無い | 保存の操作でエラー |
| API キーはテスト用 | テスト用のキーは通らない | 外部サービスに断られる |
| エラーを画面に出す | 利用者の画面にそのまま出る | 中身が人に見える |
| app.js の中身 | 同じ app.js | そのまま動く |
上の 3 行は、手元でだけ成り立っていた前提です。
公開したら動かないときは、コードより先に外側を疑います。
公開サーバーに入って成果物や設定を手で直すと、次のデプロイで置き換わって消えます。
直すのは開発環境の app.js で、直したらもう 1 度デプロイします。
同じなのはコードだけ
環境とは、app.js を動かすために周りに揃っているもののことです。
自分のパソコンが開発環境、公開サーバーが本番環境で、役割が同じものが向かい合っていても接続先もキーも中身は別なので、公開したのに動かないときはこの外側から確かめます。
環境変数は、コードを変えずに環境ごとの値を切り替える仕組み
値をコードの外側に置き、コードは名前だけを読む仕組みが環境変数(environment variable。プログラムの外側で設定し、実行時に名前で読み取る値)です。
app.js に書くのは名前だけで、手元では.env(環境変数の名前と値を並べて書くファイル)に値を書きます。
- app.js — DATABASE_URL という名前だけを書く
- .env — DATABASE_URL=localhost:5432 と値を書く
- .env は成果物に入れず、Git にも記録しない
- app.js — 名前だけが書かれたまま届く
- DATABASE_URL=db.example.com を登録する
- 起動した app.js が、この値を名前で読む
手元の .env が読まれるのは、それを置いたパソコンの中だけです。
.env は API キーを含むため Git に記録せず、成果物にも入らないので本番環境には届きません。
手順書の「本番の環境変数を設定してください」は、公開サーバーの側に同じ名前を登録することです。
| 起動した場所 | 値の設定元 | DATABASE_URL の値 | 接続の結果 |
|---|---|---|---|
| 自分のパソコン | 手元の .env | localhost:5432 | 手元のデータベースへ |
| 公開サーバー 登録した | デプロイ先の設定 | db.example.com | 公開用のデータベースへ |
| 公開サーバー 登録し忘れた | どこにも無い | 空のまま | 接続できずエラーで止まる |
同じ app.js のまま、起動した場所によって読む値が変わります。
値が読み込まれるのは起動のときなので、値を変えたら起動し直します。
左右の囲みで動いているのは、同じ app.js です。
違うのは、その外側に置かれている値だけです。
コードには名前、値は環境の側
環境変数とは、コードの外側に置いて、名前で呼び出す値のことです。
手元では .env というファイルに書き、公開サーバーでは同じ名前をその場所の設定として登録するので、公開したのに動かないときは、この登録を忘れていないかを最初に見ます。
秘密情報は環境変数にだけ置き、ソースコードと成果物には入れない
環境変数に置く値のうち特に注意するのが秘密情報(secret。知られると他人が自分になりすませる文字列)で、API キーとパスワードが代表です。
フロントエンドが読む環境変数は、ビルドのときに値が成果物へ書き込まれます。
書き込まれた値は、URL を開いた人の端末にそのまま届きます。
秘密情報は、成果物に入らない本番の環境変数にだけ置き、デプロイ先の設定画面で登録します。
登録した値は成果物に入らず、公開サーバーが app.js を起動するときに渡されます。
登録を忘れると、名前はあっても値が無いまま起動します。
登録した値があるのは公開サーバーの側だけで、成果物にも手元の .env にも同じ値は写りません。
公開したあと、値そのものがある場所は 1 か所だけです。
- API_KEY に本番用の値が入っている
- 読めるのは起動した app.js と、サーバーを操作できる人だけ
- app.js には API_KEY という名前だけ
- 値そのものは書かれていない
- 届くのは画面の HTML と JavaScript だけ
- 秘密情報の値は含まれない
値があるのは本番の環境変数だけで、成果物にも利用者の端末にも入っていません。
置いた場所を何人が読めるかという見方は「セキュリティで気をつけること」の記事で扱います。
値の置き場所は 1 か所に絞る
秘密情報とは、知られると他人に使われてしまう文字列のことです。
コードに書くとビルドでまとめられて利用者の端末まで届くので、値は書かずに公開サーバーの設定として登録し、コードには名前だけを書きます。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2手元では動いた my-app が、公開したらエラーで止まりました。本文で挙げた原因として正しいものはどれですか。
Q3API キーやデータベースのパスワードのような秘密情報を置く場所として、本文の説明に合うものはどれですか。