Du code au deploiement : pipeline complet 25 min de lecture

Le Dockerfile et le deploiement Kubernetes

Dockerfile multi-stage

Un Dockerfile multi-stage reduit la taille de l'image finale en separant le build du runtime.

# Dockerfile multi-stage pour une app Node.js
# ── Stage 1 : Build ──
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ── Stage 2 : Runtime ──
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./
EXPOSE 3000
USER node
CMD ["node", "dist/main.js"]

Manifestes Kubernetes

Les manifestes YAML decrivent l'etat souhaite de l'application sur Kubernetes.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mon-app
  namespace: mon-app-production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mon-app
  template:
    metadata:
      labels:
        app: mon-app
    spec:
      containers:
        - name: mon-app
          image: registry.gitlab.com/equipe/mon-app:abc123
          ports:
            - containerPort: 3000
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: mon-app-secrets
                  key: database-url
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mon-app
  namespace: mon-app-production
spec:
  selector:
    app: mon-app
  ports:
    - port: 80
      targetPort: 3000
  type: ClusterIP
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mon-app
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - mon-app.example.com
      secretName: mon-app-tls
  rules:
    - host: mon-app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mon-app
                port:
                  number: 80
Bonne pratique : Ne jamais utiliser le tag :latest en production. Utilisez le hash du commit ($CI_COMMIT_SHORT_SHA) pour tracer exactement quelle version est deployee.