如何通过Docker Compose将环境变量传递给Vite运行的Svelte(Kit)应用
问题分析与解决方案
首先修正你Docker Compose配置中的错误:你重复定义了build字段,这会导致配置无效,需要合并为一个完整的build块。
接下来针对Vite环境变量的机制,分两种场景给出解决方案:
场景1:构建时固定环境变量(变量无需动态修改)
Vite会将VITE_前缀的环境变量在构建阶段注入到客户端代码中,构建完成后变量值会被硬编码到产物里,运行时无法修改。
修正后的Dockerfile
FROM node:18-alpine AS builder WORKDIR /app # 接收构建参数并设置为环境变量,供Vite构建使用 ARG VITE_SERVER_HOST ENV VITE_SERVER_HOST=$VITE_SERVER_HOST COPY package*.json . RUN npm ci COPY . . RUN npm run build RUN npm prune --production FROM node:18-alpine WORKDIR /app COPY --from=builder /app . ENV NODE_ENV=production # 第二阶段无需重复处理VITE_SERVER_HOST,客户端代码已构建完成 CMD ["node", "build"]
修正后的Docker Compose配置
web: container_name: songrex-web restart: unless-stopped build: context: web args: - VITE_SERVER_HOST=<URL> environment: - PORT=5173 - ORIGIN=<URL> ports: - 5173:5173 depends_on: - server
此时重新构建镜像并启动容器,客户端代码中的import.meta.env.VITE_SERVER_HOST就能正确获取到构建时传入的变量值。
场景2:运行时动态传递环境变量(变量需要在容器启动时修改)
由于Vite的VITE_前缀变量是构建时注入的,运行时无法直接修改客户端代码中的变量值。可以通过以下两种方式实现运行时动态传递:
方案A:服务器端环境变量 + API端点传递
- Docker Compose配置:添加非
VITE_前缀的环境变量
web: # ...其他配置 environment: - PORT=5173 - ORIGIN=<URL> - SERVER_HOST=<URL>
- 创建SvelteKit API路由(
src/routes/api/server-host/+server.js)
export async function GET({ env }) { return new Response( JSON.stringify({ host: env.SERVER_HOST || "server" }), { headers: { "Content-Type": "application/json" } } ); }
- 客户端代码调用API获取变量
let hosturl; async function loadServerHost() { const res = await fetch("/api/server-host"); const data = await res.json(); hosturl = `${data.host}:3000`; } loadServerHost();
- 简化Dockerfile:无需在构建阶段处理变量
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . RUN npm run build RUN npm prune --production FROM node:18-alpine WORKDIR /app COPY --from=builder /app . ENV NODE_ENV=production CMD ["node", "build"]
方案B:运行时替换构建产物占位符
- 客户端代码使用占位符
const hosturl = (import.meta.env.VITE_SERVER_HOST || "{{SERVER_HOST}}") + ":3000";
- Dockerfile添加启动脚本
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . # 构建时注入占位符 RUN VITE_SERVER_HOST="{{SERVER_HOST}}" npm run build RUN npm prune --production FROM node:18-alpine WORKDIR /app COPY --from=builder /app . ENV NODE_ENV=production ENV SERVER_HOST=server # 添加启动脚本 COPY entrypoint.sh . RUN chmod +x entrypoint.sh ENTRYPOINT ["./entrypoint.sh"]
- 编写启动脚本
entrypoint.sh
#!/bin/sh # 替换构建产物中的占位符 sed -i "s/{{SERVER_HOST}}/$SERVER_HOST/g" /app/build/**/*.js # 启动应用 node build
- Docker Compose配置:设置运行时环境变量
web: # ...其他配置 environment: - PORT=5173 - ORIGIN=<URL> - SERVER_HOST=<URL>
内容的提问来源于stack exchange,提问作者DaFeist
相关产品推荐
相关产品推荐

