docker production code build docker production code build docker docker

docker production code build


In Docker, in general, you want to create an image of your software that contains all that is necessary for your Application to run on any machine. This is what Docker is used for: bind the Application and its dependencies into a single artifact so that it can run everywhere where Docker is installed.

The self-sufficient image is very handy when you use an orchestrator like Docker swarm. The orchestrator can run the container on any machine that is part of the network (i.e. the swarm) by pulling the image and starting a container. If nor the image neither the host contain all that it needs then the container fails.

There are cases where you need to change very easy the files inside the container as it runs, for example in development. In that case you mount a local directory from the host into the container (see volumes); in this way you just modify the files in the host and the modification is propagated immediately inside the container. Even in this case, your image should contain the files needed to run the Application on other machine; using a volume just hides them in the development environment.


It sounds like you're worried about two different, valid, problems:

  1. Ensuring an isolated/reproducible production environment.
  2. Ensuring an isolated/reproducible build environment (for building #1).

You can achieve both with the approach you suggested - have the build steps run as part of your Dockerfile. But this has the disadvantages that you mention - you're left with all of your source/development artifacts at runtime, unless you take explicit steps to remove them all.

Docker introduced multi-stage builds to somewhat alleviate this issue - it effectively allows you to "squash" multiple layers into one. But it doesn't eliminate the problem of needing to explicitly clean up.

So in my experience, the most common solution is indeed to build your artifact externally, and then COPY it into your production image.

That solves problem #1, but not #2. So go one step further - build your Docker image inside a Docker container! CI platforms are increasingly supporting this approach as a first-class concept - see e.g. Circle CI's Docker executor.