デプロイと環境変数 — 手元で動いたものを公開するまで

この記事は、プログラミングやバイブコーディングをする上で最低限身につけたほうがよい IT の実践的な知識を 1 から身につける「IT 基礎知識講座の一部」です。
手元で動いたのに公開すると動かない原因は、コードの外側にあります。ビルド・配置・公開の 3 段階と、環境ごとに値を切り替える環境変数を図解で確かめます。

この記事は、手元で動いたアプリを公開するまでの手順であるデプロイと、公開先ごとに値を切り替える環境変数を扱います。

同じ app.js が、自分のパソコンと公開サーバーの 2 か所で動きます。

手元では動いたのに公開先では動かないとき、原因はコードの外側にあります。

1 つの app.js が、2 か所で動く
app.js書いたのは 1 つそのまま実行node app.jsデプロイビルド・配置・公開自分のパソコンlocalhost:3000公開サーバーmy-app.example.com自分だけ誰でも
書いた app.js は 1 つです。上の道はそのまま手元で実行する場合、下の道はデプロイして公開サーバーで動かす場合。右端が、その URL を開ける人です。

この 2 つの場所の違いが、公開したら動かない理由です。

デプロイは、ビルド・配置・公開の 3 段階でできている

公開サーバーに置いて誰でも使える状態にする作業がデプロイで、その中身はビルド・配置・公開の 3 段階です。

デプロイの 3 段階と、途中で失敗したときに見えること
ビルド配置公開app.js と必要なファイルを揃える公開サーバーへ送って起動するURL の要求を受け付ける成果物のフォルダ起動した my-appmy-app.example.comが開く配置に進まない起動の途中で止まる前の成果物のまま
上から順に進みます。左が段階、真ん中の 2 つがそこですることとできあがるもの、右がその段階で失敗したときに見えることです。

1 段階目がビルド(build。app.js と必要なファイルを、公開サーバーで実行できる形に揃える作業)で、できあがったファイル一式が成果物(build output)です。

ビルドが 1 つにまとめるものと、成果物に入らないもの
app.js自分が書いた外部ライブラリ他の人が作ったコード手元だけで使う設定のファイルビルド成果物のフォルダ公開サーバーへ送る手元に残り送られない
app.js と外部ライブラリが 1 つの成果物にまとまり、公開サーバーへ送られます。手元だけで使う設定のファイルはまとめられず、手元に残ります。

手元だけで使う設定のファイルは成果物に入らず、手元に残ります。

公開サーバーに届くのは、まとめたあとの成果物だけです。

前の成果物に戻すのがロールバック(rollback)です。

deploy は配置だけを指すことも、3 段階すべてを指すこともあります。

CI/CD(Continuous Integration / Continuous Delivery。コードを記録するたびに、この 3 段階を自動で行う仕組み)という言い方も出てきますが、自動になるだけで段階は同じです。

デプロイは 3 つの作業をまとめた呼び方

デプロイとは、揃える・送る・受け付ける、の 3 つを続けて行うことです。

揃えるのがビルド、送って起動するのが配置、URL の要求を受け付けるのが公開で、手元だけで使う設定のファイルはまとめる対象に入らないので公開サーバーには届きません。

開発環境と本番環境 — 同じコードでも、コードの外側にあるものが違う

手元で動いた app.js が公開サーバーで動かないのは、コードが変わったからではありません。

環境(environment。app.js を動かすために揃っている、コンピュータ・OS・実行環境・データベース・設定の値の一式)が違うからです。

「開発環境とは」の記事の開発環境は道具の組み合わせ、ここでの開発環境はその道具で動かす場所です。

同じ app.js が動く、2 つの環境の中身
同じ app.js が動く 2 つの環境
  • 動かす app.js は、どちらの環境でも同じ 1 つ
開発環境 — 自分のパソコン
  • 自分で入れた node
  • 同じパソコンの中にあるデータベース
  • エラーの中身を画面に出す設定
本番環境 — 公開サーバー
  • サーバーに入っている node
  • 別のサーバーにあるデータベース
  • エラーを画面に出さず記録に残す設定
外枠が app.js を動かす環境の全体で、中の 2 つがそれぞれの環境です。動かす app.js は 1 つでも、周りに揃っているものは別のものです。

外枠の中に 2 つの環境があり、動かす app.js はどちらも同じ 1 つです。

同じなのはコードだけで、開く URL もデータベースの場所も API キーも別のものです。

手元で通っていた前提公開サーバーでは公開したときに起きること
接続先は localhost:5432その名前のデータベースは無い保存の操作でエラー
API キーはテスト用テスト用のキーは通らない外部サービスに断られる
エラーを画面に出す利用者の画面にそのまま出る中身が人に見える
app.js の中身同じ app.jsそのまま動く

上の 3 行は、手元でだけ成り立っていた前提です。

