У меня есть очень простой сервер «Hello world», который я написал на RUST, программа работает корректно локально (не как изображение), cargo run
Вот мой файл main.rs —
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();
}
Груз.томл:
[package]
name = "axum-project"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.5"
tokio = { version = "1", features = ["full"] }
tracing = "0.1"
tracing-subscriber = "0.2"
вот мой файл докеров, созданный с помощью 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"]
Всякий раз, когда я запускаю изображение, я получаю 2024-07-10 12:23:01 Hello, world!
, и контейнер закрывается.
Похоже, что процесс завершается, когда он выполняется в контейнере, но не когда он не выполняется в контейнере; можешь отредактировать заголовок вопроса, чтобы уточнить это? В обоих случаях процесс «работает на локальном хосте», но «локальный хост» означает нечто иное.
Ваш код должен вернуть Hello world
по запросу GET к /. Означает ли это, что сервер отключается после первого успешного запроса?
Можете ли вы опубликовать свой cargo.toml
?
@chesedo, я вижу Hello world
в журналах контейнера. @Dogbert, сервер отключится после того, как это сообщение будет напечатано в журналах контейнера.
@Greg0ry ``` [пакет] name = "axum-project" version = "0.1.0" edition = "2021" [зависимости] axum = "0.5" tokio = { version = "1", Features = ["full" ] } tracing = "0.1" tracing-subscriber = "0.2" ```
Это очень похоже на то, что изображение выполняет двоичный файл hello world по умолчанию, созданный cargo init
, можете ли вы удалить все изображения и попытаться создать их заново?
@yonatanhornstein, тогда совершенно ясно, что двоичный файл, запускаемый вашим контейнером, не является двоичным файлом, который будет создан опубликованным вами кодом main.rs
. Это потому, что ваш main.rs
никогда не выводит на консоль «Hello world».
Я немного изменил Dockerfile main.rs
и Cargo.toml
такие же:
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"]
Затем:
cd /path/to/project
docker build -t foo .
docker run -it --rm -p 3000:3000 foo
в другом терминале:
curl localhost:3000
каждый раз, когда я делаю скручивание, я получаю Hello world
обратно.
Вы можете решить свою проблему, добавляя исходные фрагменты в Dockerfile
один за другим, перестраивая и перезапуская их.
Большое спасибо, у меня все сработало и исправилось.
Если двоичный файл работает локально, но не в Docker, то, по моему опыту, это почти всегда проблема с настройкой Docker.
В вашем случае вы не копируете «в» Docker локальные файлы перед сборкой двоичного файла. Итак, вы в конечном итоге создаете некий код Rust по умолчанию, который выводит «Hello, world!» вместо.
Это можно исправить, добавив эту строку COPY
в ваш Dockerfile перед сборкой двоичного файла следующим образом:
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
Вы видите
Hello, world!
в журналах контейнера? Или это HTTP-ответ?