Apa yang Dibangun oleh Docker Multi-Stage?

Bangunan Docker Multi-tahap adalah fitur yang diperkenalkan dalam Docker 17.05 yang memungkinkan anda menggunakan beberapa kali pernyataan dalam sebuah Dockerfile tunggal. Setiap instruksi memulai tahap baru, yang dapat memiliki gambar dasar, dependensi, dan perintah sendiri. Artefak dapat disalin secara selektif dari satu tahap ke tahap lain, sementara gambar akhir hanya mempertahankan apa yang sangat diperlukan untuk menjalankan aplikasi. Pendekatan ini menghilangkan kebutuhan untuk rantaian manual Dockerfiles atau mengandalkan skrip build complex, dan itu mengurangi ukuran gambar secara dramatis dengan excluding compiler, dan perpustakaan antarmedia.

Ide intinya adalah untuk memisahkan lingkungan build dari lingkungan runtime. Dalam sebuah bangunan panggung tunggal yang khas, seorang pengembang memasang semua alat build (misalnya, kompiler, manajer paket, kerangka kerja uji coba) dalam gambar yang sama yang akan digunakan untuk produksi. Yang mengapungkan gambar dan meningkatkan permukaan serangan. Pembangunan multi-tahap menyelesaikan hal ini dengan menggunakan gambar yang kaya tebal, kaya fitur untuk kompilasi dan kemudian menyalin hanya artefak yang dihasilkan ke dalam gambar runtime minimal seperti atau .

Manfaat dari Bangun Multi-Stage

Keuntungan mengadopsi bangunan multi-tahap melebihi pengurangan ukuran sederhana. mereka memiliki dampak besar pada keamanan, kestabilan, dan kecepatan penyebaran.

1.Urangkan Ukuran Gambar

Dengan membuang ketergantungan build-time, membangun multi-tahap sering mengecilkan gambar hingga 50% hingga 90%. Sebagai contoh, aplikasi Node.js yang dibangun menggunakan penuh image (lebih dari 300MB) dapat dilendirkan ke bawah 20MB dengan menyalin hanya folder yang dibangun menjadi basis . tabungan penyimpanan ini langsung diterjemahkan ke kali tarik yang lebih cepat, bandwidth jaringan yang lebih sedikit, dan biaya registry yang lebih rendah.

2. Keamanan yang Lebih Baik

Setiap paket atau alat yang terpasang dalam sebuah gambar kontainer adalah potensi kerentanan. Pembangunan multi-tahap memungkinkan anda untuk mengecualikan kompiler, debugger, dan pustaka pengembangan dari gambar akhir, secara signifikan mengurangi permukaan serangan. Anda bahkan dapat menggunakan gambar seperti atau untuk tahap runtime, yang hanya berisi minimum kosong untuk mengeksekusi biner aplikasi.

2. Proses Pembangunan Streamlined

Semua langkah pembangunan didefinisikan dalam Dockerfile tunggal, membuat proses itu mandiri dan mudah untuk versi. CI/CD pipeline mendapatkan keuntungan dari satu titik masuk: Dockerfile. Tidak perlu mempertahankan build scripts yang terpisah atau manual cleanup steps.

4. Keberbaikan dan Keberlanjutan yang Dipertingkatkan

Karena seluruh bangunan ditangkap dalam satu Dockerfile, pengembang atau sistem apapun dapat mereproduksi lapisan yang sama persis. Penggunaan tag versi spesifik untuk gambar dasar lebih lanjut menjamin membangun secara konsisten di seluruh lingkungan.

Bangunan Multi-Stage Dockerfile: Langkah demi Langkah

walkthrough ini meliputi pembuatan sebuah produksi ⁇ siap multi ⁇ tahap Dockerfile untuk sebuah Node.js dan aplikasi React. Prinsip-prinsip yang sama berlaku untuk bahasa terkompilasi manapun.

1. Rencanakan Tahap Anda

Sebelum menulis kode, petakan tahap yang Anda butuhkan.

  • [[EfolfLT:0]]Builder stage ⁇ pasang semua alat-alat pembangunan, pasang dependensi, dan jalankan perintah build.
  • [[EfleksifT:0]]Runtime stage ⁇ menggunakan gambar dasar minimal, menyalin hanya artefak yang dibangun dari tahap pembangun, dan mendefinisikan perilaku runtime.

Untuk proyek kompleks, Anda dapat menambahkan tahap intermediate untuk tes, analisis statik, atau kompresi aset.

2. Tulis Panggung Pembina

Mulai dari toolchain yang diperlukan. Gunakan namakan tahap dengan untuk merujuk mereka nanti. Untuk Node.js:

FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

Poin kunci:

  • Nafles Penggunaan untuk pemasangan ketergantungan yang deterministik, lebih cepat.
  • ¡Cear perintah sebagai lapisan terpisah ketika memungkinkan untuk memanfaatkan caching.
  • Alat-alat pembangunan pemasangan tools (seperti TypeScript, webpack) dalam tahap ini saja.

* 3) Menambah Tahap Ujian Menengah (Opsional)

Untuk menegakkan kualitas kode, tambahkan tahap yang menjalankan tes. Tahap ini dapat menggunakan kembali gambar pembangun atau memasang alat tambahan.Karena bukan tahap akhir, kegagalan tes tidak akan hadir dalam gambar akhir.

FROM builder AS test
RUN npm run test