公開したら動かないときは、コードより先に外側を疑います。

公開サーバーに入って成果物や設定を手で直すと、次のデプロイで置き換わって消えます。

直すのは開発環境の app.js で、直したらもう 1 度デプロイします。

同じなのはコードだけ

環境とは、app.js を動かすために周りに揃っているもののことです。

自分のパソコンが開発環境、公開サーバーが本番環境で、役割が同じものが向かい合っていても接続先もキーも中身は別なので、公開したのに動かないときはこの外側から確かめます。

環境変数は、コードを変えずに環境ごとの値を切り替える仕組み

値をコードの外側に置き、コードは名前だけを読む仕組みが環境変数(environment variable。プログラムの外側で設定し、実行時に名前で読み取る値)です。

app.js に書くのは名前だけで、手元では.env(環境変数の名前と値を並べて書くファイル)に値を書きます。

DATABASE_URL の名前と値が、どこに置かれるか
自分のパソコン(開発環境)
my-app フォルダ
  • app.js — DATABASE_URL という名前だけを書く
  • .env — DATABASE_URL=localhost:5432 と値を書く
  • .env は成果物に入れず、Git にも記録しない
公開サーバー(本番環境)
成果物のフォルダ
  • app.js — 名前だけが書かれたまま届く
デプロイ先の設定
  • DATABASE_URL=db.example.com を登録する
  • 起動した app.js が、この値を名前で読む
左が自分のパソコン、右が公開サーバーです。app.js に書くのは名前だけで、値は左では .env、右ではデプロイ先の設定に置かれます。

手元の .env が読まれるのは、それを置いたパソコンの中だけです。

.env は API キーを含むため Git に記録せず、成果物にも入らないので本番環境には届きません。

手順書の「本番の環境変数を設定してください」は、公開サーバーの側に同じ名前を登録することです。

起動した場所値の設定元DATABASE_URL の値接続の結果
自分のパソコン手元の .envlocalhost:5432手元のデータベースへ
公開サーバー 登録したデプロイ先の設定db.example.com公開用のデータベースへ
公開サーバー 登録し忘れたどこにも無い空のまま接続できずエラーで止まる

同じ app.js のまま、起動した場所によって読む値が変わります。

値が読み込まれるのは起動のときなので、値を変えたら起動し直します。

左右の囲みで動いているのは、同じ app.js です。

違うのは、その外側に置かれている値だけです。

コードには名前、値は環境の側

環境変数とは、コードの外側に置いて、名前で呼び出す値のことです。

手元では .env というファイルに書き、公開サーバーでは同じ名前をその場所の設定として登録するので、公開したのに動かないときは、この登録を忘れていないかを最初に見ます。

秘密情報は環境変数にだけ置き、ソースコードと成果物には入れない

環境変数に置く値のうち特に注意するのが秘密情報(secret。知られると他人が自分になりすませる文字列)で、API キーとパスワードが代表です。

フロントエンドが読む環境変数は、ビルドのときに値が成果物へ書き込まれます。

書き込まれた値は、URL を開いた人の端末にそのまま届きます。

秘密情報は、成果物に入らない本番の環境変数にだけ置き、デプロイ先の設定画面で登録します。

登録した値は成果物に入らず、公開サーバーが app.js を起動するときに渡されます。

登録を忘れると、名前はあっても値が無いまま起動します。

登録した値があるのは公開サーバーの側だけで、成果物にも手元の .env にも同じ値は写りません。

公開したあと、値そのものがある場所は 1 か所だけです。

公開したあと、API キーの値があるのはどこか
公開サーバー
本番の環境変数
  • API_KEY に本番用の値が入っている
  • 読めるのは起動した app.js と、サーバーを操作できる人だけ
成果物のフォルダ
  • app.js には API_KEY という名前だけ
  • 値そのものは書かれていない
利用者の端末
  • 届くのは画面の HTML と JavaScript だけ
  • 秘密情報の値は含まれない
左が公開サーバーの中、右が利用者の端末です。API キーの値があるのは本番の環境変数だけです。

値があるのは本番の環境変数だけで、成果物にも利用者の端末にも入っていません。

置いた場所を何人が読めるかという見方は「セキュリティで気をつけること」の記事で扱います。

値の置き場所は 1 か所に絞る

秘密情報とは、知られると他人に使われてしまう文字列のことです。

コードに書くとビルドでまとめられて利用者の端末まで届くので、値は書かずに公開サーバーの設定として登録し、コードには名前だけを書きます。

QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1デプロイの 3 段階のうち、app.js と必要なファイルを、公開サーバーで実行できる形に揃える段階はどれですか。

Q2手元では動いた my-app が、公開したらエラーで止まりました。本文で挙げた原因として正しいものはどれですか。

Q3API キーやデータベースのパスワードのような秘密情報を置く場所として、本文の説明に合うものはどれですか。