You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Astro部署Google Cloud Run后客户端PUBLIC环境变量未定义问题

问题:Astro SSR应用部署到Google Cloud Run后客户端无法获取PUBLIC_前缀的环境变量

我正在Turborepo中部署一个SSR模式的Astro应用,已经打包成Docker容器部署到Google Cloud Run。本地开发时,在.env文件配置PUBLIC_VALUE="https://example.com/example",客户端通过import.meta.env.PUBLIC_VALUE能正常获取并使用,yarn run dev完全正常。但部署到Cloud Run后,客户端的该变量显示为undefined。

我熟悉Cloud Run的使用,此前其他应用通过Cloud Console设置环境变量后用process.env可以正常获取,但此处客户端无法拿到import.meta.env.PUBLIC_VALUE。项目构建和运行都没有报错,相关配置如下:

astro.config.js 配置

import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";
import react from "@astrojs/react";
import 'dotenv/config';
import node from "@astrojs/node";

export default defineConfig({
  integrations: [tailwind(), react()],
  output: 'server',
  adapter: node({
    mode: "standalone"
  })
});

Dockerfile 配置

FROM node:18-alpine AS base

RUN apk add --no-cache libc6-compat
RUN apk update
RUN yarn global add turbo

FROM base AS builder
WORKDIR /app
COPY . .
RUN turbo prune --scope=admin-frontend --docker

FROM base AS installer
WORKDIR /app

COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/yarn.lock ./yarn.lock
RUN yarn install

COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json

RUN turbo run build --filter=admin-frontend...

FROM base AS runner
WORKDIR /app

RUN addgroup --system --gid 1001 expressjs
RUN adduser --system --uid 1001 expressjs
USER expressjs
COPY --from=installer /app .

ENV HOST=0.0.0.0
ENV PORT=3000
EXPOSE 3000

CMD node ./apps/admin-frontend/dist/server/entry.mjs

原因分析

Astro中PUBLIC_前缀的环境变量是构建时注入客户端代码的:本地开发时,Astro会实时读取.env文件并注入变量;但你的Docker流程是在镜像构建阶段(installer阶段)执行turbo build,此时Cloud Run设置的环境变量还未生效(Cloud Run的环境变量是容器运行时才注入的),导致客户端代码里的import.meta.env.PUBLIC_VALUE被替换为undefined。

即使是SSR模式,客户端代码中的import.meta.env.PUBLIC_*依然遵循构建时注入的规则,不会自动读取运行时的环境变量。

解决方法

方法1:构建镜像时传入环境变量(适合固定值场景)

修改Dockerfile,在构建阶段添加参数接收环境变量,确保构建时注入客户端代码:

# 在installer阶段添加以下内容
ARG PUBLIC_VALUE
ENV PUBLIC_VALUE=$PUBLIC_VALUE

# 保留原有的RUN turbo run build命令
RUN turbo run build --filter=admin-frontend...

构建镜像时传递参数:

docker build --build-arg PUBLIC_VALUE="https://example.com/example" -t your-image-name .

如果使用Cloud Build,在cloudbuild.yaml中配置args传递该参数即可。

方法2:运行时从服务端传递变量到客户端(适合动态调整场景)

在SSR服务端代码中读取运行时环境变量,通过全局变量或props传递给客户端:

  1. 在Astro布局文件(如src/layouts/Layout.astro)中添加服务端代码:
---
// 服务端代码:读取Cloud Run设置的环境变量
const publicValue = process.env.PUBLIC_VALUE;
---
<html>
  <head>
    <script>
      // 将变量挂载到window,客户端可直接访问
      window.PUBLIC_VALUE = "{publicValue}";
    </script>
  </head>
  <body>
    <slot />
  </body>
</html>
  1. 客户端组件中使用window.PUBLIC_VALUE替代import.meta.env.PUBLIC_VALUE。

方法3:通过Vite配置运行时注入变量(推荐SSR场景)

在astro.config.js中通过Vite的define配置,将服务端运行时的环境变量注入客户端代码:

import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";
import react from "@astrojs/react";
import node from "@astrojs/node";

export default defineConfig({
  integrations: [tailwind(), react()],
  output: 'server',
  adapter: node({ mode: "standalone" }),
  vite: {
    define: {
      // 将服务端环境变量转为客户端可识别的格式,运行时生效
      'import.meta.env.PUBLIC_VALUE': JSON.stringify(process.env.PUBLIC_VALUE),
    },
  },
});

这种方式不需要修改客户端代码,Cloud Run设置的环境变量会在容器运行时自动注入,重启服务即可更新变量值。

内容的提问来源于stack exchange,提问作者Graunephar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 11:08:12