Ce sunt construiește Docker Multi-Stage?

Docker construiește în mai multe etape o caracteristică introdusă în Docker 17.05 care vă permite să utilizați mai multe declarații într-un singur fișier Docker. Fiecare instrucțiuni începe o nouă etapă, care poate avea propria imagine de bază, dependențe și comenzi.Artefactele pot fi copiate selectiv de la o etapă la alta, în timp ce imaginea finală păstrează doar ceea ce este strict necesar pentru a rula aplicația. Această abordare elimină necesitatea de a lanț manual Dockerfiles sau se bazează pe scenarii complexe de construcție, și reduce dramatic dimensiunea imaginii prin excluderea compilatorilor, biblioteci de dezvoltare, și fișiere intermediare.

Ideea de bază este de a separa mediul de construcţie de mediul funcţional. Într-o construcţie tipică monoetajată, un dezvoltator instalează toate instrumentele de construcţie (de exemplu, compilatoare, manageri de pachete, cadre de testare) în aceeaşi imagine care va fi folosită pentru producţie. Aceasta balonează imaginea şi creşte suprafaţa de atac. Construieşte în mai multe etape soluţionează acest lucru folosind o imagine groasă, bogată în caracteristici pentru compilare şi apoi copierea doar a artefactelor rezultate într-o imagine minimă de timp de execuție, cum ar fi sau .

Beneficiile de mai multe etape de constructii

Avantajele adoptării de structuri multi-stadioane merg dincolo de reducerea simplă a dimensiunii. Acestea au un impact profund asupra securității, întreținere și viteza de desfășurare.

1. Dimensiune redusă imagine

Prin eliminarea dependențelor de timp de construcție, mai multe etape construiește adesea micșorează imaginile cu 50% până la 90%. De exemplu, o aplicație Node.js construită folosind întreaga imagine (peste 300MB) poate fi redusă la sub 20MB prin copierea doar a dosarului construit într-o bază . Această economie de stocare se traduce direct la perioade de tragere mai rapide, latime mai mică de rețea și costuri mai mici de înregistrare.

2. Îmbunătățirea securității

Fiecare pachet sau instrument instalat într-o imagine container este o vulnerabilitate potențială. Construcții multi-stage vă permite să excludeți compilatoarele, depanatoarele și bibliotecile de dezvoltare din imaginea finală, reducând semnificativ suprafața de atac. Puteți utiliza imagini ca sau pentru etapa de execuție, care conțin doar minimul gol pentru a executa aplicația binară.

3. Proces de construcție simplificat

Toate etapele de constructie sunt definite intr-un singur fisier Docker, ceea ce face procesul autonom si usor de versiune. Conductele CI/CD beneficiaza de un singur punct de intrare: fisierul Docker. Nu este nevoie sa mentineti scripturi de constructie separate sau pasi de curatare manuali.

4. Reproducibilitate și coerență sporită

Deoarece întreaga clădire este capturată într-un singur fişier Docker, orice dezvoltator sau sistem poate reproduce exact aceleaşi straturi. Utilizarea de etichete versiune specifice pentru imagini de bază garantează în continuare construi consistente în medii.

Construirea unui fișier Docker cu mai multe trepte: Pas cu pas

Acest walkthrough acoperă crearea unui fișier Docker cu mai multe etape de producție pentru o aplicație Node.js și React. Aceleași principii se aplică oricărei limbi compilate.

1. Planificaţi-vă etapele

Înainte de a scrie codul, harta etapele de care aveți nevoie. O clădire tipică multi-etape are cel puțin două etape:

  • Stadiul de construcție
  • Stadiul de funcționare

Pentru proiecte complexe, puteți adăuga etape intermediare pentru teste, analiză statică sau compresie a activelor.

2. Scrie scena constructorului

Începeți cu o imagine de bază care include lanțul de unelte necesar. Utilizați etapele numite cu pentru a le referi mai târziu.

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

Puncte cheie:

  • Utilizarea pentru instalarea de dependență deterministă și mai rapidă.
  • Ţineţi comenzile ca straturi separate atunci când este posibil să se legenă.
  • Instalați instrumente de construcție (ca TypeScript, doar în această etapă.

3. Adăugați o etapă intermediară de testare (opțional)

Pentru a aplica calitatea codului, adăugați o etapă care rulează teste. Această etapă poate refolosi imaginea constructorului sau instala instrumente suplimentare. Deoarece nu este etapa finală, eșecurile de testare nu vor fi prezente în imaginea finală.

FROM builder AS test
RUN npm run test

Puteți rula această etapă în conducta ta CI cu pentru a prinde eșecuri devreme fără a construi întreaga imagine finală.

4. Definirea etapei de execuție

Pentru o aplicație React, imaginea runtime poate fi un server Nginx. Pentru un API suport, ar putea fi o imagine de bază distroless sau un minimal Alpine cu Node.js runtime. Copiați numai artefactele esențiale folosind .

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

Dacă aveți nevoie de Node.js runtime, evitați copierea de la constructor; în schimb, reinstalați dependențele de producție în etapa de execuție:

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. Construiți și testați imaginea

Construiește imaginea finală folosind comanda standard:

docker build -t myapp:latest .

Pentru a verifica dimensiunea, executați și comparați cu o singură etapă de construcție. Executați recipientul și confirmați că aplicația răspunde corect:

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

Cele mai bune practici pentru construcţii multi-stagiare

  • Folosiţi etichete specifice de imagine de bază
  • Optimizează cachingul strat
  • Leverage buildKit
  • Crearea mai multor etape finale pentru diferite medii
  • Utilizați pentru construcții de dezvoltare
  • Ascunde secretele de imagini

Modele comune și cazuri de utilizare

Limbi compuse (Go, Rust, C++)

Pentru binare statice, etapa de execuție poate utiliza (imagine de bază goală). Numai binar și poate un fișier de configurare sunt copiate. Exemplu pentru 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"]

Aplicații Python

Utilizați o etapă de constructor cu pentru a instala dependențe și compila orice extensii C, apoi copiați doar pachetele instalate într-o etapă de execuție:

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 cu server API

Construi atât frontend și backend într-un singur fișier Docker. Utilizați etape separate constructor pentru fiecare, apoi copiați ambele artefacte într-o singură imagine runtime:

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"]

Depanarea de mai multe etape de construcție

  • Layer caching nu funcționează
  • Artifactul nu a fost găsit
  • Secret de scurgere
  • Imagini finale mari în ciuda mai multor etape

Concluzie

Docker construiește în mai multe etape sunt o piatră de temelie a containerizării moderne. Ele vă permit să expediați imagini slabe, sigure în timp ce menținerea procesului de construcție simplu și documentat într-un singur fișier Docker. Prin separarea preocupărilor între build și runtime, puteți reduce drastic dimensiunea imaginii, îmbunătăți securitatea, și eficientiza conductele CI/CD. Tehnicile prezentate aici se aplică aproape orice stiva . De asemenea, sunteți construirea Node.js, Go, Python, Java, sau aplicații frontend. Începe prin conversia fișierelor Docker existente la mai multe etape construiește, și veți vedea imediat îmbunătățiri în ceea ce privește viteza de construcție, eficiența de implementare și costurile de infrastructură generale.

Pentru mai multe detalii, consultați documentația oficială a construcției Docker în mai multe etape și Dockerfile best practice guide.Exemplarele din lumea reală sunt disponibile și în documentația ]Docker Library.