Anda dapat menjalankan tahap ini dalam CI pipeline anda dengan untuk menangkap kegagalan lebih awal tanpa membangun seluruh gambar akhir.

4. Takrifkan Tahap Runtime

Untuk aplikasi React, gambar runtime dapat berupa server Nginx. Untuk API backend, mungkin berupa gambar dasar yang tidak tertandingi atau Alpine minimal dengan runtime Node.js. Salin hanya artifak penting menggunakan .

FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

¡Jika Anda membutuhkan waktu jalan Node.js, hindari menyalin dari pembangun; sebaliknya pasang ulang dependensi produksi dalam tahap waktu jalan:

FROM node:14-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]

g. 5. Bina dan Uji Gambar

COFINES gambar akhir menggunakan perintah standar:

docker build -t myapp:latest .

Untuk memverifikasi ukuran, jalankan dan bandingkan dengan satu ⁇ peringkat membangun. Jalankan kontainer dan konfirmasi aplikasi merespon dengan benar:

docker run -d -p 8080:80 myapp:latest
curl http://localhost:8080

Praktek Terbaik untuk Bangun Multi-Stage

  • Gunakan tag gambar dasar spesifik ⁇ evert untuk mencegah kejutan. Prefer atau .
  • ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ dan Sebelum sisa kode sumber sehingga lapisan hanya tidak berlaku apabila dependensi berubah.
  • [[GALFLT:0]]Leverage buildKit[]] ⁇ aktifkan BuildKit dengan untuk build yang lebih cepat, inline caching, dan paralelisme yang lebih baik.
  • [[EfleksifFLT:0]]Create multiple tahap akhir untuk lingkungan yang berbeda ⁇ Misalnya, tahap pengembangan dengan alat debugging dan tahap produksi dengan gambar dasar yang mengeras.
  • Use untuk pembangunan builds]] ⁇ dalam pengembangan anda dapat berhenti pada tahap untuk mendapatkan reload langsung dan peta sumber, kemudian membangun kembali dengan untuk produksi.
  • [[Objek- rahasia] Jaga rahasia keluar dari gambar ⁇ gunakan bendera Docker BuildKit jika Anda perlu melewatkan kredensial selama membangun; jangan pernah menyertakannya dalam gambar akhir.

Corak Umum dan Penggunaan Kasus

kompiled Languages (Go, Rust, C++)

Untuk binary statis, tahap runtime dapat menggunakan (gambar dasar kosong). Hanya biner dan mungkin berkas konfigurasi yang disalin. Contoh untuk Go:

FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .

FROM scratch
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]

Aplikasi Python X

¡Foldon Gunakan tahap pembangun dengan untuk memasang dependensi dan mengkompilasi ekstensi C apapun, kemudian hanya salin paket yang dipasang ke tahap runtime:

FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .

FROM python:3.11-slim
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app /app
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

Frontend yang Diambil oleh Pelayan API

Bangun kedua depan dan belakang di satu Dockerfile. Gunakan tahap pembangun terpisah untuk masing-masing, kemudian salin kedua artefak ke gambar waktu jalan tunggal:

FROM node:14-alpine AS frontend-builder
WORKDIR /app
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ .
RUN npm run build

FROM node:14-alpine AS api-builder
WORKDIR /app
COPY api/package*.json ./
RUN npm ci
COPY api/ .
RUN npm run build

FROM node:14-alpine
WORKDIR /app
COPY --from=frontend-builder /app/build ./public
COPY --from=api-builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]

Penembakan Masalah Proyek Multi-Stage Builds

  • OCLC [[fLAST:0]]Layer caching tidak bekerja ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ [[FLT [[FLT [[FLT [[FLT:
  • [[ELAG Artifact tidak ditemukan]] ⁇ verifikasi jalur dalam pernyataan . Tahap pembangun harus menghasilkan output di lokasi yang ditentukan. Gunakan untuk debug.
  • [[GALAT:0]]cret secret bocoran ⁇ jangan pernah salin seluruh direktori yang mungkin berisi atau . Explicitly hanya menyalin berkas yang dibutuhkan.
  • [[EfolsonFLT:0]] Gambar final besar meskipun multi-tahap ⁇ periksa apakah Anda tidak sengaja menyalin atau seluruh sumber. Gunakan untuk melihat ukuran lapisan.

Kekecualian Kesimpulan

Bangunan Docker Multi-tahap adalah batu penjuru dari kontainerisasi modern. Mereka memungkinkan Anda untuk kapal ramping, mengamankan gambar sementara menjaga proses membangun sederhana dan didokumentasikan dalam satu Dockerfile tunggal. Dengan memisahkan kekhawatiran antara membangun dan runtime, Anda dapat secara drastis mengurangi ukuran gambar, meningkatkan keamanan, dan jalur aliran CI/CD pipa. Teknik yang ditunjukkan di sini berlaku untuk hampir semua stack ⁇ whether Anda membangun Node.js, Pergi, Python, Jawa, atau aplikasi frontend. Mulai dengan mengubah Dockerfiles Anda yang sudah ada ke multi-stage, dan Anda akan segera melihat perbaikan dalam membangun, mengerahkan kecepatan, dan biaya keseluruhan infrastruktur.

Untuk lebih detail, mengacu pada official Docker multi-tahap build dokumentasi[ dan Dockerfile best practice guide. Contoh-contoh Real ⁇ world juga tersedia dalam Docker Library dokumentasi.