CI/CD e Infraestrutura
GitHub Actions — Java (Maven)
# .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
# .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
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)
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
# 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
# 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
Segurança em CI
- name: Dependabot (config separado)
# .github/dependabot.yml
# version: 2, updates para maven/pip/docker
- name: Semgrep SAST
run: semgrep --config=auto --error