pypa / pipenv

Python Development Workflow for Humans.
https://pipenv.pypa.io
MIT License
24.87k stars 1.87k forks source link

Dockerfile ONBUILD is now deprecated, what should be done? #2627

Closed caio closed 6 years ago

caio commented 6 years ago

Hello everyone,

The reference Dockerfile in the root directory uses a deprecated directive and I'm opening this issue so that we decide what to do about it. (EDIT: The official -onbuild images were deprecated, that's it)

Aside: I've been away from serious python development for many years and, now that I'm dipping my toes on it again, finding and using pipenv has been a blast. Fantastic improvement, thanks a lot for the hard work! <3

So, ONBUILD has been deprecated and library maintainers started getting rid of it:

I see a few different options to solving this:

  1. Removing the onbuild directives but keeping the same idea/style (pro: the resulting Dockerfile will be super simple)
  2. Getting rid of the Dockerfile in this repo altogether as it's a tangent to this project (So, maybe move it to a separate repo so it can evolve separately and we can get some "good enough" base images on dockerhub)
  3. Crafting a fancier Dockerfile with multi-stage builds

For the 3rd option, I've been using the following quite successfully:

FROM ubuntu:18.04 as build

RUN apt update && apt install python3-pip git -y && pip3 install pipenv
RUN apt install -y python3-dev libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

WORKDIR /build
COPY Pipfile Pipfile.lock /build/
RUN bash -c 'PIPENV_VENV_IN_PROJECT=1 pipenv install'

FROM ubuntu:18.04 as application

ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

RUN apt update && apt install -y -q python3-minimal

WORKDIR /app
COPY --from=build /build /app/
COPY . /app/

CMD .venv/bin/python -mapplication.main

It has the benefit of generating way lighter-weight final images when you need to compile things. This Dockerfile is used for a project that uses scrapy, sqlalchemy and psycopg2 and the resulting image size is in the 240MB whereas building it without multi-stage would result in a image sized around 680MB.

However it's also quite awkward, which makes me unsure if it fits as a good "here's a Dockerfile to get you started asap" kind of thing:

  1. pipenv is made to generate the .env in the build directory so it can be easily copied (a flag would be helpful instead of using PIPENV_VENV_IN_PROJECT, I can try to make that happen if you think it makes sense)
  2. the application layer still has to run some apt install commands (pipenv generates binaries inside the .venv dir, but they aren't statically linked so not installing python3-minimal leads to missing libraries)

So there's that. Options so far for the Dockerfile are: Getting rid of it; Or making it super simple but "not so good" for projects of medium or higher complexity; Or making it a bit more complex but more efficient. What do you all think?

caio commented 6 years ago

Another obvious alternative that escaped my mind is to just keep it as is. It will still work, just isn't the encouraged way to go about it for most use cases.

techalchemy commented 6 years ago

Wow what is this crazy fancy docker syntax. When was this introduced? Anyway we're in no rush to change it but it's worth having the discussion, as we should definitely be aware of it and being proactive is better than being reactive. Many thanks for kicking it off.

I'm far from an expert when it comes to optimal docker configurations, what would you suggest? I'll tag @erinxocon as well for input

caio commented 6 years ago

Haha the multi-build stuff has been around for about slightly more than a year. I'm far from an expert myself, but my take on it depends on what's the goal with having the Dockerfile here:

If it's about being more generally useful, this can go big very quickly (think docker-library/python), but that's a lot of work (and I'm not sure we would be able to go very far on usefulness due to system dependencies).

And if it's about a quick "getting started" kind of thing: keep the onbuild rules, but be more explicit about it and its gotchas. That to me means appending -onbuild to the image name on dockerhub and having targeted documentation giving usage directions and how to evolve from it when the time comes.

Were it up to me I'd go for the latter as it seems to strike a better balance between effort and usefulness.

caio commented 6 years ago

Hey all,

I've just realized that what's been deprecated are the official onbuild images, not the directives per se, so I'm closing the issue. Having a -onbuild on the image name would be nice for clarity but ithere's nothing to be acted upon.

Sorry for the fuss!