7 ms·
1. Running strip on go binaries is a BAD IDEA: https://github.com/moby/moby/blob/2a95488f7843a773de2b541a47d9b971a635bfff/project/PACKAGERS.md#stripping-binarie
by c2h5oh 9y ago
1. Running strip on go binaries is a BAD IDEA: https://github.com/moby/moby/blob/2a95488f7843a773de2b541a47d9b971a635bfff/project/PACKAGERS.md#stripping-binaries https://github.com/moby/moby/blob/2a95488f7843a773de2b541a47...
Use -ldflags="-s -w" instead
2. Production build should NOT be running glide install - you want ALL your dependencies vendored, locked and commited to your repo before you build it. Bonus: you can have your Docker image build by CI pipeline and know it's going to be exactly like the one you've got locally.
3. If you're including external resources in your container (upx in this case) via url it's common sense to verify GPG signature or, when one isn't available, at least file hash
4. If your app doesn't need things like ca-certs you don't need Alpine - you can just use "FROM SCRATCH" to only have the statically linked binary in your container slashing another 50% off the final size of container.
- alberteinstein 9y agoThanks! Will try, test and update regarding points 1,2,3. My use case required ca certs but I'll mention the scratch alternative too.
- readams 9y agoOn (2) note that checking in vendored code is not necessary for reproducible builds, as you will get the exact revision that's in your lock file for glide or dep. You will, however, massively bloat your git repo.
- c2h5oh 9y agoI'll take bloat over having Github being up as a build dependency.
- bigdubs 9y agoDitto decreased build speed because of internet downloads.
- dalore 9y agoStick a cache on your build server. As long as your cache doesn't go down you can cache all the build dependencies. Then github is not a dependency anymore.
- PopsiclePete 9y agoHow far can you take this thinking? "My app will build even with Github down!" "My app will build with Github down, and the entire internet down!" "My app will build with Github down, and the internet down, and the US government being taken over by a foreign military power!" "My app will build with Github down, the internet down, and the US government being taken over, and Europe a smoldering crater from the last alien invasion!" At some point - just - nobody cares that your app can build. There's bigger problems. To me, "Github is down and not coming up!" is one of those "oh my god we now have serious problems who cares about our app" moments.
- erik_seaberg 9y agoGitHub usually does a good job but we aren't paying for an SLA guarantee and major outages aren't unheard of. It's easy enough to make your build a deterministic function of the branch contents that I don't see much of a defense for not doing it.
- dastbe 9y agoOn 4, I recommend using the multi stage to build in alpine/Debian/etc and then copy all the necessary artifacts onto a scratch base.
- andrewstuart2 9y agoI really don't understand the obsession with small docker final images, unless you're doing something silly like export/import and throwing away the benefits of layers. Removing temporary files from layers is great, but you get very little benefit from starting smaller. Especially so if that means your final layer is bigger. That's actually a lot worse storage-wise than having a fat base image and a bunch of tiny final layers. I do understand the desire to omit unnecessary attack surface, but if you have a good common base image, then you're not incurring any additional storage beyond once per docker host for all the layers your images have in common.
- ben_jones 9y agoNot a huge docker user but I've noticed various build systems and deployment mechanisms operating slower as a result of large docker images. Faster build times are really attractive to me so I keep my images small.
- ty_a 9y agoThe major problem with very large containers is that it can cause failed jobs in container schedulers due to the holdoff timer expiring before the container is even downloaded. I've only seen this with Marathon so far but I've not yet tried to launch a 2GB container in k8s.
- alberteinstein 9y agoThis doesn't happen on Kubernetes. The Pod stays in ContainerCreating state unless the entire image is pulled. We are running some Java containers which are >2GB and apart from the time it takes to start-up on a fresh node, everything is fine.
- alberteinstein 9y agoWhen a container is scheduled to a node in Kubernetes, if the image is already available, it takes only ~2s for it to be up and running. But, if it is not present on a node and the image is of 2GB, the download speed is the rate limiting factor, taking start up times well beyond 2 seconds. And in a multi node environment where you do scaling up and down or maybe autoscale, new nodes could come up a lot. So, Leaner images are always better.
- tylersmith 9y agoRe: #4 If all you need is ca-certs you can still use SCRATCH and copy copy /etc/ssl/certs/ca-certificates.crt from the build stage image into the final stage COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
- alberteinstein 9y agoThanks, will try this out and update.
- jimjimjim 9y agoThank you for mentioning vendoring.
- deleted 9y ago[deleted]
- eikenberry 9y ago> 1. Running strip on go binaries is a BAD IDEA: This is old information. It is perfectly fine to strip Go binaries and has been for years. This post does a pretty decent job of summing it up. https://dominik.honnef.co/posts/2016/10/go-and-strip/ https://dominik.honnef.co/posts/2016/10/go-and-strip/
- alberteinstein 9y ago#4: Another motivation for using Alpine is to have a shell available so that quick debugging is possible if something goes wrong. For e.g. use ping to see if DNS lookups are happening in a Kubernetes cluster.