skip to Main Content

I have a very simple "Hello world" server that i wrote in RUST, the program is running correctly locally (not as an image), cargo run

Here is my main.rs file –

use axum::{routing::get, Router};
use std::net::SocketAddr;
use tracing_subscriber;

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello, world!" }));

    let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
    tracing::debug!("listening on {}", addr);

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

here is my dockerfile that was generated using docker init

https://forms.gle/ybq9Krt8jtBL3iCk7

ARG RUST_VERSION=1.70.0
ARG APP_NAME=rust-image



FROM rust:${RUST_VERSION}-alpine AS build
ARG APP_NAME
WORKDIR /app


RUN apk add --no-cache clang lld musl-dev git


RUN --mount=type=bind,source=src,target=src 
    --mount=type=bind,source=Cargo.toml,target=Cargo.toml 
    --mount=type=bind,source=Cargo.lock,target=Cargo.lock 
    --mount=type=cache,target=/app/target/ 
    --mount=type=cache,target=/usr/local/cargo/git/db 
    --mount=type=cache,target=/usr/local/cargo/registry/ 
    cargo build --locked --release && 
    cp ./target/release/$APP_NAME /bin/server


FROM alpine:3.18 AS final


ARG UID=10001
RUN adduser 
    --disabled-password 
    --gecos "" 
    --home "/nonexistent" 
    --shell "/sbin/nologin" 
    --no-create-home 
    --uid "${UID}" 
    appuser
USER appuser

COPY --from=build /bin/server /bin/

EXPOSE 3000

CMD ["/bin/server"]

Whenever i run the image, ill get 2024-07-10 12:23:01 Hello, world! and the container will shut down.

2

Answers


  1. I modified Dockerfile slightly main.rs and Cargo.toml are the same:

    ARG RUST_VERSION=1.70.0
    ARG APP_NAME=rust-image
    
    FROM rust:${RUST_VERSION}-alpine AS build
    
    RUN apk add --no-cache clang lld musl-dev git
    
    WORKDIR /app
    COPY src /app/src
    COPY Cargo.toml /app
    
    ARG APP_NAME
    
    
    RUN cargo build --release && 
        cp ./target/release/axum-project /bin/server
    
    
    FROM alpine:3.18 AS final
    
    
    ARG UID=10001
    RUN adduser 
        --disabled-password 
        --gecos "" 
        --home "/nonexistent" 
        --shell "/sbin/nologin" 
        --no-create-home 
        --uid "${UID}" 
        appuser
    USER appuser
    
    COPY --from=build /bin/server /bin/
    
    EXPOSE 3000
    
    CMD ["/bin/server"] 
    

    Then:

    cd /path/to/project
    docker build -t foo .
    docker run -it --rm -p 3000:3000 foo
    

    in another terminal:

    curl localhost:3000
    

    each time I do curl I get Hello world back.

    Login or Signup to reply.
  2. If a binary works locally, but not in Docker, then it is almost always a Docker setup issue in my experience.

    In your case, you are not copying "into" Docker the local files before building the binary. So you are ending up building some default Rust code which prints out "Hello, world!" instead.

    This can be fixed by adding this COPY line to your Dockerfile before the binary is build as follow:

    ARG RUST_VERSION=1.70.0
    ARG APP_NAME=rust-image
    
    FROM rust:${RUST_VERSION}-alpine AS build
    ARG APP_NAME
    COPY . /app # Add this line
    WORKDIR /app
    
    # The rest of your dockerfile remains the same
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search