コンテンツにスキップ

環境変数運用ルール(索引用)

このドキュメントは .env.example の所在・役割と更新手順のみ をまとめた索引です。変数一覧は各 .env.example を単一のソースとして参照してください。

AWS Secrets Manager の取得/更新/注入手順は secrets-manager-operations.md を参照してください。

staging / production URL の参照

公開 URL と probe endpoint の正本は scripts/ops/deploy-targets.sh とし、手元確認や runbook では just environment-urls staging / just environment-urls production を使って同じ値を引く。

Vendure メール送信

staging / production の transactional email は Amazon SES を正本にします。 reputation / suppression list / 監視メトリクスを完全に分離するため、 環境別に SES identity と MAIL FROM を分けています。region は両環境とも ap-northeast-1

環境 identity (用途) EMAIL_FROM MAIL FROM
production ritsubi.co.jp (顧客向け transactional 専用) order@ritsubi.co.jp bounces.ritsubi.co.jp
staging ritsubi-platform.com (infrastructure / non-prod 隔離) noreply@ritsubi-platform.com mail.ritsubi-platform.com

env 値の正本は AWS Secrets Manager。直接 flyctl secrets set で恒久値を書かない。 Fly secret は just sync-fly-secrets <env> で Secrets Manager から同期した副本として扱う。

flyctl secrets set の直接実行は禁止--stage なしの flyctl secrets set は bluegreen deploy を暗黙発動し、本番障害の原因になる (2026-06-08 障害)。secret の変更は以下のいずれかを使う:

  • just sync-fly-secrets <env> — AWS Secrets Manager から一括同期 (推奨)
  • scripts/ops/fly-secrets-set.sh -a <app> KEY=VALUE — 個別設定 (常に --stage で import)
  • fly-secrets-set.sh ... --deploy — stage + 明示的 deploy

保持するキーと格納先:

キー 格納 secret
EMAIL_TRANSPORT=ses b2b-ecommerce/{env}/vendure
EMAIL_FROM(上表) b2b-ecommerce/{env}/vendure
EMAIL_TEST_RECIPIENT(実受信できる検証用アドレス。docs へ記載しない) b2b-ecommerce/{env}/vendure
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY(SES 送信専用 minimum-privilege credential。ritsubi-vendure-ses-sender user は両 identity への ses:SendEmail / ses:SendRawEmail を保持) b2b-ecommerce/{env}/vendure
AWS_REGION=ap-northeast-1 / AWS_DEFAULT_REGION=ap-northeast-1 b2b-ecommerce/{env}/shared

更新フロー詳細は ./secrets-manager-operations.md を参照。 SES / Secrets / Fly の3点 drift 確認は just vendure-ses-email-audit <env> (末尾 true で Fly secrets まで照合。expected 値は環境別に分岐済み)。

型安全な環境変数 (runtime.ts)

