Peter Grainger の回答を拡張するDocker 17.05 以降で利用可能なマルチステージ ビルドを使用することができました。公式ページには次のように記載されています。
マルチステージ ビルドでFROM
は、Dockerfile で複数のステートメントを使用します。各FROM
命令は異なるベースを使用でき、それぞれがビルドの新しい段階を開始します。アーティファクトをあるステージから別のステージに選択的にコピーして、最終イメージに不要なものをすべて残すことができます。
ここでこれを念頭に置いて、Dockerfile
3 つのビルド ステージを含める例を示します。これは、クライアント Web アプリケーションの運用イメージを作成するためのものです。
# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
chmod 0700 /root/.ssh && \
ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
yarn --pure-lockfile --mutex file --network-concurrency 1 && \
rm -rf /root/.ssh/
# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod
# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]
.dockerignore
ファイルの内容を繰り返します(プロジェクトの結果のディレクトリがコピーされるのを.gitignore
防ぎます):node_modules
dist
.idea
dist
node_modules
*.log
イメージをビルドするコマンド例:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
SSH 秘密鍵にパスフレーズがない場合は、空のSSH_KEY_PASSPHRASE
引数を指定してください。
これがどのように機能するかです:
1)。最初の段階でのみpackage.json
、yarn.lock
ファイルとプライベート SSH キーが という名前の最初の中間イメージにコピーされsources
ます。今後 SSH キーのパスフレーズ プロンプトが表示されないようにするために、自動的に に追加されssh-agent
ます。最後にyarn
、コマンドは NPM から必要なすべての依存関係をインストールし、SSH 経由で Bitbucket からプライベート git リポジトリを複製します。
2)。第 2 段階では、Web アプリケーションのソース コードをビルドおよび縮小しdist
、次の中間イメージのディレクトリに配置しproduction
ます。installed のソース コードは、最初の段階で生成されたnode_modules
という名前のイメージから次の行でコピーされることに注意してください。sources
COPY --from=sources /app/ /app/
おそらく、次の行でもある可能性があります。
COPY --from=sources /app/node_modules/ /app/node_modules/
node_modules
ここには、最初の中間イメージからのディレクトリのみがSSH_KEY
あり、SSH_KEY_PASSPHRASE
引数はありません。ビルドに必要な残りのすべては、プロジェクト ディレクトリからコピーされます。
3)。第 3 段階では、名前が付けられた 2 番目の中間イメージからディレクトリezze/geoport:0.6.0
のみを含め、Web サーバーを起動するために Node Express をインストールすることで、タグ付けされる最終イメージのサイズを縮小します。dist
production
画像を一覧表示すると、次のような出力が得られます。
REPOSITORY TAG IMAGE ID CREATED SIZE
ezze/geoport 0.6.0 8e8809c4e996 3 hours ago 717MB
<none> <none> 1f6518644324 3 hours ago 1.1GB
<none> <none> fa00f1182917 4 hours ago 1.63GB
node carbon b87c2ad8344d 4 weeks ago 676MB
ここで、タグの付いていないイメージは、最初と 2 番目の中間ビルド ステージに対応します。
あなたが実行する場合
$ docker history ezze/geoport:0.6.0 --no-trunc
最終的なイメージでは、SSH_KEY
とについての言及は見られません。SSH_KEY_PASSPHRASE