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

如何解决Rust Axum应用通过Docker Compose传递环境变量失败问题

问题

我有一个Rust Axum应用,启动初期会读取数据库URL创建数据库连接,代码如下:

async fn main() {
    let db_connection_str = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set.");
    println!("Connecting to database: {}", db_connection_str);

    let pool = PgPoolOptions::new()
       .max_connections(5)
       .acquire_timeout(Duration::from_secs(3))
       .connect(&db_connection_str)
       .await
       .expect("can't connect to database");

目前遇到的问题是:应用无法获取环境变量,db_connection_str为空,控制台输出“Connecting to database: ”,看不到实际的数据库URL。

我的Dockerfile内容:

FROM rust:1.84 AS development

WORKDIR /backend

COPY . .

ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL

RUN cargo run

Docker Compose配置:

backend:
    build: ./backend
    ports:
      - "5173:5173"
    environment:
      DATABASE_URL: $DATABASE_URL

我有一个.env文件用于存储环境变量。

注意:执行以下命令时,应用能正常获取环境变量:

docker build -t backend --build-arg DATABASE_URL=<Database_url> .

但执行docker-compose up时就会出现上述无法获取环境变量的问题。

解决方案

核心问题分析

  1. Dockerfile逻辑错误:旧Dockerfile里的RUN cargo run是在镜像构建阶段执行的,而Docker Compose中environment配置的是容器运行阶段的环境变量,构建阶段根本拿不到这些变量。另外,把应用运行放在构建步骤里本身就不符合Docker最佳实践——构建阶段应只负责编译代码,运行操作要放在容器启动时执行。
  2. Compose环境变量传递方式问题:旧配置里DATABASE_URL: $DATABASE_URL需要确保Compose能正确读取本地.env文件的变量,否则会传递空值。

具体修复步骤

1. 重构Dockerfile,分离构建与运行阶段

修改Dockerfile,先在构建阶段编译二进制文件,再在运行阶段复制产物并启动应用:

# 构建阶段:编译Rust应用
FROM rust:1.84 AS builder

WORKDIR /backend

COPY . .

# 编译release版本(需要debug版本则替换为cargo build)
RUN cargo build --release

# 运行阶段:只保留必要的运行环境和二进制文件
FROM rust:1.84 AS development

WORKDIR /backend

# 从构建阶段复制编译好的二进制文件(替换为你Cargo.toml里的项目名称)
COPY --from=builder /backend/target/release/your-app-name .

# 容器启动时运行应用
CMD ["./your-app-name"]

2. 调整Docker Compose配置

让Compose正确读取.env文件并传递环境变量到容器运行阶段:

backend:
    build: ./backend
    ports:
      - "5173:5173"
    # 直接指定要传递的环境变量名,Compose会自动从当前目录的.env文件中读取对应值
    environment:
      - DATABASE_URL
    # 如果你的.env文件不在Compose文件同级目录,可手动指定路径
    # env_file:
    #   - ./path/to/your/.env

3. 检查.env文件格式

确保.env文件无多余空格,格式正确:

DATABASE_URL=postgres://username:password@db-host:5432/db-name

为什么单独构建命令能生效?

因为手动执行docker build时,通过--build-arg DATABASE_URL把变量传递给了构建阶段,而旧Dockerfile里的RUN cargo run正好在构建阶段执行,所以能拿到这个变量。但Compose的environment是给运行阶段的,旧Dockerfile的运行逻辑在构建阶段,自然拿不到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:07:28