Rust Axum服务器本地正常,Docker容器启动后立即退出问题
问题解决:Axum服务Docker容器启动后立即退出
问题描述
用Rust编写的Axum Hello World服务,本地执行cargo run可正常运行,但通过docker init生成的Dockerfile构建镜像后,运行容器会输出2024-07-10 12:23:01 Hello, world!后立即关闭。
原因分析
- 二进制文件复制错误:Dockerfile中定义的
APP_NAME为rust-image,但Cargo.toml里的包名是axum-project,导致构建阶段复制的是不存在的二进制文件,最终容器运行的不是正确的Axum服务。 - 日志未初始化:main.rs中导入了
tracing_subscriber但未执行初始化,无法输出服务启动的日志信息,难以直观排查问题。
解决方案
1. 修正Dockerfile的APP_NAME参数
将Dockerfile里的ARG APP_NAME=rust-image改为ARG APP_NAME=axum-project,与Cargo.toml的包名保持一致,确保正确复制编译后的二进制文件。
2. 初始化Tracing日志
在main.rs的main函数开头添加日志初始化代码,以便查看服务启动日志,确认服务是否正常监听端口。
修改后的文件
修改后的Dockerfile
ARG RUST_VERSION=1.70.0 ARG APP_NAME=axum-project # 改为与Cargo.toml一致的包名 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"]
修改后的main.rs
use axum::{routing::get, Router}; use std::net::SocketAddr; use tracing_subscriber; #[tokio::main] async fn main() { // 初始化tracing日志,启用控制台输出 tracing_subscriber::fmt::init(); 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(); }
验证步骤
- 重新构建镜像:
docker build -t axum-server . - 运行容器:
docker run -p 3000:3000 axum-server - 此时会看到
listening on 0.0.0.0:3000的日志,容器保持运行状态,访问http://localhost:3000可得到Hello, world!响应。
内容的提问来源于stack exchange,提问作者yonatan hornstein
相关产品推荐
相关产品推荐

