Table of Contents
Τι είναι πολυ-σταθερά Docker Builds;
Τα πολυστάδια Docker builds είναι ένα χαρακτηριστικό που εισήχθη στο Docker 17.05 που σας επιτρέπει να χρησιμοποιήσετε πολλαπλές [[LFT:0]] δηλώσεις μέσα σε ένα ενιαίο αρχείο Docker. Κάθε [[LFT:1] οδηγία ξεκινά ένα νέο στάδιο, το οποίο μπορεί να έχει τη δική της βασική εικόνα, εξαρτήσεις και εντολές. Τα αντικείμενα μπορούν να αντιγραφούν επιλεκτικά από το ένα στάδιο στο άλλο, ενώ η τελική εικόνα διατηρεί μόνο ό, τι είναι απολύτως απαραίτητο για την εκτέλεση της εφαρμογής. Αυτή η προσέγγιση εξαλείφει την ανάγκη να αλυσιδώσει με το χέρι Dockerfiles ή να βασιστεί σε πολύπλοκα σενάρια κατασκευής, και μειώνει δραματικά το μέγεθος της εικόνας με εξαίρεση τους μεταγλωττιστές, τις βιβλιοθήκες ανάπτυξης, και τα ενδιάμεσα αρχεία.
Η βασική ιδέα είναι να διαχωρίσουμε το περιβάλλον κατασκευής από το περιβάλλον χρόνου λειτουργίας. Σε ένα τυπικό μονοβάθμιο οικοδόμημα, ένας προγραμματιστής εγκαθιστά όλα τα εργαλεία κατασκευής (π.χ. μεταγλωττιστές, διαχειριστές πακέτων, πλαίσια δοκιμών) στην ίδια εικόνα που θα χρησιμοποιηθεί για την παραγωγή. Αυτό φουσκώνει την εικόνα και αυξάνει την επιφάνεια επίθεσης. Κατασκευάζει πολλά στάδια λύνοντας αυτό χρησιμοποιώντας μια παχιά, πλούσια σε χαρακτηριστικά εικόνα για την κατάρτιση και στη συνέχεια αντιγράφοντας μόνο τα αντικείμενα που προκύπτουν σε μια ελάχιστη εικόνα χρόνου λειτουργίας όπως ή ].
Οφέλη από Multi-Stage Builds
Τα πλεονεκτήματα της υιοθέτησης πολυβάθμιων κατασκευών υπερβαίνουν την απλή μείωση του μεγέθους.
1. Μειωμένο μέγεθος εικόνας
Με την απόρριψη εξαρτήσεων από τον χρόνο κατασκευής, τα πολυ-στάδια δομούν συχνά συρρικνώνονται τις εικόνες κατά 50% έως 90%. Για παράδειγμα, μια εφαρμογή Node.js που κατασκευάστηκε χρησιμοποιώντας την πλήρη εικόνα [ (πάνω από 300MB) μπορεί να αδυνατίσει κάτω από 20MB αντιγράφοντας μόνο τον ενσωματωμένο φάκελο ] σε μια βάση [[LFT:6]]. Αυτή η εξοικονόμηση αποθήκευσης μεταφράζεται άμεσα σε ταχύτερους χρόνους έλξης, λιγότερο εύρος ζώνης δικτύου και χαμηλότερο κόστος μητρώου.
2. Βελτιωμένη ασφάλεια
Κάθε εγκατεστημένο πακέτο ή εργαλείο σε μια εικόνα εμπορευματοκιβωτίων είναι μια πιθανή ευπάθεια. Κατασκευές πολλαπλών σταδίων σας επιτρέπουν να αποκλείσετε μεταγλωττιστές, αποσφαλματωτές, και βιβλιοθήκες ανάπτυξης από την τελική εικόνα, μειώνοντας σημαντικά την επιφάνεια επίθεσης. Μπορείτε ακόμη και να χρησιμοποιήσετε εικόνες όπως [[LFT:7]] ή [[LFT:8]] για το στάδιο του χρόνου εκτέλεσης, οι οποίες περιέχουν μόνο το ελάχιστο για την εκτέλεση του δυαδικού εφαρμογής.
3. Διαδικασία κατασκευής με στριμωγμένα φύλλα
Όλα τα βήματα κατασκευής ορίζονται σε ένα ενιαίο αρχείο Docker, καθιστώντας την διαδικασία αυτο-αποκλεισμένη και εύκολη στην έκδοση. Οι αγωγοί CI/CD επωφελούνται από ένα μόνο σημείο εισόδου: το αρχείο Docker. Δεν υπάρχει καμία ανάγκη να διατηρηθεί ξεχωριστό σενάριο κατασκευής ή χειροκίνητα βήματα καθαρισμού.
4. Ενισχυμένη αναπαραγωγιμότητα και συνέπεια
Επειδή ολόκληρο το οικοδόμημα συλλαμβάνεται σε ένα Dockerfile, κάθε προγραμματιστής ή σύστημα μπορεί να αναπαράγει τα ίδια ακριβώς στρώματα. Η χρήση συγκεκριμένων ετικετών έκδοσης για τις εικόνες βάσης εγγυάται περαιτέρω σταθερές κατασκευές σε περιβάλλοντα.
Κατασκευή ενός αρχείου Docker πολλαπλών σταδίων: Step by Step
Αυτή η διαδικασία καλύπτει τη δημιουργία ενός αρχείου παραγωγής ⁇ έτοιμης πολυ-στάδιο Dockerfile για μια εφαρμογή Node.js και React. Οι ίδιες αρχές ισχύουν και για κάθε γλώσσα που έχει μεταγλωττιστεί.
1. Σχεδιάστε τις στάδιές σας
Πριν από τη συγγραφή κώδικα, χαρτογραφήστε τα στάδια που χρειάζεστε. Μια τυπική κατασκευή πολλαπλών σταδίων έχει τουλάχιστον δύο στάδια:
- Στάδιο κατασκευής ⁇ εγκαθιστά όλα τα εργαλεία κατασκευής, εγκαθιστά εξαρτήσεις και εκτελεί την εντολή κατασκευής.
- ⁇ ⁇ ουν τάιμ σταδιο ⁇ χρησιμοποιεί μια ελάχιστη βασική εικόνα, αντιγράφει μόνο τα κτιστά τεχνουργήματα από το στάδιο του κατασκευαστή, και ορίζει τη συμπεριφορά του χρόνου εκτέλεσης.
Για σύνθετα έργα μπορείτε να προσθέσετε ενδιάμεσα στάδια για δοκιμές, στατική ανάλυση, ή συμπίεση περιουσιακών στοιχείων.
2. Γράψτε το στάδιο κατασκευής
Ξεκινήστε με μια βασική εικόνα που περιλαμβάνει την απαιτούμενη αλυσίδα εργαλείων. Χρησιμοποιήστε με το όνομα στάδια με για να τα αναφέρετε αργότερα. Για κόμβους:
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
Βασικά σημεία:
- Χρήση για την ντετερμινιστική, ταχύτερη εγκατάσταση εξάρτησης.
- Διατήρηση εντολών ως ξεχωριστών στρωμάτων όταν είναι δυνατόν για μόχλευση caching.
- Εγκαταστήστε εργαλεία κατασκευής (όπως TypeScript, webpack) σε αυτό το στάδιο μόνο.
3. Προσθέστε ένα ενδιάμεσο στάδιο δοκιμής (προαιρετικό)
Για να επιβάλετε την ποιότητα του κώδικα, προσθέστε ένα στάδιο που εκτελεί δοκιμές. Αυτό το στάδιο μπορεί να επαναχρησιμοποιήσει την εικόνα του κατασκευαστή ή να εγκαταστήσει πρόσθετα εργαλεία.
FROM builder AS test
RUN npm run test
Μπορείτε να τρέξετε αυτό το στάδιο στον αγωγό CI σας με για να πιάσετε τις αποτυχίες νωρίς χωρίς να φτιάξετε ολόκληρη την τελική εικόνα.
4. Καθορίστε το στάδιο του χρόνου εκτέλεσης
Για μια εφαρμογή React, η εικόνα runtime μπορεί να είναι ένας εξυπηρετητής Nginx. Για ένα σύστημα υποστήριξης API, μπορεί να είναι μια αναπότρεπτη βασική εικόνα ή ένα ελάχιστο Alpine με το χρόνο εκτέλεσης του κόμβου. Αντιγράψτε μόνο τα βασικά αντικείμενα που χρησιμοποιούν .
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Εάν χρειάζεστε το χρόνο εκτέλεσης του κόμβου, αποφύγετε την αντιγραφή [[LFT:17]] από τον κατασκευαστή· αντίθετα, επανατοποθετήστε τις εξαρτήσεις παραγωγής στο στάδιο του χρόνου εκτέλεσης:
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"]
5. Κατασκευάστε και να δοκιμάσετε την εικόνα
Κατασκευή της τελικής εικόνας με τη χρήση της τυπικής εντολής:
docker build -t myapp:latest .
Για να επαληθεύσετε το μέγεθος, εκτελέστε και συγκρίνετε με ένα ενιαίο στάδιο κατασκευής.
docker run -d -p 8080:80 myapp:latest
curl http://localhost:8080
Βέλτιστες πρακτικές για πολυ-σταθερές κατασκευές
- Χρησιμοποιήστε συγκεκριμένες ετικέτες βασικής εικόνας ⁇ αποφύγετε για την αποφυγή εκπλήξεων. Προτιμήστε ] ή .
- Βελτιστοποιήστε το στρώμα caching ⁇ αντιγράψτε ] και πριν από το υπόλοιπο του πηγαίου κώδικα, ώστε το στρώμα να ακυρώνεται μόνο όταν αλλάζουν οι εξαρτήσεις.
- Κτίριο μόχλευσηςKit ⁇ ενεργοποίηση του BuildKit με [] για γρηγορότερες κατασκευές, εσωτερική κάψα και καλύτερο παραλληλισμό.
- Δημιουργήστε πολλαπλά τελικά στάδια για διαφορετικά περιβάλλοντα ⁇ για παράδειγμα, ένα στάδιο ανάπτυξης με εργαλεία αποσφαλμάτωσης και ένα στάδιο παραγωγής με μια σκληρυμένη βασική εικόνα.
- Χρησιμοποιήστε για κατασκευές ανάπτυξης ⁇ στην ανάπτυξη μπορείτε να σταματήσετε στο στάδιο για να πάρετε ζωντανά επαναφορτώστε και χάρτες πηγής, στη συνέχεια να ξαναχτίσετε με για παραγωγή.
- Κράτα μυστικά έξω από τις εικόνες ⁇ χρησιμοποίησε τη σημαία του Docker BuildKit αν χρειαστεί να περάσεις διαπιστευτήρια κατά τη διάρκεια της κατασκευής· ποτέ μην τα συμπεριλάβεις στην τελική εικόνα.
Κοινές περιπτώσεις χρήσης και τυποποίησης
Γλώσσες που έχουν εισαχθεί (Go, Rust, C++)
Για στατικά δυαδικά, το στάδιο του χρόνου εκτέλεσης μπορεί να χρησιμοποιήσει [[LFT:33]] (κενή εικόνα βάσης). Μόνο το δυαδικό και ίσως ένα αρχείο ρυθμίσεων αντιγράφονται. Παράδειγμα για μετάβαση:
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"]
Εφαρμογές Python
Χρησιμοποιήστε ένα στάδιο κατασκευής με [[LFT:35]] για να εγκαταστήσετε εξαρτήσεις και να μεταγλωττίσετε τυχόν επεκτάσεις C, στη συνέχεια αντιγράψτε μόνο τα εγκατεστημένα πακέτα σε ένα στάδιο χρόνου εκτέλεσης:
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"]
Περιβάλλον με εξυπηρετητή API
Κατασκευή συστήματος υποστήριξης και υποστήριξης σε ένα αρχείο Docker. Χρησιμοποιήστε ξεχωριστά στάδια κατασκευής για κάθε ένα, στη συνέχεια αντιγράψτε και τα δύο αντικείμενα σε μια εικόνα ενός μόνο χρόνου εκτέλεσης:
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"]
Αντιμετώπιση προβλημάτων πολλαπλών δομών
- Το layer caching δεν λειτουργεί[ ⁇ εξασφαλίζει [[LFT:38]] εξαρτήσεις εντολών εντολών πριν από τον πηγαίο κώδικα. Χρησιμοποιήστε [[LFT:39]] για να αποκλείσετε περιττά αρχεία.
- Το αντικείμενο δεν βρέθηκε ⁇ επαληθεύστε τις διαδρομές στη δήλωση . Το στάδιο του κατασκευαστή πρέπει να παράγει έξοδο στην καθορισμένη τοποθεσία. Χρησιμοποιήστε [ για αποσφαλμάτωση.
- Μυστική διαρροή ⁇ ποτέ μην αντιγράψετε ολόκληρους καταλόγους που μπορεί να περιέχουν ] ή .
- Μεγάλες τελικές εικόνες παρά τα πολύ στάδια ⁇ ελέγξτε αν κατά λάθος αντιγράφετε ή ολόκληρη την πηγή. Χρησιμοποιήστε [ για να δείτε μεγέθη στρωμάτων.
Συμπέρασμα
Τα πολυστάδια Docker χτίζουν είναι ένας ακρογωνιαίος λίθος της σύγχρονης εμπορευματοποίησης. Σας επιτρέπουν να στείλετε άπαχο, ασφαλείς εικόνες, ενώ τη διατήρηση της διαδικασίας κατασκευής απλή και τεκμηριωμένη σε ένα ενιαίο Dockerfile. Με τον διαχωρισμό των ανησυχιών μεταξύ κατασκευής και χρόνου λειτουργίας, μπορείτε να μειώσετε δραστικά το μέγεθος της εικόνας, να βελτιώσετε την ασφάλεια, και να βελτιώσετε τους αγωγούς CI/CD. Οι τεχνικές που εμφανίζονται εδώ ισχύουν σχεδόν για οποιαδήποτε στοίβα ⁇ είτε κατασκευάζετε κόμβους, Go, Python, Java, ή εφαρμογές frontend. Ξεκινήστε με τη μετατροπή των υπαρχόντων Dockerfiles σας σε πολυβάθμια οικοδομήματα, και θα δείτε αμέσως βελτιώσεις στην ταχύτητα κατασκευής, την απόδοση ανάπτυξης, και το συνολικό κόστος υποδομής.
Για περισσότερες λεπτομέρειες, ανατρέξτε στον επίσημο φάκελο κατασκευής πολυσταδίων Docker] και στον οδηγό βέλτιστων πρακτικών Dockerfile. Τα πραγματικά ⁇ παγκόσμια παραδείγματα είναι επίσης διαθέσιμα στην τεκμηρίωση Docker Library].