Table of Contents
Hva er fler-Stage Docker Buildings?
Multi-stage Docker-bygg er en funksjon introdusert i Docker 17.05 som lar deg bruke flere uttalelser i en enkelt Dockerfil. Hver instruksjon starter et nytt stadium, som kan ha sitt eget basebilde, avhengighet og kommandoer. Artifakter kan selektivt kopieres fra ett stadium til et annet, mens det endelige bildet bare beholder det som er strengt nødvendig for å kjøre programmet. Denne tilnærmingen eliminerer behovet for manuelt kjede Dockerfiles eller stole på komplekse byggeskripter, og det reduserer dramatisk bildestørrelse ved å utelukke kompilere, utviklingsbiblioteker og mellomliggende filer.
Kjernen ideen er å skille byggemiljøet fra kjøremiljøet. I en typisk enkelt-trinns bygning installerer en utvikler alle byggeverktøy (f.eks. kompilatorer, pakkeledere, testrammer) i samme bilde som vil bli brukt til produksjon. Det blommer bildet og øker angrepsoverflaten. Multi-trinns bygg løser dette ved å bruke et tykkt, funksjonsrikt bilde for sammenstilling og deretter kopiere bare de resulterende gjenstandene til et minimalt Runtime-bilde som eller .
Fordelene med fler-Stage-bygginger
Fordelene ved å vedta flertrinns bygg går utover enkel størrelsesreduksjon. De har en dyp innvirkning på sikkerhet, vedlikeholdsevne og utplasseringshastighet.
1. Redusert bildestørrelse
Ved å kaste byggetid avhengigheter, multi-stage bygger ofte krympe bilder med 50% til 90%. For eksempel kan et Node.js program bygget ved å bruke den fulle bilde (over 300 MB) bli slanket ned til under 20 MB ved å kopiere bare den bygget mappen i en base. Denne lagringsbesparelsen oversetter direkte til raskere trekktider, mindre nettverksbredde og lavere registerkostnader.
2. Forbedret sikkerhet
Hver installert pakke eller verktøy i et beholderbilde er en potensiell sårbarhet. Flertrinnsbygg lar deg utelukke kompilatorer, debuggers og utviklingsbiblioteker fra det endelige bildet, betydelig redusere angrepsoverflaten. Du kan til og med bruke bilder som eller for køyretidsfasen, som inneholder bare det minste som er nødvendig for å utføre programmet binært.
3. Strømlinjet byggeprosess
Alle byggetrinn er definert i en enkelt Dockerfil, noe som gjør prosessen selvstendig og enkel å versjon. CI/CD-rørledninger drar nytte av et enkelt inngangspunkt: Dockerfilen. Det er ikke nødvendig å opprettholde separate byggeskripter eller manuelle oppryddingstrinn.
4. Forbedret reprodusabilitet og konsistens
Fordi hele bygget er fanget i én Dockerfil, kan enhver utvikler eller system reproducere nøyaktig samme lag. Bruken av spesifikke versjonstagger for basebilder ytterligere garanterer konsekvente bygg over hele miljøer.
Bygge en fler-Stage Dockerfil: Trinn for trinn
Denne gjennomgangen dekker opprettelsen av en produksjon ⁇ ready multi-stage Dockerfile for en Node.js og React-applikasjon. De samme prinsippene gjelder for ethvert kompilert språk.
1. Planlegg dine stadier
Før du skriver kode, kartlegg ut de trinnene du trenger. En typisk flertrinnsbygging har minst to trinn:
- Byggefase] ⁇ installerer alle byggeverktøy, installerer avhengigheter og kjører byggekommando.
- Runtime scene ⁇ bruker et minimalt basisbilde, kopierer bare de bygde gjenstandene fra byggmesterstadiet, og definerer kjøretidens oppførsel.
For komplekse prosjekter kan du legge til mellomstadier for tester, statisk analyse eller komprimering av eiendeler.
2. Skriv Byggemaskinen Stage
Start med et basisbilde som inkluderer det nødvendige verktøykjedet. Bruk navngitte stadier med for å referere dem senere. For Node.js:
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
Nøkkelpunkter:
- Bruk for deterministisk, raskere avhengighetsinstallasjon.
- Behold kommandoer som separate lag når det er mulig å utnytte kasjering.
- Installer byggeverktøy (som TypeScript, webpack) i dette trinnet.
3. Legg til en mellomliggende testfase (valgfritt)
For å håndheve kodekvaliteten, legger du til et trinn som kjører tester. Dette trinnet kan gjenbruke byggmesterbildet eller installere ekstra verktøy. Fordi det ikke er det siste trinnet, vil testfeil ikke være tilstede i det endelige bildet.
FROM builder AS test
RUN npm run test
Du kan kjøre dette stadiet i CI-rørledningen med for å fange feil tidlig uten å bygge hele det endelige bildet.
4. Definere Runtime Stage
For et React-program kan køyretiden være en Nginx-server. For et backend-API kan det være et uforstyrret basisbilde eller et minimalt Alpine med Node.js-kjøretiden. Kopier bare de essensielle gjenstandene ved hjelp av .
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Hvis du trenger Node.js-kjøretid, unngå å kopiere fra byggmesteren; i stedet installere produksjonsavhengigheter på nytt i løpetid-stadiet:
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. Bygg og test bildet
Bygg det endelige bildet ved hjelp av standardkommandoen:
docker build -t myapp:latest .
For å verifisere størrelsen, kjør og sammenligne med en enkelt-trinns bygge. Kjør beholderen og bekreft programmet svarer riktig:
docker run -d -p 8080:80 myapp:latest
curl http://localhost:8080
Beste praksis for fler-Stage Buildings
- Bruk spesifikke grunnbildemerker ⁇ unngå ] for å hindre overraskelser. Foretrekk eller ].
- Optimize lag caching ⁇ kopi ] og før resten av kildekoden slik at lag er bare ugyldiggjort når avhengighet endres.
- Leverasje buildKit ⁇ aktiver BuildKit med for raskere bygg, inline caching og bedre parallellisme.
- Opprett flere sluttfaser for ulike miljøer ⁇ for eksempel et utviklingsstadium med feilsøkingsverktøy og et produksjonsstadium med et herdet basisbilde.
- Bruk for utviklingsbygg] ⁇ i utviklingen kan du stoppe på -stadiet for å få levende reload og kildekart, og deretter gjenoppbygge med til produksjon.
- Hold hemmeligheter ute av bilder ⁇ bruk Docker BuildKits flagg hvis du trenger å passere legitimasjon under bygging; aldri inkludere dem i det endelige bildet.
Vanlige mønster og brukssaker
Kompilert språk (Gå, Rust, C++)
For statiske binære lenker kan kjøretiden bruke [[FLT: 33]] (tomt basisbilde). Bare binær- og kanskje en konfigurasjonsfil kopieres. Eksempel på 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"]
Python-applikasjoner
Bruk et byggestadium med til å installere avhengigheter og kompilere eventuelle C-utvidelser, og kopier deretter bare de installerte pakkene til et kjøretid stadium:
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 med API Server
Bygg både frontend og backend i én Dockerfil. Bruk separate byggstadier for hver, og kopier deretter begge gjenstandene til et enkelt kjøretidsbilde:
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"]
Feilsøking av fler-Stage-bygginger
- Layer caching fungerer ikke ⁇ sikre kommandoer rekkefølge avhengigheter før kildekode. Bruk til å utelukke unødvendige filer.
- Artifaktet ikke funnet ⁇ verifiser stiene i -uttalelsen. Byggefasen må produsere utdata på den angitte plasseringen. Bruk til å feilsøke.
- Secret lekkasje ⁇ kopier aldri hele mapper som kan inneholde eller ]. Kopiere bare nødvendige filer.
- Store endelige bilder til tross for multi-stage] ⁇ sjekk om du ved et uhell kopierer eller hele kilden. Bruk til å se lagstørrelser.
Konklusjon
Multi-stage Docker-bygg er en hjørnestein i moderne containerisering. De gjør det mulig å skipe lean, sikre bilder mens du holder byggeprosessen enkel og dokumentert i en enkelt Dockerfil. Ved å skille bekymringer mellom bygg og kjøretid kan du drastisk redusere bildestørrelsen, forbedre sikkerheten og effektivisere CI/CD-rørledninger. Teknikkene som vises her gjelder for nesten alle stabeler - uansett om du bygger Node.js, Go, Python, Java eller frontend-applikasjoner. Start med å konvertere eksisterende Dockerfiles til flertrinnsbygg, og du vil umiddelbart se forbedringer i byggehastighet, distribusjonseffektivitet og generelle infrastrukturkostnader.
For mer informasjon, se offisiell Docker multi-stage byggedokumentasjon og ]Dockerfile beste praksis guide. Ekte ⁇ verden eksempler er også tilgjengelig i Docker Library dokumentasjon.