環境変数運用ルール(索引用)¶
このドキュメントは .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: 薄い層として維持し、createEnvやruntimeEnvのマッピングを担う。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 constantspackages/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_cidev_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.mjs→wrangler 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 の通常開発既定は
3021。3022を使うのは Playwright / E2E で分離起動したい場合に限る。
Portless 開発で参照する補助変数¶
以下は Secrets Manager に保存しないローカル実行用の補助変数 です。just
や Playwright の起動コマンドで都度指定します。
Storefront のサーバーサイド fetch は、VENDURE_BASE_URL が localhost /
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 の正本には置かず、起動コマンド側で一時指定してください。
更新フロー¶
- 変更が必要になったら、対象パッケージの
.env.exampleを先に更新する(SSOT)。 - 実運用環境への投入手順がある場合は、該当デプロイ手順書(例:
docs/03-implementation/infrastructure/deployment-guide.md)に追記する。変数一覧は書かない。 - 実運用・ローカルの投入は、Secrets Manager または起動コマンドで行う(
.envファイルを前提にしない)。
出荷Webhook shadow lane で追加した変数¶
production の出荷Webhookを比較検証する場合は、Vendure 側で次を使用します。
SHIPMENT_WEBHOOK_SHADOW_ENABLEDtrueのとき、system-integration/shipment/notifyで shadow 実行を追加します。- 既定は無効です。kill switch として即時に
falseへ戻せるように運用してください。 SHIPMENT_WEBHOOK_SHADOW_CAPTURE_ENABLEDtrueのとき、production / shadow の比較記録を残します。- shadow 実行自体を残しつつ比較ログだけ止めたい場合に
falseを使います。
補足:
- いずれも
.envに固定せず、Secrets Manager かデプロイ設定の server-side 変数として管理します。 - 詳細な挙動は
../vendure-plugins/system-integration.mdを参照してください。
CMS キャッシュ改善で追加した主要変数¶
- Storefront
CMS_REVALIDATE_SECRET(POST /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_vendurelauncher では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.jpをb2b-ecommerce/prod/vendureに設定する)- WordPress (
ritsubi-ec-plugin) CMS_REVALIDATE_SECRET(Storefront/api/revalidate/cmsのx-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.com。STOREFRONT_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_SECRETは Storefront / 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_IDCLOUDFLARE_ACCOUNT_ID(*_sharedで管理)CLOUDFLARE_API_TOKEN(*_sharedで管理)
CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID / CLOUDFLARE_ACCOUNT_ID /
CLOUDFLARE_API_TOKEN は dev|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_KVbindingCMS_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_TOKEN や MAINTENANCE_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など)で警告がないか確認。