ローカルで直した値が CI に反映されていない ── どの環境でも dotvault pull 1 回で同じ .env をそろえる

上原正吉(EarthLink Network Co., Ltd.)。Claude Codeを開発の主体に据え、20を超えるプロダクトを1人で同時に開発・運用しています。これは、その現場の実測記です。

ローカルで直した値が CI に反映されていない ── どの環境でも dotvault pull 1 回で同じ .env をそろえる

ローカルで直した値が CI に反映されていない ── どの環境でも dotvault pull 1 回で同じ .env をそろえる

この記事は、連載「dotvault の使い方 ── .env を手で配るのをやめ、CI・チーム・AI エージェントに 1 コマンドで配るまで」の第 2 回です。この連載が終わる時に、dotvault を誰でも無料で使える形で公開する予定です。

ローカルの .env で API キーを新しいものに替え、動くことを確かめて push します。ところが CI は古いキーのまま失敗します。CI の設定画面に入れた値は、そこで別に直さない限り変わらないからです。アプリを動かすサーバーにも、GitHub Codespaces のようなクラウドの開発環境にも、同じ値がそれぞれ入っています。どこに何を入れたのか、どれが今の値なのかが、だんだん分からなくなります。

「環境ごとの設定画面に入れてあるのだから、管理はできている」と考えがちです。けれども、入れる場所が 1 つ増えるたびに、値を直す場所も 1 つ増えます。直し忘れは、その環境で動かした時に初めて分かります。

この回では、値の置き場所を dotvault の 1 か所にまとめ、どの環境でも dotvault pull の 1 回で同じ .env をそろえます。install・login・init は、その場所で最初の 1 回だけです。その後に打つのは pull(.env を作らないなら run)だけです。最初の 1 回から、画面を 1 枚ずつ付けて進めます。

結論

  • 同じ環境変数が要る場所は、ローカルだけではありません。 CI/CD、サーバーの実行環境、クラウドの開発環境(GitHub Codespaces、ChatGPT の Codex のクラウド版、Claude Code の Web 版など)にも、同じ値が要ることがよくあります。
  • どの場所でも、値を受け取るのは dotvault pull の 1 回です。 install・login・init は、その場所で最初の 1 回だけです。init が作る project-config.json を commit しておけば、clone した場所では init も要りません。
  • Node.js が入っていて、HTTPS で外に出られる環境なら、どこでも同じ手順で動きます。 この回の端末の画面は、以前の設定が何も無い Linux のコンテナ(Docker の node:20)で、最初から通したものです。
  • dotvault pull は、.env の中の決まった区間だけを書き換えます。 dotvault に無い key の手書きの行は、そのまま残ります。書き出した .env は自分だけが読める権限(-rw-------)になります。
  • .env のファイルを作りたくない時は、dotvault run -- <コマンド> を使います。 この回で入れた値は .env に書かれず、起動したコマンドにだけ渡ります。
  • 人がログインしない場所(CI、サーバー、AI エージェントが自動で動く環境)でも、打つのは同じ dotvault pull か run です。 違うのは、login の代わりに service token を渡すことだけです。7 回目と 8 回目で扱います。

本文(読了 約12分)