各ワークスペース(apps/*, packages/*)には、zod@t3-oss/env-core を使用した runtime.ts が導入されています。

  • 役割:
  • 起動時/ビルド時の環境変数バリデーション。
  • 型補完の提供。
  • public/server の露出制御。
  • 使用方法:
import { runtime } from "@/runtime";
console.log(runtime.VENDURE_BASE_URL);
  • 注意点:
  • process.env を直接参照せず、常に runtime.ts からエクスポートされた値を使用してください。
  • 新しい環境変数を追加した場合は、必ず対応するワークスペースの env.schema.ts のスキーマを更新してください。

contract と apps の役割分離

  • packages/contract: 共通バリデーション関数・共通型定義を集約する正本。
  • URL/Email/Boolean などの判定関数やスキーマはここに置く。
  • apps/*/src/env.schema.ts: 薄い層として維持し、createEnvruntimeEnv のマッピングを担う。
  • apps/*/src/runtime.ts: process.env の解決・型付けを行う唯一の入口。

config / utils / domain の責務分離

  • packages/config: shared な設定の正本。
  • @ritsubi/config/env: app 横断で共通利用する env fragment
  • @ritsubi/config/defaults: runtime fallback / build defaults。port などの 数値定数はここを唯一の正本にし、TS は型付き constant を直接 import する。 shell / process-compose / nx project.json から見たい値は scripts/dev/codegen-env-defaults.mjs.env.defaults を生成し、 scripts/dev/load-env-defaults.{sh,mjs} 経由で読む。 drift は pnpm run lint:env-defaults と pre-commit (env-defaults-drift) で検知する。
  • @ritsubi/config/spec: cross-app shared immutable technical constants
  • packages/utils: low-level helper / runtime helper。設定値の正本は持たない
  • packages/domain: 業務意味を持つ不変条件・業務定数の正本。

import ルール

  • 新規コードで bare import の @ritsubi/config は使わず、責務別 subpath import を使う。
  • app 内で広く使う shared constant は、必要に応じて app local の facade (apps/storefront/src/defaults.ts など) を経由してよい。
  • app 固有の値は app local に置き、shared だからといって機械的に packages/config へ集約しない。

配置とスコープ

本プロジェクトでは 機密情報 を AWS Secrets Manager で管理します。非機密の設定値(例: ポート)は 起動コマンドで一時的に上書き して運用します(.env / .env.local への依存は避ける)。

  • secret 名の雛形は secrets-manager-key-template.md を参照してください。

  • Secrets prefix: b2b-ecommerce

  • 主要な構成SECRETS_CONFIG 名):
  • dev: 共有(b2b-ecommerce/dev/shared)。
  • ci / ci_shared: CI 共有(b2b-ecommerce/ci/shared)。互換 alias: dev_ci
  • dev_storefront: Storefront の開発環境。
  • dev_vendure: Vendure の開発環境。
  • staging: 共有(ステージング)。
  • staging_storefront: Storefront のステージング。
  • staging_vendure: Vendure のステージング。
  • prod: 共有(本番)。
  • prod_storefront: Storefront の本番。
  • prod_vendure: Vendure の本番。

Secrets Manager からの注入

機密情報を取得してコマンドを実行する場合は、just 経由で AWS Secrets Manager を使用してください。

# 例: 開発サーバーの起動
just dev-full

# 例: マイグレーションの実行
just vendure-migrate

これにより、開発者は AWS 認証(例: aws sso login)を一度行っておけば、機密情報が必要なタスクでも安全に起動できます。

ローカルの AWS プロファイル名は統一のため、次を推奨します。

export RITSUBI_AWS_PROFILE=ritsubi

scripts/ops/with-env.sh / scripts/ops/secrets.mjs は、AWS_PROFILE 未設定時に RITSUBI_AWS_PROFILE(未設定なら ritsubi)を利用します。

shared / service の置き場が揺れていないかは、次の監査コマンドで確認できます。

node scripts/ops/secrets.mjs --env staging --services shared,storefront --audit --fail-on-duplicates

AWS SSO ログイン手順(ローカル)

初回に SSO プロファイルを作成し、その後はログインだけ実行します。

# 1) 初回のみ: SSO プロファイル作成
aws configure sso --profile ritsubi

# 参考: ~/.aws/config の例
# [profile ritsubi]
# sso_start_url = https://ssoins-7758fb90e3ed456e.portal.ap-northeast-1.app.aws
# sso_region = ap-northeast-1
# sso_account_id = 610249909456
# sso_role_name = AdministratorAccess
# region = ap-northeast-1

# 2) シェル共通設定(~/.zshrc など)
export RITSUBI_AWS_PROFILE=ritsubi
export SECRETS_PREFIX=b2b-ecommerce

# 3) 日次ログイン
aws sso login --profile "$RITSUBI_AWS_PROFILE"

# 4) セッション確認
aws sts get-caller-identity --profile "$RITSUBI_AWS_PROFILE"

補足:

  • AWS_PROFILE を明示したい場合は AWS_PROFILE=<name> just ... でも実行可能。
  • RITSUBI_AWS_PROFILE を未設定にすると既定で ritsubi を参照します。

実行環境ごとの秘密情報フロー

  • ローカル開発: just / scripts/ops/with-env.sh が AWS Secrets Manager を参照してプロセスに注入。
  • GitHub Actions: OIDC で AWS_ROLE_ARN を Assume し、scripts/ops/secrets.mjs で取得。
  • Cloudflare Workers: workflow 内で scripts/ops/secrets.mjswrangler secret bulk
  • Fly.io (Vendure): 実行時は Secrets Manager を直参照せず、scripts/ops/sync-fly-secrets.sh で AWS Secrets Manager → Fly Secrets を事前同期。

従来の .env ファイルとの関係

.env.example は「必要な変数の一覧(SSOT)」として維持します。

  • 機密情報(APIキー等)が必要: just 経由で AWS Secrets Manager を使用
  • 非機密(ポート等)を変更したい: 起動コマンドで PORT=... のように一時的に上書き

PORT 系の扱い

  • PORT を Secrets Manager 等で管理しない。
  • サーバーポートは PORT を正とし、env.schema.ts では管理しない。
  • 変更が必要な場合は、起動コマンドで PORT=xxxx を一時的に設定する(永続化しない)。
  • 既定値は固定ポート(例: PORT=3021)で動かし、必要なときだけ上書きする。
  • Vendure の通常開発既定は 30213022 を使うのは Playwright / E2E で分離起動したい場合に限る。

Portless 開発で参照する補助変数

以下は Secrets Manager に保存しないローカル実行用の補助変数 です。just や Playwright の起動コマンドで都度指定します。

Storefront のサーバーサイド fetch は、VENDURE_BASE_URLlocalhost / 127.0.0.1 などの loopback URL で、初回アクセスが失敗した場合にだけ Portless URL へ再試行します。

  • PORTLESS=0: Portless URL への再試行を無効化する。
  • PORTLESS_PROXY_PORT / PORTLESS_PORT: Portless の proxy port。未指定時は worktree 名 → Git ブランチ名 → カレントディレクトリ名の順で識別子を決め、そこから決定的に算出する。
  • PORTLESS_VENDURE_URL: 再試行先の完全なベース URL。指定時はこれを最優先で使う。
  • PORTLESS_VENDURE_NAME: PORTLESS_VENDURE_URL 未指定時の route 名。既定は vendure で、http://<route>.localhost:<proxyPort> を組み立てる。

Playwright E2E で route 名だけを変えたい場合は、次の補助変数を使います。

  • PORTLESS_STOREFRONT_E2E_NAME: Storefront E2E の route 名(既定: storefront-e2e
  • PORTLESS_VENDURE_E2E_NAME: Vendure E2E の route 名(既定: vendure-e2e

これらは worktree ごとに値が変わるため、.env.example や Secrets Manager の正本には置かず、起動コマンド側で一時指定してください。

更新フロー

  1. 変更が必要になったら、対象パッケージの .env.example を先に更新する(SSOT)。
  2. 実運用環境への投入手順がある場合は、該当デプロイ手順書(例: docs/03-implementation/infrastructure/deployment-guide.md)に追記する。変数一覧は書かない。
  3. 実運用・ローカルの投入は、Secrets Manager または起動コマンドで行う(.env ファイルを前提にしない)。

出荷Webhook shadow lane で追加した変数

production の出荷Webhookを比較検証する場合は、Vendure 側で次を使用します。

  • SHIPMENT_WEBHOOK_SHADOW_ENABLED
  • true のとき、system-integration/shipment/notify で shadow 実行を追加します。
  • 既定は無効です。kill switch として即時に false へ戻せるように運用してください。
  • SHIPMENT_WEBHOOK_SHADOW_CAPTURE_ENABLED
  • true のとき、production / shadow の比較記録を残します。
  • shadow 実行自体を残しつつ比較ログだけ止めたい場合に false を使います。

補足:

  • いずれも .env に固定せず、Secrets Manager かデプロイ設定の server-side 変数として管理します。
  • 詳細な挙動は ../vendure-plugins/system-integration.md を参照してください。

CMS キャッシュ改善で追加した主要変数

  • Storefront
  • CMS_REVALIDATE_SECRETPOST /api/revalidate/cms の認証用)
  • SENTRY_DEBUG_TOKEN(非本番の手動 Sentry debug trigger 用)
  • SENTRY_DEBUG_SIGNING_SECRET(staging synthetic canary 用の dedicated signing secret)
  • VENDURE_ASSET_URL(Vendure 商品画像の公開ベースURL。ec-assets 分離用)
  • VITE_PUBLIC_WORDPRESS_ASSET_BASE_URL/wp-content/* の配信ベースURL)
  • CLOUDFLARE_ACCESS_CLIENT_ID(Cloudflare Access service token client id, *_shared
  • CLOUDFLARE_ACCESS_CLIENT_SECRET(Cloudflare Access service token secret, *_shared
  • Vendure (CMS Integration Plugin)
  • CMS_REVALIDATE_SECRET(Storefront /api/revalidate/storefront-data への x-cms-revalidate-secret ヘッダ。商品 / variant / collection 更新後の Storefront data cache invalidation で使用。*_shared 正本) local の dev_vendure launcher では STOREFRONT_DATA_REVALIDATE_DISABLED=true と local dummy secret を既定注入し、Storefront 未起動の baseline sync では外部 revalidate に依存しない。
  • CLOUDFLARE_ACCESS_CLIENT_ID(WPGraphQL への CF-Access-Client-Id
  • CLOUDFLARE_ACCESS_CLIENT_SECRET(WPGraphQL への CF-Access-Client-Secret
  • WORDPRESS_FETCH_TIMEOUT_MS(WPGraphQL fetch タイムアウト)
  • WORDPRESS_FETCH_CACHE_TTL_SECONDS(プロセス内 TTL キャッシュ。 headerMenu / footerMenu のみ runtime で bypassCache: true を立てるため、TTL の影響を受けない)
  • WORDPRESS_FETCH_CACHE_MAX_ENTRIES(キャッシュ上限件数)
  • WORDPRESS_SNAPSHOT_TTL_SECONDS(last-known-good snapshot の保持時間)
  • STOREFRONT_URL(server-to-server / canonical origin。 例: production は https://order.ritsubi-platform.com。CORS allowlist や revalidate など、Vendure runtime が server-to-server の Storefront origin を 必要とする経路で使う)
  • STOREFRONT_PUBLIC_URL(Vendure Dashboard の商品 Storefront プレビュー、メール本文の顧客向けリンク、メンテナンス回避 URL など、 管理者・顧客がブラウザで開く公開 alias。未設定時は STOREFRONT_URL に フォールバックするため、production では https://medical.ritsubi.co.jpb2b-ecommerce/prod/vendure に設定する)
  • WordPress (ritsubi-ec-plugin)
  • CMS_REVALIDATE_SECRET(Storefront /api/revalidate/cmsx-cms-revalidate-secret ヘッダ。*_shared 正本)
  • STOREFRONT_REVALIDATE_URL(POST 先 URL の明示指定。任意。 未設定時は STOREFRONT_URL + /api/revalidate/cms にフォールバック)
  • STOREFRONT_URL(server-to-server で叩く canonical origin。 例: https://order.ritsubi-platform.comSTOREFRONT_REVALIDATE_URL のフォールバック元としても利用)
  • STOREFRONT_PUBLIC_URL(WP 管理画面の preview / パーマリンクで エンドユーザーに露出させる公開 alias。未設定時は STOREFRONT_URL を 流用。production は https://medical.ritsubi.co.jp を設定する)

各値の投入先は既存ルールどおり AWS Secrets Manager を正本にし、just 経由で注入する。配置先の判定は secrets-manager-operations.md の「キー配置ルール(shared 正本)」を正本とする。

補足: Storefront の canonical URL / public alias URL の repo 内 SSOT は scripts/ops/deploy-targets.sh です。STOREFRONT_PUBLIC_URL を Secrets Manager に置く場合も、runtime が alias を返すための環境別ミラー値として扱い、 新しい公開 alias の決定・変更は先に deploy-targets.sh と関連 docs を更新してください。

Dashboard から開く商品プレビューは、実際の商品詳細ページと同じ構成を保ちます。 プレビューであることの識別は本文中へ専用ブロックを差し込まず、固定表示の 「管理者プレビュー」indicator に集約します。購入操作と閲覧履歴の記録など副作用を 持つ処理は無効化しますが、関連商品・購入共起・閲覧履歴などの表示セクションは通常 ページと同じ描画経路を通します。

[!IMPORTANT] CMS_REVALIDATE_SECRETStorefront / Vendure / WordPress が同じ値を読む ため、必ず b2b-ecommerce/{env}/shared 配下に置いてください。 b2b-ecommerce/{env}/storefront / vendure / wp 側に同名キーを置くと audit (scripts/ops/secrets.mjs --audit --fail-on-duplicates)で重複検出されます。

Storefront メンテナンス KV で追加した主要変数

  • Storefront deploy / Vendure 制御面
  • CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID
  • CLOUDFLARE_ACCOUNT_ID*_shared で管理)
  • CLOUDFLARE_API_TOKEN*_shared で管理)

CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID / CLOUDFLARE_ACCOUNT_ID / CLOUDFLARE_API_TOKENdev|staging|prod*_shared を正本にする。Storefront deploy (*_storefront + shared) と Vendure 制御面 (*_vendure + shared) の両方が shared から同じ値を参照する。共通キーを *_shared に置く判断基準は secrets-manager-operations.md の「キー配置ルール(shared 正本)」に従う。

補足:

  • just / scripts/ops/with-env.sh / just secrets-*prod_* を正とする
  • 互換のため production_* も解釈するが、新規記載は prod_* に統一する
  • CI 共通 secret は ci / ci_shared を正とし、dev_ci は互換 alias としてのみ扱う

  • Cloudflare Workers

  • MAINTENANCE_KV binding
  • CMS_REVALIDATE_SECRET(shared secret 正本。必要時は Worker runtime へ別途注入)

namespace 作成には just cloudflare-maintenance-kv-create <env> を使い、返却された namespace id を target Storefront deploy config と target 環境の *_shared secret へ同期する。Storefront 固有の namespace を正本とし、ec project 全体の共通設定が必要になった時点で別 namespace を増やす。 CLOUDFLARE_API_TOKENMAINTENANCE_KV binding の検証は deploy script 側の別チェックで担保する。Workers への secret 同期は shared + storefront をマージして実行し、共有 token を Worker runtime に注入する。

記載ルール(.env.example)

  • コメントで「必須/任意」「用途」「例値」「staging 用推奨値」を明記。推測値は避け、ダミー値を使う。
  • パッケージ横断で同名の変数を使う場合は、定義場所を1か所に決め、他はコメントで参照を示す。
  • 認証バイパスやモック用フラグは開発・検証用途であることをコメントに明記する。
  • SMILE 連携は CSV インポート/エクスポートのみ。API 用の環境変数は不要。

命名ポリシー

  • フロント公開が必要なものは VITE_PUBLIC_ プレフィックスを付与し、クライアントへ露出することを明示。
  • バックエンド専用の秘密情報は SECRET/KEY/TOKEN などを含め、公開プレフィックスを付けない。
  • 環境を問わず URL はフルパスで記載し、ポート/パスを含める。
  • Vendure 連携の集約:
  • VENDURE_BASE_URL を正とし、ここから /shop-api, /admin-api, /assets を自動生成します。
  • VENDURE_API_URL非推奨(原則不要)です。
  • VENDURE_ASSET_URL は asset 配信ドメインを API ドメインから分離する場合の正式な設定です。ec-assets.* を使う構成では設定を推奨します。

トラブルシュート

  • 値がどこで定義されているか不明な場合は rg "<VAR_NAME>" -g '.env*' で所在を確認。
  • 変更時は関連するビルド/デプロイ手順(pnpm docs:build, pnpm docs:spec など)で警告がないか確認。