Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent docker from building the image from scratch after making changes to the code

A docker newbie, trying to develop in a docker container; I have a problem which is every time I make a single line change of code and try to rerun the container, docker will rebuild the image from scratch which takes a very long time; How should I set up the project correctly so it makes the best use of cache? Pretty sure it doesn't have to reinstall all the apt-get and pip installs (btw I am developing in python) whenever I make some changes to the source code. Anyone have any idea what I am missing. Appreciate any help.

My current docker file:

FROM tiangolo/uwsgi-nginx-flask:python3.6

# Copy the current directory contents into the container at /app
ADD ./app /app

# Run python's package manager and install the flask package
RUN apt-get update -y \
    && apt-get -y install default-jre \
    && apt-get install -y \
    build-essential \
    gfortran \
    libblas-dev \
    liblapack-dev \
    libxft-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
ADD ./requirements.txt /app/requirements.txt
RUN pip3 install -r requirements.txt
like image 459
Psidom Avatar asked Oct 18 '17 15:10

Psidom


People also ask

Should I rebuild docker image on every code change?

You don't need to rebuild your Docker image in development for each tiny code change. If you mount your code into your dev container, you don't have to build a new image on every code change and iterate faster.

How do I stop docker container gracefully?

docker rm -f The final option for stopping a running container is to use the --force or -f flag in conjunction with the docker rm command. Typically, docker rm is used to remove an already stopped container, but the use of the -f flag will cause it to first issue a SIGKILL.


1 Answers

Once the cache breaks in a Dockerfile, all of the following lines will need to be rebuilt since they no longer have a cache hit. The cache search looks for an existing previous layer and an identical command (or contents of something like a COPY) to reuse the cache. If both do not match, then you have a cache miss and it performs the build step. For your scenario, you simply need to reorder your lines to make sure the frequently changing part is at the end rather than the beginning of the file:

FROM tiangolo/uwsgi-nginx-flask:python3.6

# Run python's package manager and install the flask package
RUN apt-get update -y \
    && apt-get -y install default-jre \
    && apt-get install -y \
    build-essential \
    gfortran \
    libblas-dev \
    liblapack-dev \
    libxft-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip3 install -r requirements.txt

# Copy the current directory contents into the container at /app
COPY app /app

I've also modified your ADD lines to COPY because you don't need the extra features provided by ADD.

During development, I'd recommend mounting app as a volume in your container so you don't need to rebuild the image for every code change. You can leave the COPY app /app inside your Dockerfile and the volume mount will simply overlay the directory, hiding anything in your image at that location. You only need to restart your container to pickup your modifications. Once finished, a build will create an image that looks identical to your development environment.

like image 70
BMitch Avatar answered Sep 28 '22 08:09

BMitch