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