cloudflareでのシークレット環境変数の設定とastroからの参照方法


| 4 min read | cloudflare-worker astro

しばらくハマったのでメモ

astroのapiにて、gemini api keyを使うため、シークレット変数として参照しかったが、ローカル開発のときに指定したimport.meta.envでの参照がデプロイ先のcloudflare workerにて環境変数を設定しても空になっていたので混乱した。環境変数の埋め込みタイミングの違いにより参照方法が変わるのでメモしておく

解決方法としてはlocalsを使ってenvの値を参照するとよい

ドキュメントのこの部分を読めば自明なのだが、apiに関するコードがかかれてなかったので、スルーしてしまっていた

https://docs.astro.build/en/guides/middleware/#storing-data-in-contextlocals

環境

  • node: 20
  • astro: 5.13.2
  • wrangler: 4.31.0

確認

以下のようなAPIを作成して確認する

// src/pages/api/env.ts
export const prerender = false; // ssr
 
import type { APIRoute } from "astro";
 
// echo server
export const GET: APIRoute = async ({ url, locals }) => {
  const searchQuery = url.searchParams.get("query");
  const localsProjectId = locals.runtime?.env.MY_VAR;
  const metaProjectId = import.meta.env.MY_VAR;
 
  return new Response(JSON.stringify({ searchQuery, localsProjectId, metaProjectId }), {
    headers: { "Content-Type": "application/json" },
  });
}
  • local環境
npm run dev

別コンソールにて。どちらも.envにはいった値が表示される

curl http://localhost:4321/api/env
{"searchQuery":null,"localsProjectId":"env-my-var","metaProjectId":"env-my-var"}
  • デプロイ先

cloudflareのURLに対して呼び出すと、import.meta.envの値は空のため返ってこない。localsの値はcloudflareの設定画面から作成したもの

curl https://xxxx.workers.dev/api/echo
 
{"searchQuery":null,"localsProjectId":"env-cf-var"}

仕組み

ついでに環境変数の設定場所と関係性もまとめておく

ローカル開発環境(npm run dev)では

.envの中身を見るためlocalsでも、import.metaでも同様の値が取得できる

プレビュー環境(ローカルでbuildしたものをastro previewするときなど)も同様

表にするとこう

環境設定方法参照方法補足
ローカル開発(astro dev、wrangler dev、astro preview).env.env.developmentimport.meta.env.MY_VARVite がビルド時に注入するので動く。SSRでも値が埋め込まれる
本番環境(wrangler deploy、astro build)wrangler.toml [vars] / wrangler secret putlocals.runtime.env.MY_VARCloudflare が runtime で env を注入。SSRにおいてimport.meta.env はビルド済み定数なので undefined

いくつか補足

  • cloudflare workerでは、環境変数をbuild時に渡すのではなく、runtimeに入れ込む様子(なので、context.locals.envという名称がついている)。そのためSSRのサーバー側にて参照する環境変数はクライアント側にあるimport.meta.envではなくlocalsから参照しないといけない
  • publicな(クライアントサイドで参照する環境変数)であればprefixにPUBLIC_MY_VARなどとしてwrangler.toml [vars]に設定することで参照可能となる
  • astroにはMODEという概念があり(devで起動しているかbuildしたものをみているかで変わる)import.meta.env.MODE でどちらかを参照可能。MODEの違いにより.env.developmentや、.env.productionなどといった名称でも環境変数が参照可能になっている

参考