I have an actix web rust service that I am trying to containerize, and although it is not my first container project, I am still new to the concept, so the error here could be very basic.
I observed that when running my image, it was exiting with code 0 and no panic message even though it certainly should have been panicking since I was calling expect
with an environment variable that was not defined.
Here is my main function, exactly as it was.
#[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
}
I have now found that somehow, by adding a newline after the erroring line, which is the assignment of bind_ip
, I can see the panic message in the terminal.
The new code now looks like
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");
You can find the specific commit here. Adding a comment in place of the newline also solved the problem.
This newline has no effect on the executable when I run it outside of the container either through cargo run
or manually calling the executable.
I was unable to find any information at all online about unexpected behavior of rust's panic messages inside of docker containers, so I'm really at a loss here. I've tried many different orientations of the code to try to reproduce the error in a simpler way, but it seems like the version of the code without the newline is the only one that doesn't show a panic message.
I am unsure if this error will be reproducible on anyone else's machines, but I am running on WSL2 with Docker version 20.10.22, build 3a2c30b.
EDIT:
Based on feedback that the problem is likely due to cached dependencies, I ran additional tests and found that after doing a full clean with docker system prune -a
, my first build will fail, but any arbitrary change to the file and then a second build will result in a successful image.
Here is my 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"]