# Cicd Infra

> CI/CD e Infraestrutura: GitHub Actions, Docker multi-stage, Docker Compose, Kubernetes, Trivy, deploy strategies. Use para criar pipelines, dockerizar apps Java/Python, configurar K8s, ou revisar infraestrutura de deploy.

- Skill: `nxs-cafi/cicd-infra` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nxs-cafi/cicd-infra`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nxs-cafi/cicd-infra/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: nxs-cafi (https://skillmd.com/u/nxs-cafi)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nxs-cafi/cicd-infra

---


# CI/CD e Infraestrutura

## GitHub Actions — Java (Maven)

```yaml
# .github/workflows/java-ci.yml
name: Java CI

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

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

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

      - name: Test
        run: mvn -B verify

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        if: always()

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Trivy filesystem scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: fs
          severity: HIGH,CRITICAL
          exit-code: 1
```

## GitHub Actions — Python

```yaml
# .github/workflows/python-ci.yml
name: Python CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip

      - run: pip install -e ".[dev]"
      - run: pytest --cov=src --cov-report=xml -v
      - run: bandit -r src/ -ll
      - run: safety check

      - uses: codecov/codecov-action@v4
```

## Docker — Spring Boot (multi-stage)

```dockerfile
# Dockerfile
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN ./mvnw -B package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
USER app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget -qO- http://localhost:8080/actuator/health/liveness || exit 1
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-jar", "app.jar"]
```

## Docker — FastAPI (multi-stage)

```dockerfile
FROM python:3.12-slim AS build
WORKDIR /app
COPY pyproject.toml .
RUN pip install --no-cache-dir .

FROM python:3.12-slim
WORKDIR /app
RUN useradd -m appuser
USER appuser
COPY --from=build /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY src ./src
EXPOSE 8000
HEALTHCHECK CMD curl -f http://localhost:8000/health/live || exit 1
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
```

## .dockerignore (obrigatório)

```
.git
.env
*.md
tests/
target/
__pycache__
.venv
node_modules
```

## Docker Compose — Dev

```yaml
# docker-compose.yml
services:
  app:
    build: .
    ports: ["8080:8080"]
    environment:
      DATABASE_URL: postgresql://app:app@postgres:5432/app
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres: { condition: service_healthy }
      redis: { condition: service_started }

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s

  redis:
    image: redis:7-alpine

  kafka:
    image: confluentinc/cp-kafka:7.5.0
    environment:
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
```

## Kubernetes — Manifests Básicos

```yaml
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: app
          image: ghcr.io/org/order-service:${VERSION}
          ports:
            - containerPort: 8080
          envFrom:
            - secretRef:
                name: order-service-secrets
            - configMapRef:
                name: order-service-config
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1000m"
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            initialDelaySeconds: 30
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            initialDelaySeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
```

## Deploy Strategies

| Estratégia | Descrição | Quando |
|------------|-----------|--------|
| Rolling | Substitui pods gradualmente | Default K8s |
| Blue/Green | Dois ambientes, switch de tráfego | Zero downtime crítico |
| Canary | % gradual de tráfego | Validar antes de 100% |
| Feature Flag | Lógica no app (LaunchDarkly) | Releases frequentes |

## Checklist de Produção

- [ ] Secrets em K8s Secret / Vault (não em imagem)
- [ ] Resource limits definidos
- [ ] Liveness + readiness probes
- [ ] Imagem escaneada (Trivy) no CI
- [ ] SBOM gerado (opcional: syft)
- [ ] Logs centralizados
- [ ] Métricas expostas para Prometheus
- [ ] Rollback documentado

## Segurança em CI

```yaml
- name: Dependabot (config separado)
  # .github/dependabot.yml
  # version: 2, updates para maven/pip/docker

- name: Semgrep SAST
  run: semgrep --config=auto --error
```

