Salta al contenuto principale

09 - Deploy e DevOps con Claude

Prepara il deploy: Dockerfile multi-stage, Docker Compose, CI/CD con GitHub Actions, health check, logging e monitoring in produzione.

Cosa ne pensi di questo articolo?

09 - Deploy e DevOps con Claude
ClaudeFoto:Matheus BertelliPexels

In Breve

Prepara il deploy: Dockerfile multi-stage, Docker Compose, CI/CD con GitHub Actions, health check, logging e monitoring in produzione.

Deploy e DevOps con Claude

Il deploy è spesso la fase più trascurata nei progetti personali, ma è fondamentale per trasformare il codice in un prodotto funzionante. Claude può aiutarti a configurare containerizzazione, CI/CD, monitoring e logging in modo professionale.

In questo articolo vedremo come usare Claude per preparare il progetto alla produzione, creare pipeline di deploy automatizzate e configurare l'infrastruttura.

Cosa Imparerai

  • Containerizzazione con Docker (multi-stage builds)
  • Docker Compose per sviluppo locale
  • CI/CD con GitHub Actions
  • Deploy su cloud (AWS, Railway, Fly.io)
  • Logging e monitoring base

Containerizzazione con Docker

Multi-Stage Build per Spring Boot

Dockerfile - Spring Boot Ottimizzato
# Stage 1: Build
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app

# Cache dependencies
COPY pom.xml mvnw ./
COPY .mvn .mvn
RUN ./mvnw dependency:go-offline -B

# Build application
COPY src src
RUN ./mvnw package -DskipTests -B

# Extract layers for better caching
RUN java -Djarmode=layertools -jar target/*.jar extract

# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app

# Security: non-root user
RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -D appuser
USER appuser

# Copy layers in order of change frequency
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s \
    CMD wget -q --spider http://localhost:8080/actuator/health || exit 1

EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

Multi-Stage Build per Angular

Dockerfile - Angular con Nginx
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app

# Cache dependencies
COPY package*.json ./
RUN npm ci

# Build application
COPY . .
RUN npm run build -- --configuration=production

# Stage 2: Serve
FROM nginx:alpine
COPY --from=builder /app/dist/*/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
server {{ '{' }}
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # SPA routing
    location / {{ '{' }}
        try_files $uri $uri/ /index.html;
    {{ '}' }}

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {{ '{' }}
        expires 1y;
        add_header Cache-Control "public, immutable";
    {{ '}' }}

    # API proxy (development)
    location /api/ {{ '{' }}
        proxy_pass http://backend:8080/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    {{ '}' }}
{{ '}' }}

Docker Compose per Sviluppo

docker-compose.yml
version: '3.8'

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - DATABASE_URL=jdbc:postgresql://postgres:5432/orders
      - DATABASE_USER=postgres
      - DATABASE_PASSWORD=postgres
      - KAFKA_BOOTSTRAP_SERVERS=kafka:9092
    depends_on:
      postgres:
        condition: service_healthy
      kafka:
        condition: service_started
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "4200:80"
    depends_on:
      - backend

  postgres:
    image: postgres:16-alpine
    environment:
      - POSTGRES_DB=orders
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  kafka:
    image: confluentinc/cp-kafka:7.5.0
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_LISTENERS: PLAINTEXT://kafka:9092,CONTROLLER://kafka:9093
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
    ports:
      - "9092:9092"

volumes:
  postgres_data:

CI/CD con GitHub Actions

.github/workflows/ci.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ '{{' }} github.repository {{ '}}' }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: maven

      - name: Run tests
        run: ./mvnw verify
        working-directory: ./backend

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          files: ./backend/target/site/jacoco/jacoco.xml

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'

    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ '{{' }} env.REGISTRY {{ '}}' }}
          username: ${{ '{{' }} github.actor {{ '}}' }}
          password: ${{ '{{' }} secrets.GITHUB_TOKEN {{ '}}' }}

      - name: Build and push Backend
        uses: docker/build-push-action@v5
        with:
          context: ./backend
          push: true
          tags: ${{ '{{' }} env.REGISTRY {{ '}}' }}/${{ '{{' }} env.IMAGE_NAME {{ '}}' }}-backend:${{ '{{' }} github.sha {{ '}}' }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - name: Deploy to Railway
        uses: berviantoleo/railway-deploy@main
        with:
          railway_token: ${{ '{{' }} secrets.RAILWAY_TOKEN {{ '}}' }}
          service: order-service

Logging e Monitoring

application.yml - Logging Configurazione
logging:
  level:
    root: INFO
    com.company.orders: DEBUG
  pattern:
    console: "%d{{ '{' }}yyyy-MM-dd HH:mm:ss{{ '}' }} [%thread] %-5level %logger{{ '{' }}36{{ '}' }} - %msg%n"

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: when_authorized
  metrics:
    tags:
      application: order-service

# Structured logging for production
---
spring:
  config:
    activate:
      on-profile: prod

logging:
  pattern:
    console: '{{ '{' }}"timestamp":"%d{{ '{' }}ISO8601{{ '}' }}","level":"%level","logger":"%logger","message":"%msg","thread":"%thread"{{ '}' }}%n'

Checklist Deploy

Checklist Pre-Deploy

  • Dockerfile multi-stage ottimizzato
  • Docker Compose per sviluppo locale
  • Health check configurato
  • CI/CD pipeline funzionante
  • Secrets gestiti correttamente (non in git)
  • Logging strutturato per produzione
  • Metriche esposte (Prometheus/Actuator)
  • Backup database automatizzato

Conclusione

In questo articolo abbiamo visto come preparare il progetto per il deploy in produzione. Nel prossimo e ultimo articolo, esploreremo l'evoluzione del progetto: scalabilità, manutenzione e aggiunta di nuove feature.

Punti Chiave da Ricordare

  • Multi-stage builds: Immagini piccole e sicure
  • Docker Compose: Ambiente locale riproducibile
  • CI/CD automatizzato: Deploy consistente e affidabile
  • Health checks: Fondamentali per orchestratori
  • Logging strutturato: Facilità debugging in produzione

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti