为什么Docker在macOS和Ubuntu上构建我的Rust程序时会产生不同的图像?这是Docker中的bug吗?

cclgggtu  于 2023-03-07  发布在  Docker
关注(0)|答案(1)|浏览(126)

下面是我的简单Rust程序:

use std::time::SystemTime;

fn main() {
    let now = SystemTime::now();
    println!("{:?}", now);
}

这是我的Dockerfile:

FROM rust:1.50 as builder
WORKDIR /usr/src
RUN cargo new --bin playground
WORKDIR /usr/src/playground
COPY Cargo.toml .
COPY Cargo.lock .
RUN cargo build --release
RUN rm -rf src
COPY src src
RUN cargo build --release

FROM ubuntu:18.04
COPY --from=builder /usr/src/playground/target/release/playground /usr/local/bin/playground
CMD [ "playground" ]

我的构建器映像包含cargo build --release两次,因为第一次它构建我的依赖项,第二次它构建我的可执行文件。我知道上面的简单程序没有外部依赖项,但这是我通常使用的设置,当我的src代码更改但我的Cargo.toml没有更改时,它极大地加快了Docker构建(它在几秒钟内构建,而不是几分钟)。
然而,我得到完全不同的结果时,我docker builddocker run这在macOS相比Ubuntu.
在macOS上,我获得系统时间,例如:

SystemTime { tv_sec: 1614652600, tv_nsec: 426791496 }

在Ubuntu上,我得到了默认的Rust程序输出:

Hello, world!

在Ubuntu上构建时,第一个cargo build --release生成的可执行文件似乎被缓存,因此第二个cargo build --release不执行任何操作(当它在macOS上重建可执行文件时)。我不确定什么是“正确的”行为,但据我所知,Docker在两个不同的操作系统上构建相同的东西时不应该产生不同的映像?这是Docker中的一个bug还是我根本误解了Docker的工作原理?
有趣的是,这只发生在我use的东西。如果我改变我的 rust 程序:

fn main() {
    println!("CHANGED!");
}

然后我在macOS和Ubuntu上都得到了Hello, world!。请注意,如果我在第二个RUN cargo build --release之前添加RUN cargo clean来修复这个问题,我可以在两个操作系统上获得一致的行为。但是,我仍然认为如果没有这个修复,我会得到不同的图像。
请注意,我使用的是macOS Catalina 版本10.15.7和Docker桌面版本3.1.0,我使用的是Ubuntu 18.04.4和Docker版本19.03.6。

dba5bblo

dba5bblo1#

这是Docker中的一个bug还是我从根本上误解了Docker的工作原理?
我认为这更多的是一个Docker的限制,而不是一个错误。
据我所知,Docker在两个不同的操作系统上构建相同的东西时不应该产生不同的图像?
Docker确实为每个容器提供了一个“操作系统环境”,但内核始终是主机的内核- Docker不是一个完整的VM。
一个程序在不同的操作系统上运行的方式可能不同,因此也可能得到不同的构建结果。
但是,我不相信在这个特定的案例中会发生这种情况,我认为您可能是对的,主机或Docker端存在一些细微的差异,我建议检查src目录和main.rs容器的外部(主机)端和内部(Docker)端的修改和创建时间

相关问题