File caching in container
What is layer
In Docker, a "layer" refers to a read-only filesystem that contains files and metadata that are used to build a Docker image. Docker images are composed of multiple layers, and each layer represents a set of changes or instructions in the Dockerfile. Layers are stacked on top of each other, and when you run a Docker container, a writable container layer is added on top of the read-only layers.
Check the layers of a built image using docker history <container>
docker history vue-app
IMAGE CREATED CREATED BY SIZE COMMENT
9b08c5ae017c 17 hours ago CMD ["npm" "run" "serve"] 0B buildkit.dockerfile.v0
<missing> 17 hours ago EXPOSE map[8080/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 17 hours ago ENV API_URL=http://api.myapp.com 0B buildkit.dockerfile.v0
<missing> 17 hours ago USER app 0B buildkit.dockerfile.v0
<missing> 17 hours ago RUN /bin/sh -c addgroup app && adduser -S -G… 4.87kB buildkit.dockerfile.v0
<missing> 17 hours ago RUN /bin/sh -c npm install # buildkit 223MB buildkit.dockerfile.v0
<missing> 17 hours ago RUN /bin/sh -c apk upgrade # buildkit 8.52MB buildkit.dockerfile.v0
<missing> 17 hours ago COPY . . # buildkit 493kB buildkit.dockerfile.v0
<missing> 19 hours ago WORKDIR /app 0B buildkit.dockerfile.v0
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["node"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) COPY file:4d192565a7220e13… 388B
<missing> 2 weeks ago /bin/sh -c apk add --no-cache --virtual .bui… 7.82MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV YARN_VERSION=1.22.19 0B
<missing> 2 weeks ago /bin/sh -c addgroup -g 1000 node && addu… 172MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV NODE_VERSION=21.1.0 0B
<missing> 6 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 6 weeks ago /bin/sh -c #(nop) ADD file:756183bba9c7f4593… 7.34MB
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
According to the result, changes of npm install
made 223MB
each time we build.
To get a caching and reusability for those packages, what can we do?
Well, for each layer, docker will check all changes(files for example) between the current and previous. If not change applied in the layer, the next RUN
will not be executed.
Implementation
FROM node:alpine
WORKDIR /app
RUN apk upgrade
# copy package.json and package-lock.json
# before npm install
COPY package*.json .
RUN npm install
COPY . .
RUN addgroup app && adduser -S -G app app
USER app
ENV API_URL=http://api.myapp.com
EXPOSE 8080
CMD ["npm", "run", "serve"]
2
3
4
5
6
7
8
9
10
11
12
13
If now rebuild image twice, we can see all layers were cached for sure since we didn't change anything. So try it out with adding/removing dependencies from current node project to see what happens.
docker build --tag vue-app .
2023/11/10 16:15:05 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed
[+] Building 2.0s (12/12) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 264B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 53B 0.0s
=> [internal] load metadata for docker.io/library/node:alpine 1.9s
=> [1/7] FROM docker.io/library/node:alpine@sha256:df76a9449df49785f89d517764012e3396b063ba3e746e8d88f36e9f332b1864 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 733B 0.0s
=> CACHED [2/7] WORKDIR /app 0.0s
=> CACHED [3/7] RUN apk upgrade 0.0s
=> CACHED [4/7] COPY package*.json . 0.0s
=> CACHED [5/7] RUN npm install 0.0s
=> CACHED [6/7] COPY . . 0.0s
=> CACHED [7/7] RUN addgroup app && adduser -S -G app app 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:d70d1656b8d292bfaecdee9f943e07580cdbabd8dd9ce7753c94645af2b0f6d9 0.0s
=> => naming to docker.io/library/vue-app 0.0s
What's Next?
View a summary of image vulnerabilities and recommendations → docker scout quickview
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25