为什么我的rust代码中的一个换行符会导致docker容器中的panic消息不出现?

tjrkku2a  于 2023-04-20  发布在  Docker
关注(0)|答案(1)|浏览(107)

我有一个actix web rust服务,我正在尝试容器化,虽然这不是我的第一个容器项目,但我对这个概念还是很陌生,所以这里的错误可能是非常基本的。
我观察到,当运行我的镜像时,它以代码0退出,并且没有panic消息,尽管它肯定应该panic,因为我使用未定义的环境变量调用expect
这是我的主要功能,完全一样。

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Hello, world!");
    env_logger::init_from_env(Env::default().default_filter_or("info"));

    let bind_ip = std::env::var("BIND_IP").expect("Must define $BIND_IP");
    let bind_port: u16 = std::env::var("BIND_PORT")
        .expect("Must define $BIND_PORT")
        .parse()
        .expect("Got binding port, but failed to parse to u16");

    HttpServer::new(move || {
        App::new()
            .service(hello_world)
            .service(purchase)
            .wrap(Logger::default())
    })
    .bind((bind_ip, bind_port))?
    .run()
    .await
}

我现在发现,通过在出错行后添加一个换行符,即bind_ip的赋值,我可以在终端中看到panic消息。
新代码现在看起来像

env_logger::init_from_env(Env::default().default_filter_or("info"));

    let bind_ip = std::env::var("BIND_IP").expect("Must define $BIND_IP");

    let bind_port: u16 = std::env::var("BIND_PORT")
        .expect("Must define $BIND_PORT")
        .parse()
        .expect("Got binding port, but failed to parse to u16");

你可以找到特定的提交here。添加一个注解代替换行符也解决了这个问题。
当我通过cargo run或手动调用可执行文件在容器外运行它时,此换行符对可执行文件没有影响。
我在网上根本找不到任何关于rust在docker容器中的panic消息的意外行为的信息,所以我真的很困惑。我尝试了许多不同的代码方向,试图以更简单的方式重现错误,但似乎没有换行符的代码版本是唯一一个没有显示panic消息的版本。
我不确定这个错误是否会在其他人的机器上重现,但我正在WSL2上运行Docker版本20.10.22,build 3a2c30b。
编辑:根据反馈,问题可能是由于缓存依赖关系,我运行了额外的测试,发现在使用docker system prune -a进行完全清理后,我的第一次构建将失败,但对文件的任何任意更改以及第二次构建将导致成功的映像。
下面是我的Dockerfile:

FROM rust:1.67 as builder
RUN USER=root cargo new --bin myapp
WORKDIR myapp
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml
RUN cargo build --release

COPY ./ ./
RUN cargo build --release

FROM debian:bullseye-slim
RUN apt-get update && apt-get install && rm -rf /var/lib/apt/lists/* tmp/* /var/tmp/*

COPY --from=builder /myapp/target/release/purchasing /usr/local/bin/purchasing

EXPOSE 9000
ENV RUST_BACKTRACE=1
ENV SCHEMA_REGISTRY_ADDRESS=localhost:8082
ENV KAFKA_BROKER_ADDRESS=localhost:9092
ENV BIND_IP=0.0.0.0
ENV BIND_PORT=9000
CMD ["purchasing"]
iszxjhcz

iszxjhcz1#

我发现我想要的答案出现在this post中。
我的问题不在于没有显示panic消息,而是cargo正在从我的cargo new编译基本的hello world main.rs
由于我的实际源代码使用了打印到控制台的相同消息,所以我错误地认为它正在被编译。
在运行第二个compile命令之前添加一个RUN touch src/main.rs到我的dockerfile解决了这个问题!查看其他帖子以获得更好的细节,了解为什么这会使cargo实际上重新编译。

相关问题