SvelteKit Docker构建时PUBLIC_BACKEND_SERVER_URL未导出错误
SvelteKit Docker构建时PUBLIC_环境变量无法识别问题
问题场景
开发SvelteKit项目时,本地执行npm run dev能正常加载.env中定义的PUBLIC_BACKEND_SERVER_URL,但执行docker build -t svelte-frontend .时构建失败,报错环境变量未被识别。
错误日志
2.803 x Build failed in 2.13s 2.803 error during build: 2.803 src/lib/posts/fetch-pagination.ts (3:9): "PUBLIC_BACKEND_SERVER_URL" is not exported by "virtual:$env/static/public", imported by "src/lib/posts/fetch-pagination.ts". 2.803 file: /app/src/lib/posts/fetch-pagination.ts:3:9 2.803 2.803 1: import { get, type Writable } from "svelte/store"; 2.803 2: import { collectionObj } from "./store"; 2.803 3: import { PUBLIC_BACKEND_SERVER_URL } from "$env/static/public"; 2.803 ^
相关代码与配置
src/lib/fetch-pagination.ts
import { get, type Writable } from "svelte/store"; import { collectionObj } from "./store"; import { PUBLIC_BACKEND_SERVER_URL } from "$env/static/public"; // Define the options for the fetch request const options = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({...}), }; // Fetch function to get paginated posts export const fetchPaginatedPosts = async (key: string = "posts", last_id: string = "") => { collectionObj.set(key); console.log("de: ", get(collectionObj)); try { const response = await fetch( `${PUBLIC_BACKEND_SERVER_URL}/get-paginated`, options ); if (!response.ok) { throw new Error("Network response was not ok"); } const res = await response.json(); console.log("API call"); return res; } catch (error) { console.error(error); throw error; } };
.env文件
PUBLIC_BACKEND_SERVER_URL=http://localhost:1234
Dockerfile
FROM node:20-alpine AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . RUN npm run build RUN npm prune --production FROM node:20-alpine WORKDIR /app COPY --from=builder /app/build build/ COPY --from=builder /app/node_modules node_modules/ COPY package.json . EXPOSE 3000 ENV NODE_ENV=production CMD ["node", "./build"]
package.json中的脚本
{ "scripts": { "dev": "vite dev", "build": "vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" } }
核心问题
- 为什么
PUBLIC_BACKEND_SERVER_URL在Docker构建过程中无法被$env/static/public识别? - 在SvelteKit项目的Docker构建中,需要额外执行哪些步骤才能确保环境变量被正确导入?
- 我的Dockerfile配置是否存在问题导致了该错误?
问题排查补充(编辑 ✅)
之前尝试复制.env文件失败,最终发现.dockerignore中包含**/.env规则,导致构建时.env文件未被复制到镜像中。虽然忽略.env是安全实践,但如果需要在构建阶段使用该文件,需调整.dockerignore,临时移除该规则,或者通过其他方式注入环境变量。
问题解答
原因分析:
SvelteKit/Vite在构建阶段需要读取.env文件中带PUBLIC_前缀的变量,生成virtual:$env/static/public虚拟模块。如果.env文件被.dockerignore排除,无法进入Docker构建上下文,Vite读取不到变量就会报错该变量未导出。本地开发时.env在项目目录下,Vite能正常读取,因此无问题。解决步骤:
- 方法一:调整
.dockerignore:临时移除**/.env规则,确保构建时.env被复制到镜像中。注意:生产环境不建议直接复制本地.env,推荐用构建参数注入变量。 - 方法二:Docker构建参数注入:
- 修改Dockerfile,在
RUN npm run build前添加:ARG PUBLIC_BACKEND_SERVER_URL ENV PUBLIC_BACKEND_SERVER_URL=$PUBLIC_BACKEND_SERVER_URL - 构建时传入参数:
docker build --build-arg PUBLIC_BACKEND_SERVER_URL=http://localhost:1234 -t svelte-frontend .
- 修改Dockerfile,在
- 方法三:使用
.env.production:创建.env.production配置生产环境变量,确保该文件未被.dockerignore排除,构建时Vite会自动读取该文件。
- 方法一:调整
Dockerfile的问题:
当前Dockerfile本身无语法错误,但缺少环境变量处理逻辑。如果依赖.env文件,必须确保该文件能被复制到构建阶段容器;如果用构建参数,需要添加ARG和ENV声明传递变量到构建阶段。
内容的提问来源于stack exchange,提问作者kawa
相关产品推荐
相关产品推荐

