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