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をインストールすることにより、タグ付けされる最終イメージのサイズを縮小します。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
。