Rust in Docker image: exec no such file or directory
Rust in Docker image: exec no such file or directory
我尝试用一个小的 Rust 应用程序创建一个 Docker 图像。我想 运行 在我的 Kubernetes 集群 运行ning 上 Raspberry Pi 4b。所以图像必须是linux/arm64/v8
.
我在 macOS 上使用此命令创建图像:
$ docker build --platform linux/arm64/v8 -t dasralph/ping:arm64_1.0.4 .
但是当我 运行 它在 Raspberry Pi 上时,找不到执行程序:
$ sudo docker run dasralph/ping:arm64_1.0.4
Unable to find image 'dasralph/ping:arm64_1.0.4' locally
arm64_1.0.4: Pulling from dasralph/ping
4f4fb700ef54: Pull complete
38f252ce47e1: Pull complete
Digest: sha256:4fbda499e0552bf08bf230db56906d185bd340655c0cc741ad10ee0ea642c626
Status: Downloaded newer image for dasralph/ping:arm64_1.0.4
exec /ping: no such file or directory
这是我的 Docker 文件:
# STAGE 1 is to build the binary
# Use rust-based image for container
FROM rust:1.61 AS builder
# Adding necessary packages
RUN apt update && apt upgrade -y
RUN apt install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross
RUN rustup target add aarch64-unknown-linux-gnu
RUN rustup toolchain install stable-aarch64-unknown-linux-gnu
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
# Set working directory in container; make directory if not exists
RUN mkdir -p /usr/src/ping
WORKDIR /usr/src/ping
# Copy all Cargo files from local computer to container
COPY Cargo.toml .
COPY Cargo.lock .
COPY .env.docker .env
COPY src src
# Build release application
RUN cargo build --target aarch64-unknown-linux-gnu --release
# STAGE 2 is to have smallest image possible by including only necessary binary
# Use smallest base image
FROM shinsenter/scratch
# Copy application binary from STAGE 1 image to STAGE 2 image
COPY --from=builder /usr/src/ping/target/aarch64-unknown-linux-gnu/release/ping /
EXPOSE 8080
ENTRYPOINT ["/ping"]
有没有人提示出了什么问题?
Cargo.toml
[package]
name = "ping"
version = "0.2.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "4"
load-dotenv = "0.1.2"
main.rs
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use std::env;
use load_dotenv::load_dotenv;
load_dotenv!();
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let bind_address = env!("BIND_ADDRESS", "BIND_ADDRESS must be set");
println!("BIND_ADDRESS: {bind_address}");
HttpServer::new(|| {
App::new()
.service(hello)
})
.bind((bind_address, 8080))?
.run()
.await
}
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello Ralph!")
}
我的问题是,我需要确保 Rust compiles into a static binary。看起来 MUSL 是一种方法。
现在这是我更新的 Dockerfile:
# Build: docker build --platform linux/arm64/v8 -t dasralph/ping:arm64_0.1.0 --push .
# Run: docker run -p 8080:8080 ping
# Test: curl http://localhost:8080/
# STAGE 1 is to build the binary
# Use rust-based image for container
FROM rust:1.61.0-alpine AS builder
# Adding necessary packages
RUN apk update
RUN apk add pkgconfig openssl openssl-dev musl-dev
RUN rustup target add aarch64-unknown-linux-musl
RUN rustup toolchain install stable-aarch64-unknown-linux-musl
# Set working directory in container; make directory if not exists
RUN mkdir -p /usr/src/ping
WORKDIR /usr/src/ping
# Copy all files from local computer to container
COPY Cargo.toml .
COPY Cargo.lock .
COPY .env.docker .env
COPY src src
# Build release application
RUN cargo build --target aarch64-unknown-linux-musl --release
# STAGE 2 is to have smallest image possible by including only necessary binary
# Use smallest base image
FROM shinsenter/scratch
# Copy application binary from STAGE 1 image to STAGE 2 image
COPY --from=builder /usr/src/ping/target/aarch64-unknown-linux-musl/release/ping /
EXPOSE 8080
ENTRYPOINT ["/ping"]
我尝试用一个小的 Rust 应用程序创建一个 Docker 图像。我想 运行 在我的 Kubernetes 集群 运行ning 上 Raspberry Pi 4b。所以图像必须是linux/arm64/v8
.
我在 macOS 上使用此命令创建图像:
$ docker build --platform linux/arm64/v8 -t dasralph/ping:arm64_1.0.4 .
但是当我 运行 它在 Raspberry Pi 上时,找不到执行程序:
$ sudo docker run dasralph/ping:arm64_1.0.4
Unable to find image 'dasralph/ping:arm64_1.0.4' locally
arm64_1.0.4: Pulling from dasralph/ping
4f4fb700ef54: Pull complete
38f252ce47e1: Pull complete
Digest: sha256:4fbda499e0552bf08bf230db56906d185bd340655c0cc741ad10ee0ea642c626
Status: Downloaded newer image for dasralph/ping:arm64_1.0.4
exec /ping: no such file or directory
这是我的 Docker 文件:
# STAGE 1 is to build the binary
# Use rust-based image for container
FROM rust:1.61 AS builder
# Adding necessary packages
RUN apt update && apt upgrade -y
RUN apt install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross
RUN rustup target add aarch64-unknown-linux-gnu
RUN rustup toolchain install stable-aarch64-unknown-linux-gnu
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
# Set working directory in container; make directory if not exists
RUN mkdir -p /usr/src/ping
WORKDIR /usr/src/ping
# Copy all Cargo files from local computer to container
COPY Cargo.toml .
COPY Cargo.lock .
COPY .env.docker .env
COPY src src
# Build release application
RUN cargo build --target aarch64-unknown-linux-gnu --release
# STAGE 2 is to have smallest image possible by including only necessary binary
# Use smallest base image
FROM shinsenter/scratch
# Copy application binary from STAGE 1 image to STAGE 2 image
COPY --from=builder /usr/src/ping/target/aarch64-unknown-linux-gnu/release/ping /
EXPOSE 8080
ENTRYPOINT ["/ping"]
有没有人提示出了什么问题?
Cargo.toml
[package]
name = "ping"
version = "0.2.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "4"
load-dotenv = "0.1.2"
main.rs
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use std::env;
use load_dotenv::load_dotenv;
load_dotenv!();
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let bind_address = env!("BIND_ADDRESS", "BIND_ADDRESS must be set");
println!("BIND_ADDRESS: {bind_address}");
HttpServer::new(|| {
App::new()
.service(hello)
})
.bind((bind_address, 8080))?
.run()
.await
}
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello Ralph!")
}
我的问题是,我需要确保 Rust compiles into a static binary。看起来 MUSL 是一种方法。
现在这是我更新的 Dockerfile:
# Build: docker build --platform linux/arm64/v8 -t dasralph/ping:arm64_0.1.0 --push .
# Run: docker run -p 8080:8080 ping
# Test: curl http://localhost:8080/
# STAGE 1 is to build the binary
# Use rust-based image for container
FROM rust:1.61.0-alpine AS builder
# Adding necessary packages
RUN apk update
RUN apk add pkgconfig openssl openssl-dev musl-dev
RUN rustup target add aarch64-unknown-linux-musl
RUN rustup toolchain install stable-aarch64-unknown-linux-musl
# Set working directory in container; make directory if not exists
RUN mkdir -p /usr/src/ping
WORKDIR /usr/src/ping
# Copy all files from local computer to container
COPY Cargo.toml .
COPY Cargo.lock .
COPY .env.docker .env
COPY src src
# Build release application
RUN cargo build --target aarch64-unknown-linux-musl --release
# STAGE 2 is to have smallest image possible by including only necessary binary
# Use smallest base image
FROM shinsenter/scratch
# Copy application binary from STAGE 1 image to STAGE 2 image
COPY --from=builder /usr/src/ping/target/aarch64-unknown-linux-musl/release/ping /
EXPOSE 8080
ENTRYPOINT ["/ping"]