Memperluas jawaban Peter Grainger saya dapat menggunakan multi-stage build yang tersedia sejak Docker 17.05. Status halaman resmi:
Dengan pembuatan multi-tahap, Anda menggunakan beberapa FROM
pernyataan di Dockerfile Anda. Setiap FROM
instruksi dapat menggunakan basis yang berbeda, dan masing-masing memulai tahap baru pembangunan. Anda dapat secara selektif menyalin artefak dari satu tahap ke tahap lainnya, meninggalkan semua yang tidak Anda inginkan dalam gambar akhir.
Ingatlah ini di sini adalah contoh saya Dockerfile
termasuk tiga tahap membangun. Ini dimaksudkan untuk membuat gambar produksi aplikasi web klien.
# 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
mengulangi isi .gitignore
file (mencegah node_modules
dan mengakibatkan dist
direktori proyek tidak disalin):
.idea
dist
node_modules
*.log
Contoh perintah untuk membuat gambar:
$ docker build -t ezze/geoport:0.6.0 \
--build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
--build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
./
Jika kunci SSH pribadi Anda tidak memiliki frasa sandi, cukup tentukan SSH_KEY_PASSPHRASE
argumen kosong .
Begini Cara kerjanya:
1). Pada tahap pertama saja package.json
, yarn.lock
file dan kunci SSH pribadi disalin ke gambar perantara pertama bernama sources
. Untuk menghindari frasa sandi kunci SSH yang diminta, secara otomatis ditambahkan ssh-agent
. Akhirnya yarn
perintah menginstal semua dependensi yang diperlukan dari NPM dan klon repositori private git dari Bitbucket melalui SSH.
2). Tahap kedua membangun dan memperkecil kode sumber aplikasi web dan menempatkannya di dist
direktori gambar perantara berikutnya bernama production
. Perhatikan bahwa kode sumber yang diinstal node_modules
disalin dari gambar bernama sources
diproduksi pada tahap pertama oleh baris ini:
COPY --from=sources /app/ /app/
Mungkin itu juga bisa menjadi baris berikut:
COPY --from=sources /app/node_modules/ /app/node_modules/
Kami hanya memiliki node_modules
direktori dari gambar perantara pertama di sini, tidak ada SSH_KEY
dan SSH_KEY_PASSPHRASE
argumen lagi. Semua yang dibutuhkan untuk membangun disalin dari direktori proyek kami.
3). Pada tahap ketiga kami mengurangi ukuran gambar akhir yang akan ditandai sebagai ezze/geoport:0.6.0
dengan hanya memasukkan dist
direktori dari gambar perantara kedua bernama production
dan menginstal Node Express untuk memulai server web.
Listing gambar memberikan output seperti ini:
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
di mana gambar yang tidak di-tag terhubung ke tahap pembuatan lanjutan pertama dan kedua.
Jika Anda berlari
$ docker history ezze/geoport:0.6.0 --no-trunc
Anda tidak akan melihat menyebutkan dari SSH_KEY
dan SSH_KEY_PASSPHRASE
pada gambar akhir.