対応実施前
- express + typescript の hello world アプリを用意し、official の node image を利用した場合の image サイズ
REPOSITORY TAG IMAGE ID CREATED SIZE
test-node-app-before latest 620fd8e74f42 3 seconds ago 1.32GB
- package.json
"scripts": {
"start": "cross-env NODE_ENV=production ts-node --transpile-only src/server.ts",
- Dockerfile
- ts-node にて起動
- official の node image を利用
FROM node:12.18.1
WORKDIR /app
ENV JWT_SECRET="dummy" PORT="80"
COPY package.json /app
COPY src /app/src
RUN cd /app && npm install
CMD ["npm","start"]
対応内容
tsc コマンドで trance compile
- package.json の build に
tsc
を追加
"scripts": {
"build": "tsc",
tsconfig.json の target / module を書き換え
JavaScriptにはいくつかのモジュールパターン(CommonJSやAMD、ECMAScriptなど)がある。TypeScriptをJavaScriptに変換する際、どのモジュールパターンにするかをmoduleに指定する必要がある。
moduleには'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'esnext'などを指定できる。デフォルトはtarget === "es3" or "es5" ? "commonjs" : "es6"、つまりtargetがes3かes5ならcommonjsとなる。
- tsconfig.json の
target
とmodule
を以下に指定
{
"compilerOptions": {
"sourceMap": true,
"target": "es2017",
"module": "commonjs",
マルチステージビルドを実行 / apline linux を利用
- Dockerfile を以下のように編集
FROM node:12.18.1-alpine3.12 AS build
WORKDIR /app
COPY . /app
RUN npm ci && npm run build
FROM node:12.18.1-alpine3.12
WORKDIR /app
ENV JWT_SECRET="dummy" PORT="80"
COPY --from=build /app/dist /app/dist
COPY package.json /app
COPY package-lock.json /app
RUN npm ci --production
CMD ["npm","start"]
- Tips:
npm ci
コマンドを利用することで依存パッケージのダウンロードとインストールの高速化が実現できる
devDependencies に移動できるパッケージがないか確認する
- 以下が dependencies に記載されていたので修正
"jest": "^26.0.1",
"ts-jest": "^26.1.0",
"ts-node": "^8.10.2",
"tslint-config-airbnb": "^5.11.2",
"typescript": "^3.9.5"
結果
- 101MB まで image の容量を削減することができた
docker images
REPOSITORY TAG IMAGEID CREATED SIZE
test-node-app latest 9cdb52f0f5cf 2 hours ago 101MB