Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker isn't caching Alpine apk add command

Everytime I build the container I have to wait for apk add docker to finish which takes a long time. Since everytime it downloads the same thing, can I somehow force Docker to cache apk's downloads for development purposes?

Here's my Dockerfile:

FROM golang:1.13.5-alpine

WORKDIR /go/src/app
COPY src .

RUN go get -d -v ./...
RUN go install -v ./...

RUN apk add --update docker

CMD ["app"]

BTW, I am using this part volumes: - /var/run/docker.sock:/var/run/docker.sock in my docker-compose.yml to use sibling containers, if that matters.

EDIT: I've found google to copy docker.tgz in Chromium:

# add docker client -- do not install docker via apk -- it will try to install
# docker engine which takes a lot of space as well (we don't need it, we need
# only the small client to communicate with the host's docker server)
ADD build/docker/docker.tgz /

What is that docker.tgz? How can I get it?

like image 715
koral Avatar asked Dec 13 '22 09:12

koral


2 Answers

Reorder your Dockerfile and it should work.

FROM golang:1.13.5-alpine
RUN apk add --update docker

WORKDIR /go/src/app
COPY src .
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["app"]

As you are copying before installation, so whenever you change something in src the cache will invalidate for docker installtion.

like image 149
Adiii Avatar answered Jan 05 '23 18:01

Adiii


Whenever you have a COPY command, if any of the files involve change, it causes every command after that to get re-run. If you move your RUN apk add ... command to the start of the file before it COPYs anything, it will get cached across runs.

A fairly generic recipe for most Dockerfiles to accommodate this pattern looks like:

FROM some-base-image

# Install OS-level dependencies
RUN apk add or apt-get install ...

WORKDIR /app

# Install language-level dependencies
COPY requirements.txt requirements.lock ./
RUN something install -r requirements.txt

# Install the rest of the application
COPY main.app ./
COPY src src/

# Set up standard run-time metadata
EXPOSE 12345
CMD ["/app/main.app"]

(Go and Java applications need the additional step of compiling the application, which often lends itself to a multi-stage build, but this same pattern can be repeated in both stages.)

like image 34
David Maze Avatar answered Jan 05 '23 19:01

David Maze