前提と注意

  • 読者。 開発を自動化したい開発者、個人事業主、小さなチームの方です。1 回目「セキュアな環境変数のチーム共有のすすめ ── dotvault とは何か、この連載で何ができるようになるか」を読んでいなくても、この回だけで最初の pull まで通せます。
  • 日付と環境。 画面は 2026 年 10 月 18 日に、本番の app.dotvault.io と、その日の最新の CLI(0.15.7)で撮りました。今 npm i -g で入るのは 0.15.8 です。10 月 23 日に 0.15.8 で同じ手順を通しました。この回の手順で見える違いは 4 つです。版の表示、.env に書かれる区切りの行(# BEGIN: dotvault (managed by dotvault))、接続できない時のエラーの括弧の中の文言、区間の外の同じ名前の行をコメントにすること(下の「5. .env を受け取る」で説明)です。key とファイルの数は、後の回で key・ファイル・Global Key を足したので、今は多く出ます。端末は、Linux のコンテナ(Docker の node:20)です。以前の設定が何も無い状態から、最初の 1 回を通しました。コンテナには、token をしまう keychain の仕組み(gnome-keyring と libsecret)を入れてあります。macOS でも打つコマンドは同じです(この回の画面は macOS では撮っていません。初回の login で、キーチェーンへのアクセスを許可するか尋ねるダイアログが出ることがあります)。
  • 端末の画面は再構成です。 端末のスクリーンショットは文字が小さくなるため、実際の出力を文字どおりに写し、見やすい形に組み直しています。内容は実出力と同じで、生の出力はそのまま保存しています。終了コードは、記録した値を echo $? の行の形で示しています。
  • 画面は英語です。 管理コンソールの表示言語は、付録の手順で日本語に切り替えられます。この連載の画面は、読者の多い英語で撮っています。
  • デモのアカウントです。 画面に写るメールアドレス、project 名、値は、この連載のために作ったデモのものです。値は本物ではありません。
  • 用語。 この記事では、API キーやパスワード、接続先の URL のように外に出してはいけない値をまとめて「secret」と書きます。.env は、その secret を KEY=VALUE の形で 1 行ずつ並べたファイルです。用語の一覧は 1 回目にあります。

同じ値が要る場所と、受け取り方

環境変数を使う場所を並べると、次のようになります。値の置き場所はどれも dotvault の同じ project で、違うのは受け取り方だけです。

場所例受け取り方
ローカルのマシン自分の Mac・Windows・Linuxlogin して pull か run(この回)
人が端末を開くクラウドの開発環境GitHub Codespacesローカルと同じ(この回の手順のまま)
AI が自動で作業するクラウドの開発環境ChatGPT の Codex のクラウド版、Claude Code の Web 版service token を渡して、同じ pull か run(token の作り方と渡し方は 7・8 回目)
CI/CDGitHub Actions などservice token を渡して、同じ pull か run(7 回目)
サーバーの実行環境アプリを動かすサーバーやコンテナservice token を渡して、同じ pull か run(token の作り方と渡し方は 7 回目)

値を直す場所は、管理コンソール(または CLI)の 1 か所です。直した後は、それぞれの場所で次に pull した時に新しい値になります。run なら、次に起動した時から新しい値で動きます。

最初の 1 回と、その後

この回で打つコマンドは、その場所で最初の 1 回だけのものと、値が要るたびに打つものに分かれます。

コマンド打つ時何をするか
npm i -g @earthlink/dotvaultその場所で最初の 1 回CLI を入れる
dotvault loginその場所で最初の 1 回(更新用の token が切れた時だけもう一度。下の「2. ログインする」で説明)email とパスワードでログインする
dotvault initproject のフォルダで最初の 1 回(commit すれば、clone した場所では不要)フォルダを project に結び付ける
dotvault pull / dotvault run -- <コマンド>値が要る時に毎回.env を受け取る/値を渡して起動する

管理コンソールで project と key を作るのも、project ごとに最初の 1 回です。ここから、最初の 1 回を順に進めます。

1. インストールする(その場所で最初の 1 回)

Node.js 20 以上が入っていれば、npm で入ります。ローカルのマシンでも、クラウドの開発環境の端末でも同じです。

npm i -g @earthlink/dotvault
dotvault --version

Node 20 のコンテナで npm i -g @earthlink/dotvault を打った端末画面(再構成・2026 年 10 月 18 日)。依存パッケージの 1 つが保守終了という npm の警告が 1 行出た後、added 39 packages in 4s と表示され、続けて dotvault --version が 0.15.7 を返している。

npm の警告が 1 行出ますが、インストールは完了しています。dotvault --version が版の番号を返せば、次に進めます。

2. ログインする(その場所で最初の 1 回)

dotvault login を打つと、Email と Password を順に聞かれます。パスワードは画面に出ません。

dotvault login
dotvault whoami

dotvault login と dotvault whoami の端末画面(再構成・2026 年 10 月 18 日)。login は Email と Password の 2 つを聞き、「Logged in as <デモのメールアドレス>. Token expires in 3600s. Refresh token saved.」で終わる。whoami はメールアドレスと token の残り時間に続けて、org: org_personal_… Personal (personal, org_admin) と、自動で作られた Personal の組織を表示している。

成功すると「Logged in as … Refresh token saved.」と出ます。ログインに使った token は OS の keychain(macOS なら「キーチェーン」。パスワードを安全にしまう OS の仕組み)に入り、平文のファイルとして手元に残りません。Token expires in 3600s と出ますが、更新用の token も一緒に保存されるので、1 時間ごとにログインし直す必要はありません。更新用の token の有効期限は 30 日で、切れた時だけ dotvault login をもう一度打ちます。

dotvault whoami を打つと、自分のメールアドレスと、所属する組織が出ます。初めてログインした時点で、自分だけで使う Personal の組織が自動で作られています。管理者に組織を作ってもらう手順はありません。

3. 管理コンソールで project と key を作る(project ごとに最初の 1 回)

受け取る .env の中身は、ブラウザの管理コンソール(app.dotvault.io)で用意します。ログインは CLI と同じ email とパスワードです。Personal の組織でログインすると、サイドバーは PERSONAL の見出しの下に 8 項目が並びます。人を招く機能(Teams・My Organizations)は Personal では出ません。

Personal の組織でログインした管理コンソールのサイドバー(英語 UI)。PERSONAL の見出しの下に Dashboard・Members・Projects・Global Keys・Service Tokens・Audit Log・Help・User Settings の 8 項目が並び、Teams と My Organizations は無い。

Projects を開き、New project を押すと、名前を 1 つ聞くモーダルが出ます。名前は小文字の英数字とハイフン、アンダースコアだけで、先頭は英数字です。この記事では demo-app にしました。project の名前は dotvault 全体で 1 つだけなので、同じ demo-app は使えません。自分の名前を付けてください。

Create project のモーダル(英語 UI・2026 年 10 月 18 日)。Project name の入力欄 1 つと、「Lowercase letters, digits, hyphens and underscores only; must start with a letter or digit (e.g. my-app).」という名前の規則、Cancel と Create のボタン。

Create を押すと、一覧に demo-app が増え、development・staging・production の 3 つの環境が最初から付いています。環境の使い分けは 3 回目に書きます。この回は development だけを使います。

project 一覧(英語 UI)。demo-app の行に development・staging・production の 3 つの環境名と、Settings・Access のリンクが並ぶ。一覧の上に Active only の絞り込みと 1–1 of 1 の件数。

demo-app を開くと Keys のタブで、development が選ばれた状態です。まだ key が無いので「No keys in development yet.」と出ます。右側の Selected key の欄には「Click a key on the left to inspect.」とあり、key を選ぶと詳細が出る場所です。

demo-app の Keys タブ(英語 UI・2026 年 10 月 18 日)。環境の切り替え(development・staging・production・Common (_shared))、Filter keys の検索欄、+ Add key・+ Add file・↑ Upload のボタン。一覧は「No keys in development yet.」の空状態で、右側の Selected key には「Click a key on the left to inspect.」。

  • Add key を押すと、一覧の中に Key name と Value の入力行が出ます。名前と値を入れて Add を押すだけです。これを 3 回繰り返して、DATABASE_URL・API_BASE_URL・SMTP_PASSWORD の 3 つを入れました。

+ Add key を押した後の Keys タブ(英語 UI)。一覧の先頭に Key name と Value の入力行が現れ、SMTP_PASSWORD と demo の値を入れた状態。行の下に Add と Cancel のボタン。先に入れた DATABASE_URL が下に見える。

key の名前を押すと、右側の Selected key に、その key の環境とファイルと名前(development/env/DATABASE_URL)、説明の欄、値を表示するボタン、削除、Common(どの環境からも使える共通の key の置き場所)へ移すボタンが出ます。Common は 3 回目で扱います。値は一覧には出ません。表示するボタンを押した時だけ出ます。ボタンには「audit-logged」とありますが、監査の記録に何が残るかは 10 回目で実機を見て書きます。

DATABASE_URL を選んだ Keys タブ(英語 UI・2026 年 10 月 18 日)。一覧に API_BASE_URL・DATABASE_URL・SMTP_PASSWORD の 3 行(それぞれに錠のマークと更新日時)。右側の Selected key に development/env/DATABASE_URL、Description の欄と Save description、Reveal value (audit-logged)、Delete、⬆ Promote to Common (_shared) のボタン。

ここまでが管理コンソールの作業です。値を後で直す時も、この画面で直します。次からは端末に戻ります。

4. フォルダを project に結び付ける(init・最初の 1 回)

project のフォルダで dotvault init を打つと、project-config.json が 1 つできます。project の名前は、フォルダの名前がそのまま使われます。別の名前にしたい時は dotvault init --name <名前> です。

cd demo-app
dotvault init
cat project-config.json

dotvault init と cat project-config.json の端末画面(再構成・2026 年 10 月 18 日)。init は「Created project-config.json (project=demo-app). Next: dotvault login && dotvault pull」と 1 行返す。ファイルの中身は name が demo-app、接続先 apiUrl が https://api.dotvault.io/v1、files が [".env"]、defaultEnv が development の JSON。

このファイルには secret が入っていません。project の名前、接続先、書き出すファイルの一覧、既定の環境だけです。そのままリポジトリに commit して構いません。commit しておくと、CI でもクラウドの開発環境でも、clone した場所では init を打たずに pull できます。

5. .env を受け取る(pull・値が要るたびに)

dotvault pull を打つと、ログインの確認、secret の取得、ファイルの書き出しの 3 段階が 1 本の進捗バーで進み、最後に書き出した key の数が出ます。

ここでは、pull の前に .env に手書きの行(コメント 1 行と、PORT・DEBUG の 2 行)を置いておきました。手書きの行がどうなるかを見るためです。

dotvault pull
cat .env
ls -l .env

cat .env・dotvault pull・cat .env・ls -l .env を続けて打った端末画面(再構成・2026 年 10 月 18 日)。pull の前の .env は手書きの 3 行(コメント・PORT=3000・DEBUG=app:*)。pull は進捗バーの後に「✓ Wrote 3 keys to /work/demo-app/.env (project=demo-app, env=development, file=.env). Markers preserved.」「✔ 1 file synced, 0 excluded, 3 keys total」と出る。pull の後の .env は手書きの 3 行がそのまま残り、その下に、BEGIN と END のマーカー行に挟まれて 3 つの key が並ぶ。ls -l の権限は -rw-------。

見てほしいのは 3 点です。

  1. 手書きの行は残ります。 dotvault が書くのは # BEGIN: と # END: の 2 行に挟まれた区間(マーカーの区間)だけです。次に pull した時も、この区間だけが置き換わります。「Markers preserved.」はその意味です。ただし今の 0.15.8 では、区間の外に dotvault が書く key と同じ名前の行(たとえば前から手で書いていた DATABASE_URL=)があると、その行の頭に # dotvault: moved into the managed block below: が付いてコメントになり、警告が出ます。消えはせず、使われるのは区間の中の値です。手で持っていた .env を dotvault に移す時は、この警告で重なっていた key が分かります。
  2. 書き出した .env は自分だけが読める権限になります。 ls -l の -rw------- は、所有者だけが読み書きでき、同じマシンの他のユーザーには読めない設定(chmod 600)です。
  3. この回で入れた key は名前順に並びます。 管理コンソールで入れた順ではありません。

管理コンソールで値を直した後は、どの場所でも同じ dotvault pull をもう一度打てば、マーカーの区間が今の値に置き換わります。

6. .env を作らずに起動する(run・値が要るたびに)

.env をディスクに書きたくない時は、dotvault run -- <コマンド> を使います。この回で入れた環境変数は、.env に書かれず、起動したコマンドの環境変数にだけ渡ります。ただし、5 回目で扱う「ファイルごと預ける secret」(.npmrc など)を登録した project では、run の間はそのファイルがディスクに書き出されます。コマンドが普通に終われば消されますが、Ctrl-C などで dotvault ごと止めると残ることがあります。くわしくは 5 回目で書きます。

dotvault run -- printenv DATABASE_URL
dotvault run -- sh -c 'echo "$API_BASE_URL"'

dotvault run -- printenv DATABASE_URL と dotvault run -- sh -c 'echo "$API_BASE_URL"' の端末画面(再構成・2026 年 10 月 18 日)。どちらも 1 行目に「dotvault run: project=demo-app, env=development」と出た後、printenv が DATABASE_URL の値を、sh が API_BASE_URL の値を表示している。

pull と run の使い分けは、次の表のとおりです。

dotvault pulldotvault run -- <コマンド>
.env のファイル書き出す(マーカーの区間だけ)書かない
値の渡し先ファイルを読む仕組みすべて起動したコマンドだけ
向いている場面.env を読む前提のツールやフレームワーク、他の人が作った起動スクリプトローカル開発(dotvault run -- npm run dev)、CI、ディスクに平文の .env を残したくない時(ファイルごと預ける secret は 5 回目)
値を直した時もう一度 pull する次に起動した時から新しい値になる

ローカル開発では run をおすすめします。平文の .env が無ければ、間違えて commit することも、バックアップに入ることもありません。

init をしなくても動く

project-config.json が無いフォルダでも、project の名前を付ければ pull と run は動きます。自分が使える project の一覧は、引数なしの dotvault list で出ます。

dotvault list demo-app
dotvault pull demo-app

project のフォルダではない場所で dotvault list demo-app と dotvault pull demo-app を打った端末画面(再構成・2026 年 10 月 18 日)。list は project=demo-app の下に env・file・keys・last_modified の表(development・.env・3・更新日時)を出す。pull は「✓ Wrote 3 keys to /work/elsewhere/.env … Markers preserved.」と出る。

project 名をそのまま後ろに付ける形(dotvault pull demo-app)と --project demo-app は同じ意味です。フォルダを project に結び付けておきたい時だけ init を使います。

失敗の読み方

失敗した時は、✖ の後に大文字の code が出て、終了コード(echo $? で見える数字)が決まっています。スクリプトから呼ぶ時は、終了コードで分岐できます。下の表は、この回で実際に出た原因と、まず確かめることです。同じ code が別の原因で出ることもあります。

失敗 5 種の端末画面(再構成・2026 年 10 月 18 日)。上から、config の無いフォルダで dotvault pull → ✖ VALIDATION_ERROR(終了コード 6)、key の無い staging を指定 → ✖ PROJECT_NOT_FOUND(5)、大文字混じりの Demo-App → ✖ BAD_PROJECT(1)、接続先を届かない宛先にした時 → ✖ NETWORK_ERROR(2)、logout の後に pull → ✖ AUTH_REQUIRED(3)。

code終了コード起きたこと直し方
AUTH_REQUIRED3ログインしていないdotvault login
PERMISSION_DENIED4その project・環境を読む権限が無い。または、その名前の project が無いまず project の名前の打ち間違いを確かめる(無い project の名前を打っても、この code になります)。名前が合っていれば、組織の管理者に管理コンソールで権限を付けてもらう。service token では、その token に許していない環境や project を読んだ時にも出ます(7 回目)。権限は 9 回目で扱います
PROJECT_NOT_FOUND5その project・環境に secret が無い(この回では、key を入れていない staging を指定した時)dotvault list で自分の project の名前を、管理コンソールでその環境に key があるかを確かめる
VALIDATION_ERROR6project-config.json が無い、または指定が足りないproject 名を付けて打つか、そのフォルダで dotvault init
NETWORK_ERROR2接続先に届かない回線と、project-config.json の apiUrl を確かめる
BAD_PROJECT / BAD_ENV1project 名の形式が違う(大文字など)、または project に無い環境名小文字の名前にする。環境は development・staging・production か、3 回目で足す名前

PROJECT_NOT_FOUND は、project はあるのにその環境に key が 1 つも無い時にも出ます。上の画面の 2 つ目は、key を入れていない staging を指定した時のものです。

keychain の無い Linux やコンテナでも同じ手順

OS の keychain が使えないマシン(keychain を使う部品 libsecret が入っていない Linux、libsecret は入っていても keychain のサービスが動いていない画面の無いコンテナなど)では、最初に 2 行の知らせが出て、token は ~/.config/dotvault/credentials.json(自分だけが読める権限)に保存されます。打つコマンドと動作は同じです。下の画面は、この回と同じコンテナを keychain の無い状態で動かした時のものです。

同じ Linux のコンテナで、keychain のサービス(D-Bus のセッション)の外から dotvault whoami を打った端末画面(再構成・2026 年 10 月 18 日)。「dotvault: OS keychain unavailable (keytar could not load). Falling back to file-based token storage at /root/.config/dotvault/credentials.json (mode 0600).」と、libsecret を入れるか service token を使うよう勧める 2 行の後に、Not logged in. と出る。

付録: アカウントまわり

パスワードを忘れた時

ログイン画面の「Forgot your password?」から、メールアドレスを入れて確認コードを受け取り、次の画面でコードと新しいパスワードを入れます。パスワードは 12 文字以上で、大文字・小文字・数字・記号を含めます。画面の説明には 8 文字以上とありますが、2026 年 10 月 23 日に確かめたサーバー側の規則は 12 文字以上です。

/forgot-password の画面(英語 UI・2026 年 10 月 18 日)。「Reset your password」の見出し、メールアドレスの欄、Send reset code のボタン、Back to sign in のリンク。

/forgot-password/confirm の画面(英語 UI・2026 年 10 月 18 日)。「Set a new password」の見出しの下に、Email address、Confirmation code(メールに届く 6 桁)、New password(8 文字以上・大文字と小文字・数字・記号)、New password (confirm) の 4 つの欄と、Change password のボタン。

表示言語を日本語にする

サイドバーの User Settings を開き、Language で日本語を選ぶと、その場で保存されて「Saved.」と出ます。この設定はブラウザに保存され、アカウントには付きません。別のブラウザでは選び直します。

User Settings の画面(英語 UI・2026 年 10 月 18 日)。「This setting is stored only in this browser (not on your account).」の注意の下に Language の選択(English を選択中)があり、その下に緑の「Saved.」が出ている。

ログアウトする

dotvault logout で、今使っているアカウントの、そのマシンに保存した token(keychain か、keychain の無い環境ではファイル)を消します。そのマシンでほかのアカウントでも login していなければ、その後の dotvault whoami は「Not logged in.」になります。別のアカウントでも login していた場合は、logout の後はそちらが使われるので、そのアカウントでも logout します。

dotvault logout と dotvault whoami の端末画面(再構成・2026 年 10 月 18 日)。logout は「Logged out <デモのメールアドレス>.」、続く whoami は「Not logged in.」で、終了コードは 3。

この回に書かなかったこと

多要素認証(MFA)の登録と解除は、管理コンソールに画面が入った後に、この回の付録に足します。チームの組織に招かれた後の組織の切り替えは、9 回目に画面と一緒に書きます。

次回

3 回目は「development と production の .env を手で持ち分けるのをやめたい ── project と環境の作り方」です。この回で最初から付いていた 3 つの環境と Common の使い分け、環境どうしの差分、project の archive と delete を、画面と一緒に進めます。


dotvault は、.env や設定ファイルの secret をサーバー側に置き、権限のある人・CI・AI エージェントが 1 コマンドで受け取るサービスです(https://dotvault.io)。この連載が終わる時に、dotvault を誰でも無料で使える形で公開する予定です。公開したら、この連載の手順どおりに使い始められます。

興味のある方は、ぜひ「いいね」と記事の購読をお願いいたします。

自社プロダクトは https://www.eln.ne.jp/products にまとめています。

筆者について

上原正吉。EarthLink Network Co., Ltd. でAI開発をしています。2025年からClaude Codeを開発の主体に据え、今は20を超えるプロダクトを1人で同時に開発・運用しています。この連載では、その現場で実際に起きたこと(うまくいったことも、失敗も)を、数字と一緒に書いていきます。

また、AIで業務や開発を組み替えたい会社・チーム向けに、AI活用のコンサルティングも受け付けています。ご相談は www.eln.ne.jp からどうぞ。


EarthLink Network は、会社の全業務を AI で回すために、必要になったものを自社で作っています。いま作っているプロダクトの一覧と概要は、こちらにまとめています。

→ EarthLink Network が自社でつくっている18のプロダクト

会社と各プロダクトの詳細は、公式サイト www.eln.ne.jp をご覧ください。

ローカルで直した値が CI に反映されていない ── どの環境でも dotvault pull 1 回で同じ .env をそろえる