As seen in my last post, the node image on docker is over 1GB. I was curious what contributed to that, so I ran and attached myself to a shell in it.
$ podman run -dt node bash $ podman attach -l root@...:/#
A quick query of installed packages and their sizes gave me these top 30 packages:
dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -nr | head -n 30
Size (kB) |
Deb Package |
% (of installed packages) |
---|---|---|
68,236 | gcc-12 | 7.65 |
47,784 | libicu-dev | 5.36 |
44,477 | git | 4.99 |
36,170 | libicu72 | 4.05 |
36,161 | g++-12 | 4.05 |
33,848 | cpp-12 | 3.79 |
28,862 | libperl5.36 | 3.23 |
19,446 | libstdc++-12-dev | 2.18 |
18,062 | coreutils | 2.02 |
17,816 | perl-modules-5.36 | 1.99 |
16,203 | libx265-199 | 1.81 |
15,021 | binutils-common | 1.68 |
14,577 | mercurial-common | 1.63 |
14,284 | libgcc-12-dev | 1.60 |
12,986 | libc6 | 1.45 |
12,303 | libssl-dev | 1.38 |
11,957 | libc6-dev | 1.34 |
11,428 | binutils-x86-64-linux-gnu | 1.28 |
10,909 | librsvg2-2 | 1.22 |
10,076 | sq | 1.13 |
10,075 | libglib2.0-dev | 1.13 |
9,404 | libglib2.0-data | 1.05 |
8,323 | libpython3.11-stdlib | 0.93 |
8,130 | libmagic-mgc | 0.91 |
8,017 | libasan8 | 0.89 |
7,815 | libtsan2 | 0.87 |
7,638 | perl-base | 0.85 |
7,164 | bash | 0.80 |
6,761 | python3.11-minimal | 0.75 |
6,589 | linux-libc-dev | 0.73 |
Surprisingly, no packages for nodejs/npm are listed! I calculated the sum of the size of all installed packages, and got 891,320 kB, but overall disk usage in the image's final file system is 1,139,008 kB. That's a discrepancy of 247,688 kB!
Poking around to find some evidence of it, I see that npm is installed at /usr/local/bin/npm
. All of /usr/local
takes up 167,728 kB in the final image. Let's poke around and see which layer added that.
$ podman image tree node Image ID: 386e0be86bde Tags: [docker.io/library/node:latest] Size: 1.122GB Image Layers ├── ID: 7c85cfa30cb1 Size: 121.3MB ├── ID: a9af9831483f Size: 49.56MB ├── ID: 68731f6c1e1e Size: 181.4MB ├── ID: d396cdbdc3ad Size: 596.9MB ├── ID: 02f1f39c8ec9 Size: 22.53kB ├── ID: 4709b21dad1d Size: 164.8MB ├── ID: 24d9598c79a8 Size: 7.626MB └── ID: 19ba6ee0c874 Size: 3.584kB Top Layer of: [docker.io/library/node:latest] $ podman history node ID CREATED CREATED BY SIZE COMMENT 386e0be86bde 4 days ago /bin/sh -c #(nop) CMD ["node"] 0B <missing> 4 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-ent... 0B <missing> 4 days ago /bin/sh -c #(nop) COPY file:4d192565a7220e... 3.58kB <missing> 4 days ago /bin/sh -c set -ex && for key in 6A0... 7.63MB <missing> 4 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.22.19 0B <missing> 4 days ago /bin/sh -c ARCH= && dpkgArch="$(dpkg --pri... 165MB <missing> 4 days ago /bin/sh -c #(nop) ENV NODE_VERSION=20.7.0 0B <missing> 4 days ago /bin/sh -c groupadd --gid 1000 node && u... 22.5kB <missing> 5 days ago /bin/sh -c set -ex; apt-get update; apt-... 597MB <missing> 5 days ago /bin/sh -c apt-get update && apt-get insta... 181MB <missing> 5 days ago /bin/sh -c set -eux; apt-get update; apt... 49.6MB <missing> 5 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 5 days ago /bin/sh -c #(nop) ADD file:ce04d6a354feaef... 0B
Taking a peak in ~/.local/share/containers/storage/overlay
and doing a find against each of the layer IDs, looking for the npm binary, I get this:
./4709b21dad1d5d5cb88803c9c598c81fd9a94de38398ad002ec569cff33445c7/diff/usr/local/bin/npm ./4709b21dad1d5d5cb88803c9c598c81fd9a94de38398ad002ec569cff33445c7/diff/usr/local/lib/node_modules/corepack/shims/nodewin/npm ./4709b21dad1d5d5cb88803c9c598c81fd9a94de38398ad002ec569cff33445c7/diff/usr/local/lib/node_modules/corepack/shims/npm ./4709b21dad1d5d5cb88803c9c598c81fd9a94de38398ad002ec569cff33445c7/diff/usr/local/lib/node_modules/npm ./4709b21dad1d5d5cb88803c9c598c81fd9a94de38398ad002ec569cff33445c7/diff/usr/local/lib/node_modules/npm/bin/npm
Peaking at its directory structure, I see that that layer is 167,712 kB and accounts for all of /usr/local
, and its entirely node files. Some of the most notable disk usage is as follows:
Size (kB) | Path | Comment |
---|---|---|
93,524 | usr/local/bin/node | The binary itself. |
53,004 | usr/local/include/node/openssl/ | Most of this in its archs/ subdirectory, with 21 architectures' .h files. |
19,208 | usr/local/lib/node_modules/ | |
17,456 | usr/local/lib/node_modules/npm | |
14,308 | usr/local/lib/node_modules/npm/node_modules | Contains 196 modules, the largest as node-gyp at 3716 kB. |
So, there you have it. The node image is so large mostly because it contains a tonne of development .deb packages, and node-specific files take up ~164 MB, about 14% of the final image.