0

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"]
Ecinori
  • 1
  • 2
  • 3
    Unfortunately, I've seen too many of these kind of questions boil down to simply using an old image, or some cached artifact, or some other mishap while trying to craft your code and dockerfiles. For example, if you remove the newline and try to build and run anew, does the previous symptoms come back? – kmdreko Apr 17 '23 at 02:37
  • I am able to consistently reproduce this error by deleting the newline, going back to my other tmux session, running `docker build -t purchasing .` and then `docker run purchasing`. If I add back in the newline and run those 2 commands again, the error no longer happens. Is it possible that somehow since the panic is happening from within a tokio runtime that there is a race condition between the docker container being shut down due to the panic and the error message being logged? – Ecinori Apr 17 '23 at 12:38
  • I have set up docker on a new machine and pulled from my [repo](https://github.com/ChrisMcD1/bike-sharing). My first build, which should have been the working one, is no longer working, and the second build, which removed the newline, is now working on this machine. Some intermediate cached artifact in the build process sounds very likely. Do you have any resources that could help me trace that down? – Ecinori Apr 17 '23 at 13:45

1 Answers1

0

I have found that the answers I wanted were present in this post.

My problem was no that the panic message was not being shown, but rather that cargo was compiling the basic hello world main.rs from my cargo new.

Since my actual source code used the same message being printed to the console, I erroneously thought that it was being compiled.

Adding a RUN touch src/main.rs to my dockerfile before running the second compile command solved this issue! See other posts for better details about why that makes cargo actually recompile.

Ecinori
  • 1
  • 2