7

I have a python package that I wrote and I want to use it within multiple docker builds.

However, I can't just install my local package situated outside of Dockerfile folder. And I don't want to copy the package into multiple projects.

So how do I keep my architecture DRY?

5

I'm not sure why people have downvoted you, other than there is a well documented and easy way to go about this.

Docker images are layered, and you can build all your essential-for-all-images packages into one new docker image of our own making, and then extend from that.

For example, when you write your docker file, your first line will be

FROM someothercontainer

What you can do is then create a new image to use in your "FROM" in all future containers that you write, that will have this built in. The trivial example is to build a container something like

FROM ubuntu
apt-get install python

And then build this image as my-image-with-python-installed or whatever works.

Then, in the later container where you want to install your own unique-to-each-container stuff, you write your Dockerfile as such:

FROM my-image-with-python-installed
ADD my-local-package
...

The documentation on Docker's page is a bit low level as they want you to build the smallest base images you can, but you can find it here: https://docs.docker.com/develop/develop-images/baseimages/

Your documentation for the FROM command comes in here https://docs.docker.com/engine/reference/builder/#from but you'll need to build your base image first, but there is loads of articles out there on how to do that.

Edit:

It's very common to have a base image stored in a repository, especially if the contents don't change. This way you can access it from different build machines and don't have to rebuild it often if at all, setting up small local repositories is very easy, and many artifact management tools have this feature built in as well. If, however, you're building images on the fly but they all still have a common base it isn't necessary to store that in a repository - you just build the base image first and then as its local to that build machine all other images built on that machine will be able to access it.

  • Just a note. You will have to distribute your base image somewhere, in order to don't have to add the other base images into the src of each project. Ideally, you have your own repository/registry of docker images. Or as many people do, have'em registered in Docker Hub. – Laiv Feb 8 '18 at 10:42
  • didn't mention but, you can enforce the Dockerfile to check out your library from a repository or from a repository of artefacts. Second is preferable due to the artefact is going to be compiled – Laiv Feb 8 '18 at 10:45
  • I'll update my answer @Laiv to include that point. Thanks. – Mitch Kent Feb 8 '18 at 11:12
  • This is so obvious as soon as you said it >_<. Thanks! – Roman Feb 8 '18 at 21:10
0

A nice pattern for a Dockerfile is something like this:

FROM ubuntu:18.04

RUN apt-get update && apt-get install -y python3 python3-pip

COPY requirements.txt /tmp/base_requirements.txt
RUN python3 -m pip install -r /tmp/base_requirements.txt

COPY my_package_name/ /usr/lib/python3.6/my_package_name/

This way the package is accessible in the path and can be imported.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.