یک چندتا ادیت روی این مورد بدم؛ همونطور که گفتم من تازه داشتم اینجا داکرفایل رو برای پروژهام مینوشتم که توی گروه یکی از دوستان سوال پرسید و ترجیح دادم روی نمونه جواب بدم.
اینکه این
dockerfile
درست هست خوبه یا نه هدف نبود و هدف درک
multi-stage
بود.
اما چندتا نکته (بر خلاف دنیای پایتون) :
۱- استفاده از اسم
src
قطعا اینجا مناسب نیست؛ من حواسم نبود ولی
cargo, rustc
رو این اسم حساب میکنند پس
app
رو جایگزین کردم
۲- از
cargo-chef
استفاده کردم به ۲ دلیل :
۲-۱: توی کد بالا من
compile
انجام نمیدادم و فقط پکیجهارو دانلود میکردم؛ قصدم این بود توی استپ بعدی سراغش برم ولی خب توی بعضی شرایط خاص دردسرش زیاد میشه که الان فرصتش رو نداشتم.
۲-۲: توی همون شرایط و
crate
های خاص (که اتفاقا یکی از دوستان توی پروژهاش بهم نشون داد) باعث میشه قابلیت
cache
رو از دست بدید؛ دلیل اصلیش رو نمیدونم.
۳- بجای استفاده از اداکر ایمیجهای معرفی شده توسط پروژه
cargo-chef
از همون
rust:1.82.0
استفاده کردم و فقط یک استیج بیشتر ساختم که دستورات زیر رو داشته باشه :
RUN apt update && apt install lld clang -y && cargo install cargo-chef
۴- وقتی
sqlx
رو توی پروژه دارم؛ توی استیج
runtime
حتما باید
sqlx migrate runtime
رو اجرا کنم. (برایحجم کمتر این مورد رو با
migrate macro
اجرا کردم.
۵- خیلی بهتره موقع استفاده از
cargo build —release
توی استیج
builder
باید از فلگ:
—bin <appname>
استفاده کنم
نهایتا شد این :
FROM rust:1.82.0 AS chef
WORKDIR /app
RUN apt update && apt install lld clang -y && cargo install cargo-chef
FROM chef as planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
ENV SQLX_OFFLINE true
RUN cargo build --release --bin XYZ
FROM debian:bookworm-slim AS runtime
WORKDIR /app
RUN apt update -y \
&& apt install -y --no-install-recommends openssl ca-certificates \
&& apt autoremove -y \
&& apt clean -y \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/XYZ XYZ
COPY .env .env
ENTRYPOINT [ "./XYZ" ]