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ます。インストール済みのソースコードは、最初のステージで作成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をインストールすることにより、タグ付けされる最終イメージのサイズを縮小します。distproduction
画像を一覧表示すると、次のような出力が得られます。
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。