Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker: disable caching for a specific stage

Tags:

docker

I have a multi-stage Dockerfile. In stage one, I git clone from a github repo. In later stage, I do other stuff like pip etc and use a file from stage 1. I'd like to only disable caching for the first stage.

It looks like docker build --target stage1 --no-cache doesn't do what I want.

Is there a way to disable only a certain stage?

My Dockerfile looks like this:

FROM yijian/git-alpine
WORKDIR /tmp
RUN git clone https://github.com/abc/abc.git


FROM python:3.5.3-slim

RUN mkdir /app
ADD requirements.txt /app
ADD pip/pip.conf /root/.pip/pip.conf
WORKDIR /app
RUN pip3 install --upgrade pip && \
    pip3 install pbr && \
    pip3 install -r requirements.txt
ADD server.py /app
ADD docker/start.sh /app
RUN chmod a+x /app/start.sh
COPY --from=0 /tmp/abc/directory /usr/local/lib/python3.5/site-packages/abc/directory


EXPOSE 9092
ENTRYPOINT ["./start.sh"]
like image 574
lang2 Avatar asked Sep 01 '25 03:09

lang2


1 Answers

I don't believe that a single Dockerfile can have caching disabled for a specific state. That might make a nice feature request but I would rather see that as a declarative statement in the file rather than on the command line.

According to Docker's reference site: https://docs.docker.com/engine/reference/commandline/build/#usage

The "--target" flag allows you to select a target stage from a Dockerfile, meaning that it would only run that part of the Dockerfile. I would expect that the --no-cache flag would work in conjunction with this flag, however I wouldn't expect the other sections of the Dockerfile to run.

I believe that what you want to occur would take multiple commands which may defeat the purpose of having a multistage Dockerfile.

It would take more work, but depending on what you want to cache, you could possible include a script, such as bash or powershell, which can accomplish this goal.

Another option (depending on your needs) may be to use a separate Docker container which caches just what you need. For instance, I created a CI build which uses a Dockerfile that only imports dependencies and then my main build happens in a container that references that first container. I have done this with "dotnet restore" commands, so that the dependencies are preloaded and also have done this using "npm install". This method would work with any package management tool which allows you to specify a source. so where you have a project.json, you can extract the common dependencies and call it cache.package.json, then build a base image that has already done the heavy downloading for you, then ideally when you run this again during your more frequent builds it needs to pull less. Take advantage of the layered approach Docker offers!

like image 89
Collin Yeadon Avatar answered Sep 02 '25 21:09

Collin Yeadon