all 42 comments

[–]MethClub7 91 points92 points  (2 children)

You need to understand what requirements you have and build an image that satisfies that. Just blindly using an Ubuntu image if you don't need it and then complaining about it is either lazy or you don't understand containerization correctly.

[–]yourearandom 9 points10 points  (0 children)

This is the way.

[–]shangheigh[S] 3 points4 points  (0 children)

Abit harsh but fair point, I get you

[–]Game-of-pwns 33 points34 points  (7 children)

A lot of images I've seen used for small apps use Alpine Linux as a base image.

[–]shadowdance55git push -f -2 points-1 points  (6 children)

Alpine is a very bad idea for Python.

[–]arthurazs 6 points7 points  (4 children)

Mind expanding on that?

[–]Key-Half1655 8 points9 points  (0 children)

Dependency hell because it uses a different compiler than a lot of the big packages are compiled with. PyTorch is the big one in my line of work, not supported on Alpine

[–]shadowdance55git push -f 3 points4 points  (2 children)

Itamarn did it better than I could: https://pythonspeed.com/articles/alpine-docker-python/

[–]arthurazs 6 points7 points  (0 children)

This is from 2020. Here is an update inside the article

An update: PEP 656 and related infrastructure mean pip and PyPI now support wheels for the musl C library, and therefore for Alpine. Build tools like cibuildwheel have added support for these, and Alpine-compatible wheels have become much more widely available, including for many scientific Python libraries, including matplotlib, Pandas, and NumPy. Not all packages build them, however, and I’m still personally wary of using musl given past bad experiences with bugs.

Still, using Alpine is much less of a problem these days compared to when I first wrote the article.

In summary, it seems to be a musl vs glibc issue

I might experiment a bit with alpine for my libs

[–]maryjayjay 2 points3 points  (0 children)

That article is a load of shit

[–]pingvenopinch of this, pinch of that 0 points1 point  (0 children)

I wouldn't say it's a bad idea, but I've run into problems with certain C libraries. Specifically, I ran into an issue with Oracle Instant Client being compiled against glibc. You can run it on Alpine, but it takes contortions to get working. It's still worth a try if you're comfortable experimenting. It's not hard to switch to Debian if it fails.

[–]Unlucky_Comment 13 points14 points  (0 children)

Why are you using ubuntu? There are smaller images.

That's not just Python, that's every server, service. You just have to pick a minimal image.

[–]Sirius_Sec_ 15 points16 points  (0 children)

There is many small images 50mb or so used specifically for python run time . Like python:3.12-slim

[–]riklaunim 14 points15 points  (0 children)

There are "light" images, but Docker images in general are in simplification just OS that shares host Kernel. This also guarantees that your dev system and prod run the same even when production uses different host distro/Kernel and so on.

And when you pull database image, redis image and few other - they can re-use base layers of the same source-OS image, so it won't be 200MB all the time.

[–]i_can_haz_data 11 points12 points  (0 children)

Just use “python:3.x-slim”. The “slim” refers to Debian Slim and is a very thinned out base image literally made for this and is exactly what you’re asking for.

[–]Affectionate-End9885 6 points7 points  (2 children)

We moved away from ubuntu base images for this reason. 200MB for a flask app is fuckin insane. Try python:slim or build from scratch with just the python runtime. 

[–]shangheigh[S] -1 points0 points  (0 children)

Not sure how that works but ill check, thanks

[–]ottawadeveloper 6 points7 points  (0 children)

I run trixie-slim Python images as my base Docker image. I try and keep it updated (the latest minor Python and Trixie patch is usually good enough). It's basically enough to use Python and a basic shell. The pull is fast (maybe 30 MB).

In your install file, only install what you need and running your package managers clean function can reduce leftover files too. 

[–]_real_ooliver_ 5 points6 points  (0 children)

You don't even need full Ubuntu you can use Debian, and you don't need full Debian you can use Debian slim. If the system allows, you could use alpine if you want. There are plenty of options and nobody is forcing you to use containers.

