Skip to content

Dockerfile: Resolve deps using pipenv/Pipefile(.lock) #496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 7, 2018

Conversation

javabrett
Copy link
Contributor

@javabrett javabrett commented Jul 27, 2018

Been experimenting with pipenv for reproducible Docker image builds and came-up with this approach for httpbin.

It makes a couple of Docker cacheability improvements - mainly because Pipfile and Pipfile.lock are added on their own before deps are installed, so changes to the rest of the source-code won't cause a cache-miss and re-download of all the dependencies.

I'm curious as to whether this is an intended use of pipenv ... it seems to help solve the problems for installing as Applications (versus Libraries) with pinned versions for dependencies for a specific build.

With reference to #493, with this change the built Docker image should contain greenlet version 0.14.3 (the locked version), and not the latest 0.14.4 which would be resolved by setup.py.

Fixed #493.


RUN pip3 install --no-cache-dir gunicorn /httpbin
EXPOSE 80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why the was moved here? (Also the ‘WORKDIR’). Couldn’t we move them again to top so we can avoid adding additional docker layers for these if ‘Pipfile.lock’ changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @steffenschroeder. Are you referring to the EXPOSE or the RUN pip3 (there might be a word missing from your question)?

In ordering statements, I tend to put things that folks might want to change locally more-frequently (e.g. as part of some dev/test cycle), that would cause little change themselves, towards the bottom of the file. That way if they need to be changed for some time, they only evict cache after them, which in this case is almost nothing as EXPOSE and CMD layers are almost free. Also the EXPOSE 80 belongs with the port 80 on the next line, since they will change together. EXPOSE is really only documentation anyway - nothing depends on it, so it should be late in the file.

WORKDIR could be avoided and is a behaviour change - prior to this the container default dir is /, this makes it /httpbin, which makes more sense to me. Either a WORKDIR or a cd /httpbin is required (in the first pip3 command) so that pipenv is in the correct directory containing Pipfile*.

This change does create extra layers, for the benefit of better Docker build-cache stick, which is only of real importance in a development-context. If Pipfile.lock changes then it follows that the dependencies layer needs to be rebuilt, along with all those after it. But splitting these means that changing only say core.py will no-longer invalidate the expensive download-and-install dependencies layer, which only depends on Pipfile and Pipfile.lock.

Note that the second pip3 command now only installs httpbin itself, since all the dependencies are already resolved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @javabrett for clarification. Now, as I understand your intends better, I completely agree with it.
Splitting the installation of the dependencies and httpbin itself is very good.
The EXPOSE 80 makes, with your explaination, also sense for me.
👍

…e pip3->setup.py for httpbin.

Also added Pipfile(.lock) prior to the remaining source, improving Docker image cacheability.

Git is also required to fetch pyyaml.

This results in more deterministic and reproducible image builds, since httpbin dependencies
are installed using locked versions from Pipfile.lock before httpbin is itself installed.

Fixed postmanlabs#493.
@kennethreitz kennethreitz merged commit f8ec666 into postmanlabs:master Nov 7, 2018
@javabrett javabrett deleted the docker-pipenv branch November 7, 2018 20:33
virgiliojr94 pushed a commit to virgiliojr94/httpbin-chat2desk that referenced this pull request Jul 1, 2023
Dockerfile: Resolve deps using pipenv/Pipefile(.lock)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Docker image build not deterministic/reproducible, uses setup.py not Pipenv.lock, differs from dev env
3 participants