Build caching with Docker Compose and Docker

This is just a quick note on building images with docker-compose and how caching may affect iterative development.

For demonstration purposes, imagine a simple project, as follows…

Project Directory

Dockerfile contents

docker-compose.yml contents

If you start the service, using…

…Docker Compose will helpfully build an image from the Dockerfile  run it.  So far so good.

Now, if I modify the code in  run.py tainting the file…

… and then down / up the service, will the running container include the latest changes in run.py , or an older version?  Hmm…!

The answer is… the older build of the image will be reused!  The running container will not reflect my changes to run.py.

So why is this?  Because an image already exists satisfying the spec in docker-compose.yml, Docker Compose will run the existing image unless explicitly instructed to build the image again.  It’s easy to specify a build step, either as a standalone command to docker-compose or as a parameter to the up  command:

This is fairly intelligent, as it will reuse cached layers as much as possible and only rebuild the parts of the image that must be rebuilt.

If you don’t want any layers to be reused (for example, if one of your Dockerfile commands installs a package and the package has changed externally), you can add the  --no-cache option:

However, this will force rebuilding all the layers, so in my example above it needs to install redis again rather than just use the existing cache.

Hope this helps.

2 thoughts on “Build caching with Docker Compose and Docker

  1. in docker-compose.yml use
    “””
    app:
    build: .
    volumes: ./src /app
    “””
    and del line ‘COPY ./src /app’ from Dockerfile.
    You can add it back later, for production

    1. Hi Andrey,

      I see your idea about mounting a volume, and I’d add that with this method, you likely want to mark the volume as read only to prevent in-container processes from writing out to your host’s files. I’m a big fan of changing as little as possible between production and dev, so keeping the Dockerfile the same is advantageous from my perspective. But your suggestion certainly would avoid the caching gotcha.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

Categories

Archives

GiottoPress by Enrique Chavez