Docker | マルチビルド

Docker イメージの容量を小さくするのにマルチビルドという方法を試してみる。

Hello, world を表示する C 言語のアプリをビルドするイメージとアプリケーションを実行するイメージに分けてビルドする。

ファイル構成

main.c

1
2
3
4
5
6
#include <stdio.h>

void main()
{
printf("Hello, world\n");
}

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM alpine:latest
COPY ./main.c /root/main.c
WORKDIR /root
RUN apk --update add \
gcc \
musl-dev \
&& gcc -static -o hello main.c

FROM alpine:latest
WORKDIR /root
COPY --from=0 /root/hello ./
CMD ["/root/hello"]

ビルドする

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ sudo docker build -t hello --no-cache ./
Sending build context to Docker daemon 6.144kB
Step 1/8 : FROM alpine:latest
---> a24bb4013296
Step 2/8 : COPY ./main.c /root/main.c
---> 120ef9f314de
Step 3/8 : WORKDIR /root
---> Running in b5e42b217bc6
Removing intermediate container b5e42b217bc6
---> e4446fed71d7
Step 4/8 : RUN apk --update add gcc musl-dev && gcc -static -o hello main.c
---> Running in 01ef924aec81
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
(1/13) Upgrading musl (1.1.24-r8 -> 1.1.24-r10)
(2/13) Installing libgcc (9.3.0-r2)
(3/13) Installing libstdc++ (9.3.0-r2)
(4/13) Installing binutils (2.34-r1)
(5/13) Installing gmp (6.2.0-r0)
(6/13) Installing isl (0.18-r0)
(7/13) Installing libgomp (9.3.0-r2)
(8/13) Installing libatomic (9.3.0-r2)
(9/13) Installing libgphobos (9.3.0-r2)
(10/13) Installing mpfr4 (4.0.2-r4)
(11/13) Installing mpc1 (1.1.0-r1)
(12/13) Installing gcc (9.3.0-r2)
(13/13) Installing musl-dev (1.1.24-r10)
Executing busybox-1.31.1-r16.trigger
OK: 140 MiB in 26 packages
Removing intermediate container 01ef924aec81
---> 4e086cff991e
Step 5/8 : FROM alpine:latest
---> a24bb4013296
Step 6/8 : WORKDIR /root
---> Running in b20a4ad4ec84
Removing intermediate container b20a4ad4ec84
---> 843085070e96
Step 7/8 : COPY --from=0 /root/hello ./
---> a80c83a8438d
Step 8/8 : CMD ["/root/hello"]
---> Running in 5fc7b2ddb8e8
Removing intermediate container 5fc7b2ddb8e8
---> bd41c93c50be
Successfully built bd41c93c50be
Successfully tagged hello:latest

実行

hello アプリを実行する

1
2
$ sudo docker run hello
Hello, world

確認

Docker イメージ内に開発環境がインストールされていないことを確認する。

1
2
3
4
5
$ sudo docker run -it --rm hello /bin/ash
~ # ls
hello
~ # gcc
/bin/ash: gcc: not found

Docker イメージの容量を確認する。

1
2
$ sudo docker images | grep hello
hello latest bd41c93c50be 10 minutes ago 5.67MB

Alpine:latest の Docker イメージの容量が 5.57MB なのでかなり小さくイメージを作成できた。

1
2
$ sudo docker images | grep alpine
alpine latest a24bb4013296 6 months ago 5.57MB