4 ms·
That's the thing. All containers are, are a standardized way to ship (distribute) your artifact (application) with it's dependencies inside it. It's a tar arch
by tiew9Vii 3y ago
That's the thing.
All containers are, are a standardized way to ship (distribute) your artifact (application) with it's dependencies inside it. It's a tar archive with a manifest file. I find it easier to think of them as RPM/deb files. You get an artifact repository for free and benefits of the onion file system to reduce size.
People package entire OS distributions in their container, I consider that an anti pattern. Unless you are shipping static HTML your container shouldn't have NGINX or any other stuff in their, especially if you are running NGINX in front of your container anyway.
If your app is written in Go/Rust/C, anything that produces a static executable, the only thing in the container should be the static executable... i.e. 'FROM scratch', 'cp my-app /bin/my-app`, 'ENTRYPOINT /bin/my-app'.
If you use Java, Node, Python, anything that needs a runtime you can use NIX to build a container with only the dependencies needed to run those, nothing else. If you don't like NIX there's other ways to do it although I'm not familiar with them personally.
All the security issues with containers comes from the junk rather than just your application and only the dependencies needed for that app. If a system library is not in your container you don't need to worry about patching it.
Containers I find are always a good idea, it's a standard way to package/distribute.
How you run those containers, that's another matter with Kubernetes becoming the de-facto because it's Kuberenetes and everyone else is using it. You don't need Kubernetes to run a container, especially if it is just one or a handful of containers.
- bandrami 3y agoHere's the dependency list for Bookworm's version of Python 3: libc6, libbz2, libssl3, libatomic1, libdb5, libffi8, liblzma5, libncursesw6, libnsl2, libreadline8, libsqlite3, libtinfo6, libtirpc3, libuuid1, binutils (why is this here? ar, I think?), libctf0, libgcc-s1, libgprofng0, libjansson4, libstdc++6, libzstd1, zlib1g. It does at least finally stop pulling in 2to3 with Bookworm, but that's nearly 2 dozen non-trivial libraries which now either are duplicated (in which case what was the point?) or exist in 2 versions (which is bad) on my server. And that's if I can put down the iron sysadmin fist and make devs pull only from a blessed image on our local registry (I can deal with the occasional shouts of "graybeard!" and "fascist!" but it makes meetings more acrimonious than they need to be). Now, I 100% agree that an otherwise-empty container is all you need for a Go app, but then what is the container actually doing that I can't just do with cgroups in systemd or runit? The whole point of containers was "Devs! Free yourself from the tyranny of a sysadmin limiting your library choices!" but, well, that's exactly the problem they introduce.
- tiew9Vii 3y agoPython is a good example. You have several teams, each working on their own Python app. Each app is in various maturity levels, some are old in maintenance mode, some are new using the latest libraries. These teams or other teams also have other languages they deploy outside of Python. I'm familiar with Python but far from an expert. I think outside of Docker you would need to use Virtual env and maybe publish to a pip repo or package an an RPM/Deb. You'd have to roll your own build/deployment scripts. Alternatively you'd have ansible scripts or similar, maybe packer to build a vm or something. Multi tenant Python install's are bit of a pain which is why I think you'd need virtual env. If you do use pip that will not work for teams who do not use Python so you'd have a second set of special build scripts and another way to distribute the app. So in that scenario you have multiple different deployment mechanisms, a bunch of custom scripts etc. Using a container would give you a common deployment mechanism across all languages. In your scenario though you should absolutely be a fascist greybeard and say "You must use our companies blessed base image before we will deploy your app". Then when a security update comes out you update the base image and send an email out saying "we see your app is using base image v0.0.0, we have released a new image with patched security vulnerability xyz, please update your application to use it by YYYY-MM-DD" Nix wouldn't be to bad an alternative for a container but it has a few rough edges and getting everyone to build the nix way can be a big ask. Nix would solve the dependency + distribution issue with it's binary cache.
- rbanffy 3y ago> "You must use our companies blessed base image before we will deploy your app". Then when a security update comes out you update the base image and send an email out saying Either that or you trigger a rebuild of their images because a dependency changed. This is one of the very few cases where using “:latest” is the right thing to do. I maintain a docker image on Docker Hub (rbanffy/vm370) and I rebuild it from time to time so that it picks up the latest versions of the underlying OS. I still need to migrate it from Debian to something more minimalistic so that this becomes less of an overhead.
- otabdeveloper4 3y agoIf you're using Nix to build containers then you can just do nix-copy-closure and avoid the container hassles altogether. Containers give you an extra networking layer, theoretically, but the way it is implemented is extremely brittle and leaky, so most people don't use it anyway. I assume the same logic applies if you're using some other way of building instead of Nix, too.
- assbuttbuttass 3y agoIf your app is a static binary, why use a container at all?
- LilBytes 3y agoAdmittedly running a binary is quite simple to run on a monolith, depending on size and scaling needs a container still makes sense IMO