A container is basically a glorified chroot, so there is a few things not strictly needed, but I typically use Alpine as a base system, which has a shell, some core utils, and musl libc in just ~5 MB. Since it's on its own layer, it gets deduplicated both in build and at runtime with other Alpine containers (and many Dockerhub images have an Alpine option.)
That being said, since Go binaries have no inherent dependencies, I have indeed made Docker images containing exactly one file: the Go binary. These containers are basically the same as fat binaries, with the benefits of Docker scheduling and networking at runtime.
> I have indeed made Docker images containing exactly one file
To anyone reading this, you need some magic compiler flags in both Rust and GoLang to make sure it's a statically compiled binary (doesn't dynamically link against GNU lib-c).
But yes, this is super neat. I also like how it reads in the docker file:
Ah yeah, without CGO_ENABLED=0, you'll get a very cryptic error when the ELF binfmt can't find the linker binary...
Never tried it with Rust, but I look to using Rust in the future, so I guess I better find out what the flags are for Rust.
Sidenote: It's often useful to have ca certs and timezone info. At that point it's probably not a bad idea to just use Alpine and apk add those things.
By default, Rust compiles all Rust code statically, but the standard library depends on a libc. If you want to use MUSL, you can. If you bind to C libraries, you may need to configure it or not, it depends on how the wrapper is written.
That being said, since Go binaries have no inherent dependencies, I have indeed made Docker images containing exactly one file: the Go binary. These containers are basically the same as fat binaries, with the benefits of Docker scheduling and networking at runtime.