言語はNode.js.
変更前のDockerfile(alpine)
FROM node:12-alpine COPY example /example COPY app.js . COPY package*.json ./ RUN apk add git RUN npm install --production RUN apk update \ && apk add --no-cache curl fontconfig \ && curl -O https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \ && mkdir -p /usr/share/fonts/NotoSansCJKjp \ && unzip NotoSansCJKjp-hinted.zip -d /usr/share/fonts/NotoSansCJKjp/ \ && rm NotoSansCJKjp-hinted.zip \ && fc-cache -fv EXPOSE 3000 CMD node app.js
実際に運用する場合あまりシンプルなDockerfileにはならないんじゃないだろうか?
上記例だとnode_moduleにgitに依存しているものがある + 実行に日本語フォントが必要で追加でインストールしている。
変更前のDockerfile(distroless)
FROM node:12 as builder WORKDIR /work COPY example /example COPY app.js . COPY package*.json ./ RUN npm install RUN apt-get update \ && apt-get install curl fontconfig \ && curl -O https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \ && mkdir -p /usr/share/fonts/NotoSansCJKjp \ && unzip NotoSansCJKjp-hinted.zip -d /usr/share/fonts/NotoSansCJKjp/ \ && rm NotoSansCJKjp-hinted.zip \ && fc-cache -fv FROM gcr.io/distroless/nodejs:12 COPY example /example COPY app.js . COPY package*.json ./ COPY --from=builder /work/node_modules /node_modules COPY --from=builder /usr/share/fonts/NotoSansCJKjp /usr/share/fonts/NotoSansCJKjp EXPOSE 3000 CMD ["app.js"]
distrolessはShellやaptなどがないため追加でモジュールのインストール等が出来ない(正確には出来ないこともないかもしれないが面倒)
マルチステージビルドを使用してビルド後の必要なファイルをコピーするといったアプローチを取る。
マルチステージビルドについて少しざっくり説明するとas hogehogeで名前を付けたDockerイメージは後で使用することができる。最終的なイメージサイズには影響がない。
COPY --from=builder builderのパス 実行環境のパスでコピーができる。
最初ビルド用のDockerをnode:12-alpineにしていたがどうもdistrolessとベースイメージが異なるらしく(互換性がない)場合によっては実行時にエラーになる。
具体的にはSharpでエラーが発生した。
Error: 'linuxmusl-x64' binaries cannot be used on the 'linux-x64' platform. Please remove the 'node_modules/sharp' directory and run 'npm install' on the 'linux-x64' platform.
node:12-alpine → node:12に変更した場合、apkをaptに変更する必要がある(gitはデフォルトで入っているらしい)
CMDはデフォルトでnode.jsなのでアプリの起動はファイル名を指定するだけで良い。CMD node app.js は動作しない。
ビルドイメージのサイズについて
node:12-alpine+α 214MB ↓ gcr.io/distroless/nodejs:12 221MB
対応が面倒で放置していた軽微なセキュリティリスクも0件になっている。
参考
https://blog.inductor.me/entry/alpine-not-recommended