4 ms·
If you imagine a container as a tarball, then scratch is an empty tarball. Each time you copy a file or set of files into the container during the build, you ge
by onei 5y ago
If you imagine a container as a tarball, then scratch is an empty tarball. Each time you copy a file or set of files into the container during the build, you get a new tarball or layer. Some base containers provided by OS vendors, e.g. CentOS, Debian, are a single layer with the entire OS filesystem inside including tooling, libraries etc.
Scratch has no tooling or libraries or anything. It's empty. You typically add a binary into it and then just run that binary, but due to the lack of libraries, it just be statically compiled. So in answer to your question, you can run statically compiled C. You can't run Java due to the lack of JVM which I believe has its on set of filesystem dependencies, but I'm not a Java dev, so I'm not entirely sure.
- throwaway4good 5y agoI meant copying the JVM unix tar ball in there and use it to run whatever. Why aren't everyone just using scratch?
- NavinF 5y agoI'm pretty sure the default build of openjdk dynamically links glibc. If you build it statically, that should work.
- throwaway4good 5y agoWhy is it not best practice to do so? The naive solution using the golang image is nearly 1GB. Why carry this extra complexity around?
- NavinF 5y agoIt is best practice and I wish it was common practice, but there's a lot of friction in the way and some people will actively work against you. Static linking glibc is painful because the former maintainer has some strong opinions: https://www.akkadia.org/drepper/no_static_linking.html https://www.akkadia.org/drepper/no_static_linking.html Most distros force you to dynamically link every dependency if you want them to package it. So the default build for most projects is dynamic You've stumbled on a holy war between distros and guys like you, me, and Linus Torvalds[1] that want to deploy a binary and just have it work everywhere. 1: https://youtu.be/5PmHRSeA2c8?t=295 https://youtu.be/5PmHRSeA2c8?t=295 (Highly recommend watching Linus's answer ~6 minutes in)
- throwaway4good 5y agoSure this is understandable when we are building an OS. But here we are using Docker so we have full control over the application we are building. Why this craziness of having these huge images containing who knows what? Is it just because we can? And the cloud providers like us when we do it?
- ratww 5y agoIt mostly happened because the we carried over the previous assumptions, practices and limitations when moving into containers. I agree with you and the parent commenter, this should be the default, but some people are against static-linking, even in cases dynamic-linking provides no advantages.
- onei 5y agoThere's downsides to statically linking, particularly around what to do when vulnerabilities are found in your dependencies. If you use Debian for example, you can scan packages to detect versions with known vulnerabilities and rebuild the container to upgrade them if it's a static binary, that moves the detection into scanning your dependencies. In modern GitHub (other VCS hosts are available with similar features) this is relatively easy assuming you depend exclusively on things in your language of choice. Outside of that it gets harder and more awkward. That said, using a distro's image also means you may have a bunch of false positives in your scans, who it's a matter of taste imo.
- ulzeraj 5y agoSo Go binaries should also work right?
- raesene9 5y agoyeah I've seen statically compiled go binaries in scratch base images before, seems to work fine. If you need some basic OS files, Google's distroless is another option.
- onei 5y agoGo binaries that are statically linked work great in scratch images. If you or your dependencies start dynamically linking against libraries then they don't so much, but that's relatively unusual in my experience.