Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 27d6a6c

Browse files
authored
Merge pull request #150 from pzelnip/codependentcodr/ch264/docker-images-reducing-size
Add post on reducing Docker image sizes [ch264]
2 parents 0095bd6 + 2261e44 commit 27d6a6c

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ s3_upload:
8989
docker run -e AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) -e AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) --rm -it -w /build $(SITE_NAME):latest ./s3_push.sh
9090

9191
safety:
92-
docker run -it --rm $(SITE_NAME):latest safety check -r requirements.txt --full-report
92+
echo "move safety to codependentcodrbase, see https://app.clubhouse.io/codependentcodr/story/265/move-safety-check-to-codependentcodrbase"
93+
# docker run -it --rm $(SITE_NAME):latest safety check -r requirements.txt --full-report
9394

9495
bandit:
9596
docker run -it --rm $(SITE_NAME):latest bandit . -r

content/docker-and-image-sizes.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
Title: Docker and Image Sizes
2+
Date: 2018-08-11 19:30
3+
Modified: 2018-08-11 19:30
4+
Category: Posts
5+
tags: docker,devops
6+
cover: static/imgs/default_page_imagev2.jpg
7+
summary: I was surprised & learned something about building Docker images.
8+
9+
So this surprised me. I had a Dockerfile that looked basically like this:
10+
11+
```dockerfile
12+
FROM alpine:latest
13+
14+
RUN apk add --no-cache --update \
15+
python3 nodejs-current-npm make git curl
16+
17+
RUN python3 -m ensurepip
18+
RUN pip3 install --upgrade pip
19+
20+
RUN npm install -g markdownlint-cli
21+
22+
# needed for one of the packages in requirements.txt
23+
RUN apk add --no-cache --update python3-dev gcc build-base
24+
25+
COPY requirements.txt /build/requirements.txt
26+
RUN pip3 install -r /build/requirements.txt
27+
```
28+
29+
Building this image resulted in an image that `docker images` reported as 379MB in
30+
size. That's a little large so I wanted to trim.
31+
32+
Since those packages installed just before copying
33+
`requirements.txt` to the image were only there to be able to *install* a package,
34+
there's no reason for them to remain in the image. Cool, so we can turf them to
35+
save on image size:
36+
37+
```dockerfile
38+
FROM alpine:latest
39+
40+
RUN apk add --no-cache --update \
41+
python3 nodejs-current-npm make git curl
42+
43+
RUN python3 -m ensurepip
44+
RUN pip3 install --upgrade pip
45+
46+
RUN npm install -g markdownlint-cli
47+
48+
# needed for one of the packages in requirements.txt
49+
RUN apk add --no-cache --update python3-dev gcc build-base
50+
51+
COPY requirements.txt /build/requirements.txt
52+
RUN pip3 install -r /build/requirements.txt
53+
54+
# cleanup unneeded dependencies
55+
RUN apk del python3-dev gcc build-base
56+
```
57+
58+
Sweet, and this resulted in an image size of *381MB*, a savings of *NEGATIVE 2MB*.
59+
Wait.... WAT?
60+
61+
![<INSERT ALT TEXT HERE>]({filename}/static/imgs/wat.jpg)
62+
63+
So I *removed* some stuff and ended up with an image that's a few MB's *larger*?
64+
How does that work?
65+
66+
And this is where if we want to get technical, we start talking about how Docker
67+
uses a layered filesystem and as such (not entirely unlike Git) once something is
68+
added to an image, it can't really (or at least easily) be removed.
69+
70+
See this issue which mentions what I'm talking about:
71+
<https://github.com/gliderlabs/docker-alpine/issues/45>
72+
73+
So what do we do? Well, we *combine* the operations into a single Docker instruction:
74+
75+
```dockerfile
76+
FROM alpine:latest
77+
78+
RUN apk add --no-cache --update \
79+
python3 nodejs-current-npm make git curl
80+
81+
RUN python3 -m ensurepip
82+
RUN pip3 install --upgrade pip
83+
84+
RUN npm install -g markdownlint-cli
85+
86+
COPY requirements.txt /build/requirements.txt
87+
88+
RUN apk add --no-cache --update python3-dev gcc build-base && \
89+
pip3 install -r /build/requirements.txt && \
90+
apk del python3-dev gcc build-base
91+
```
92+
93+
Because the add & the removal of the apk packages are a single Docker instruction
94+
they don't inflate the size of the built image (you can think of layers as being
95+
"checkpoints" after each instruction in a `Dockerfile`).
96+
97+
With this change my image size dropped *significantly*. How much? Let's let the
98+
tool tell us:
99+
100+
```shell
101+
$ docker images
102+
REPOSITORY TAG IMAGE ID CREATED SIZE
103+
someimage combineops 1744771da3fa About a minute ago 216MB
104+
someimage removepckgs fc5877e2afad 4 minutes ago 381MB
105+
someimage original b6e5e43b22e0 5 minutes ago 379MB
106+
```
107+
108+
That is, it dropped from *379MB* to *216MB*. Not a bad savings at all.
109+
110+
This is a classic "time vs space" tradeoff though. Because I had to move the `requirements.txt`
111+
line up, that means that builds of this image are often slower (because of the way the Docker
112+
cache works, if I change the requirements.txt file then it'll have to install those apk packages
113+
any time `requirements.txt` changes). However, I think the savings in space (40%+) is worth it.

content/static/imgs/wat.jpg

43.1 KB
Loading

0 commit comments

Comments
 (0)