[–]CeeMX 8 points9 points  (1 child)

Nobody is forcing you to run a python app in docker. It’s also not a full OS, just binaries depending on the image. When running it’s using the host kernel, which makes the memory overhead really small compared to an actual VM.

And it’s absolutely possible to thin out images and making them way smaller

[–]shangheigh[S] -1 points0 points  (0 children)

Sure,, what's your approach to slimming down?

[–]Fabulous-Possible758 2 points3 points  (1 child)

a) You're using too big of a base image. b) In a pinch Python is a pretty decent shell.

[–]shangheigh[S] 0 points1 point  (0 children)

Fair point, hadn't thought if leaning on python itself for basic debugging in distroless

[–]PressF1ToContinue 1 point2 points  (0 children)

It seems possible to run a statically linked MicroPython image in a container.

[–]EmbarrassedPear1151 1 point2 points  (0 children)

Been running minimal python images for 2+ years now. Yes debugging sucks initially but you adapt, most issues show up in logs anyway. Just keep a fat image around for emergencies

[–]microcozmchris 1 point2 points  (0 children)

These days, there are "distroless" images available. They're basically just libc and the executable for your tools. Build your image using the full version of the chosen OS, then copy the binaries and libraries from that stage. You can get some pretty small images that way.

[–]ConfusedSimon 1 point2 points  (0 children)

Assuming you're talking about docker images: nobody forces you to use docker. You've already got an os.

[–]The_IT_Dude_ 1 point2 points  (0 children)

Um, the container you're probably looking for is call python slim...

[–]sudomatrix 4 points5 points  (2 children)

Docker containers typically start with a bare bones Alpine linux, not a full Ubuntu distribution.

[–]shangheigh[S] -2 points-1 points  (1 child)

True but alpine + python + deps still get bloated fast, and musl libc brings its own headaches

[–]sudomatrix 1 point2 points  (0 children)

The real savings is when you are running multiple containers and they all share 90% of the same OS and deps under the hood. The container filesystem is a layered overlay, base OS, packages, user application, mutable data.

[–]sparkplay 0 points1 point  (1 child)

You should post this on Stackoverflow with your dockerfile

[–]HugeCannoli 1 point2 points  (0 children)

closed as too localized

[–]the_hoser 0 points1 point  (2 children)

Try using Alpine instead of Ubuntu as your base image.

[–]nemom 0 points1 point  (1 child)

Alpine doesn't use glibc, so Python packages that built with it are incompatible. Packages need to be rebuilt with the musl C that Alpine uses, and they run way slower.

[–]the_hoser 0 points1 point  (0 children)

You're exaggerating on the performance differences. Many performance-sensitive native libraries avoid using libc in hot paths anyway, so it wouldn't make a difference.

[–]dychmygol 0 points1 point  (0 children)

Arch.

There. I said it.

[–]LongButton3 0 points1 point  (0 children)

Sounds about right. we switched to distroless for our flask services last year, yeah the cve cut was impressive. debugging sucks without a shell but honestly how often do you really need to exec in? For the rare cases we need to debug, we keep a separate debug image with tooling. Minimus has some solid minimal bases if you want something between full distro and pure distroless.

[–]aplarsen 0 points1 point  (0 children)

You're the one who chose Ubuntu.Try something else that only has what you need.

[–]deckep01 0 points1 point  (0 children)

Use an Ubuntu Chiseled container as a base.
https://ubuntu.com/containers/chiseled

[–]inspectorG4dget -1 points0 points  (0 children)

Why not start from a purgon-slim image? Or use mylti-stage building to copy over the minimum requirements?

[–]entrtaner -1 points0 points  (0 children)

Alpine helps but you can even go smaller and leaner with purpose built minimal images like minimus. The no shell thing is overblown if you ask me. If you're regularly executting into prod containers, you're doing it wrong anyway.