mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-14 12:11:27 +08:00
docs: add Spanish (es) translation (#2095)
Adds a complete Spanish translation of the ECC documentation under docs/es/, mirroring the Turkish (docs/tr/) translation in scope. 141 files covering agents, commands, rules, skills, contexts, examples, and core docs. Updates root README.md with the Spanish language link. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
28b78dd7bf
commit
ac0f11c640
@@ -0,0 +1,427 @@
|
||||
---
|
||||
name: deployment-patterns
|
||||
description: Flujos de trabajo de despliegue, patrones de pipeline CI/CD, contenedorización Docker, health checks, estrategias de rollback y listas de verificación de preparación para producción de aplicaciones web.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Patrones de Despliegue
|
||||
|
||||
Flujos de trabajo de despliegue en producción y buenas prácticas de CI/CD.
|
||||
|
||||
## Cuándo Activar
|
||||
|
||||
- Configurar pipelines de CI/CD
|
||||
- Contenedorizar una aplicación con Docker
|
||||
- Planificar estrategia de despliegue (blue-green, canary, rolling)
|
||||
- Implementar health checks y readiness probes
|
||||
- Preparar un lanzamiento a producción
|
||||
- Configurar ajustes específicos por entorno
|
||||
|
||||
## Estrategias de Despliegue
|
||||
|
||||
### Rolling Deployment (Por Defecto)
|
||||
|
||||
Reemplazar instancias gradualmente — las versiones vieja y nueva se ejecutan simultáneamente durante el despliegue.
|
||||
|
||||
```
|
||||
Instancia 1: v1 → v2 (actualizar primero)
|
||||
Instancia 2: v1 (aún ejecutando v1)
|
||||
Instancia 3: v1 (aún ejecutando v1)
|
||||
|
||||
Instancia 1: v2
|
||||
Instancia 2: v1 → v2 (actualizar segundo)
|
||||
Instancia 3: v1
|
||||
|
||||
Instancia 1: v2
|
||||
Instancia 2: v2
|
||||
Instancia 3: v1 → v2 (actualizar último)
|
||||
```
|
||||
|
||||
**Pros:** Zero downtime, despliegue gradual
|
||||
**Contras:** Dos versiones se ejecutan simultáneamente — requiere cambios compatibles hacia atrás
|
||||
**Usar cuando:** Despliegues estándar, cambios compatibles hacia atrás
|
||||
|
||||
### Blue-Green Deployment
|
||||
|
||||
Ejecutar dos entornos idénticos. Cambiar el tráfico de forma atómica.
|
||||
|
||||
```
|
||||
Blue (v1) ← tráfico
|
||||
Green (v2) inactivo, ejecutando nueva versión
|
||||
|
||||
# Después de la verificación:
|
||||
Blue (v1) inactivo (se convierte en standby)
|
||||
Green (v2) ← tráfico
|
||||
```
|
||||
|
||||
**Pros:** Rollback instantáneo (cambiar de vuelta a blue), corte limpio
|
||||
**Contras:** Requiere 2x infraestructura durante el despliegue
|
||||
**Usar cuando:** Servicios críticos, tolerancia cero a problemas
|
||||
|
||||
### Canary Deployment
|
||||
|
||||
Enrutar un pequeño porcentaje del tráfico a la nueva versión primero.
|
||||
|
||||
```
|
||||
v1: 95% del tráfico
|
||||
v2: 5% del tráfico (canary)
|
||||
|
||||
# Si las métricas se ven bien:
|
||||
v1: 50% del tráfico
|
||||
v2: 50% del tráfico
|
||||
|
||||
# Final:
|
||||
v2: 100% del tráfico
|
||||
```
|
||||
|
||||
**Pros:** Detecta problemas con tráfico real antes del despliegue completo
|
||||
**Contras:** Requiere infraestructura de división de tráfico, monitoreo
|
||||
**Usar cuando:** Servicios de alto tráfico, cambios arriesgados, feature flags
|
||||
|
||||
## Docker
|
||||
|
||||
### Dockerfile Multi-Stage (Node.js)
|
||||
|
||||
```dockerfile
|
||||
# Etapa 1: Instalar dependencias
|
||||
FROM node:22-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --production=false
|
||||
|
||||
# Etapa 2: Build
|
||||
FROM node:22-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
RUN npm prune --production
|
||||
|
||||
# Etapa 3: Imagen de producción
|
||||
FROM node:22-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
|
||||
USER appuser
|
||||
|
||||
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
|
||||
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
|
||||
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
|
||||
|
||||
CMD ["node", "dist/server.js"]
|
||||
```
|
||||
|
||||
### Dockerfile Multi-Stage (Go)
|
||||
|
||||
```dockerfile
|
||||
FROM golang:1.22-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /server ./cmd/server
|
||||
|
||||
FROM alpine:3.19 AS runner
|
||||
RUN apk --no-cache add ca-certificates
|
||||
RUN adduser -D -u 1001 appuser
|
||||
USER appuser
|
||||
|
||||
COPY --from=builder /server /server
|
||||
|
||||
EXPOSE 8080
|
||||
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:8080/health || exit 1
|
||||
CMD ["/server"]
|
||||
```
|
||||
|
||||
### Dockerfile Multi-Stage (Python/Django)
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim AS builder
|
||||
WORKDIR /app
|
||||
RUN pip install --no-cache-dir uv
|
||||
COPY requirements.txt .
|
||||
RUN uv pip install --system --no-cache -r requirements.txt
|
||||
|
||||
FROM python:3.12-slim AS runner
|
||||
WORKDIR /app
|
||||
|
||||
RUN useradd -r -u 1001 appuser
|
||||
USER appuser
|
||||
|
||||
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
|
||||
COPY --from=builder /usr/local/bin /usr/local/bin
|
||||
COPY . .
|
||||
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
EXPOSE 8000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/')" || exit 1
|
||||
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
|
||||
```
|
||||
|
||||
### Buenas Prácticas de Docker
|
||||
|
||||
```
|
||||
# Buenas prácticas
|
||||
- Usar etiquetas de versión específicas (node:22-alpine, no node:latest)
|
||||
- Builds multi-stage para minimizar el tamaño de imagen
|
||||
- Ejecutar como usuario no-root
|
||||
- Copiar archivos de dependencias primero (cache de capas)
|
||||
- Usar .dockerignore para excluir node_modules, .git, tests
|
||||
- Agregar instrucción HEALTHCHECK
|
||||
- Establecer límites de recursos en docker-compose o k8s
|
||||
|
||||
# Malas prácticas
|
||||
- Ejecutar como root
|
||||
- Usar etiquetas :latest
|
||||
- Copiar todo el repositorio en una sola capa COPY
|
||||
- Instalar dependencias de desarrollo en imagen de producción
|
||||
- Almacenar secretos en la imagen (usar variables de entorno o gestor de secretos)
|
||||
```
|
||||
|
||||
## Pipeline CI/CD
|
||||
|
||||
### GitHub Actions (Pipeline Estándar)
|
||||
|
||||
```yaml
|
||||
name: CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
||||
- run: npm run typecheck
|
||||
- run: npm test -- --coverage
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage/
|
||||
|
||||
build:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository }}:${{ 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'
|
||||
environment: production
|
||||
steps:
|
||||
- name: Deploy to production
|
||||
run: |
|
||||
# Comando de despliegue específico de plataforma
|
||||
# Railway: railway up
|
||||
# Vercel: vercel --prod
|
||||
# K8s: kubectl set image deployment/app app=ghcr.io/${{ github.repository }}:${{ github.sha }}
|
||||
echo "Deploying ${{ github.sha }}"
|
||||
```
|
||||
|
||||
### Etapas del Pipeline
|
||||
|
||||
```
|
||||
PR abierto:
|
||||
lint → typecheck → pruebas unitarias → pruebas de integración → despliegue preview
|
||||
|
||||
Merge a main:
|
||||
lint → typecheck → pruebas unitarias → pruebas de integración → build imagen → desplegar staging → smoke tests → desplegar producción
|
||||
```
|
||||
|
||||
## Health Checks
|
||||
|
||||
### Endpoint de Health Check
|
||||
|
||||
```typescript
|
||||
// Health check simple
|
||||
app.get("/health", (req, res) => {
|
||||
res.status(200).json({ status: "ok" });
|
||||
});
|
||||
|
||||
// Health check detallado (para monitoreo interno)
|
||||
app.get("/health/detailed", async (req, res) => {
|
||||
const checks = {
|
||||
database: await checkDatabase(),
|
||||
redis: await checkRedis(),
|
||||
externalApi: await checkExternalApi(),
|
||||
};
|
||||
|
||||
const allHealthy = Object.values(checks).every(c => c.status === "ok");
|
||||
|
||||
res.status(allHealthy ? 200 : 503).json({
|
||||
status: allHealthy ? "ok" : "degraded",
|
||||
timestamp: new Date().toISOString(),
|
||||
version: process.env.APP_VERSION || "unknown",
|
||||
uptime: process.uptime(),
|
||||
checks,
|
||||
});
|
||||
});
|
||||
|
||||
async function checkDatabase(): Promise<HealthCheck> {
|
||||
try {
|
||||
await db.query("SELECT 1");
|
||||
return { status: "ok", latency_ms: 2 };
|
||||
} catch (err) {
|
||||
return { status: "error", message: "Database unreachable" };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Probes de Kubernetes
|
||||
|
||||
```yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 2
|
||||
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 5
|
||||
failureThreshold: 30 # 30 * 5s = 150s tiempo máximo de inicio
|
||||
```
|
||||
|
||||
## Configuración de Entorno
|
||||
|
||||
### Patrón Twelve-Factor App
|
||||
|
||||
```bash
|
||||
# Toda la configuración mediante variables de entorno — nunca en el código
|
||||
DATABASE_URL=postgres://user:pass@host:5432/db
|
||||
REDIS_URL=redis://host:6379/0
|
||||
API_KEY=${API_KEY} # inyectado por el gestor de secretos
|
||||
LOG_LEVEL=info
|
||||
PORT=3000
|
||||
|
||||
# Comportamiento específico por entorno
|
||||
NODE_ENV=production # o staging, development
|
||||
APP_ENV=production # entorno de app explícito
|
||||
```
|
||||
|
||||
### Validación de Configuración
|
||||
|
||||
```typescript
|
||||
import { z } from "zod";
|
||||
|
||||
const envSchema = z.object({
|
||||
NODE_ENV: z.enum(["development", "staging", "production"]),
|
||||
PORT: z.coerce.number().default(3000),
|
||||
DATABASE_URL: z.string().url(),
|
||||
REDIS_URL: z.string().url(),
|
||||
JWT_SECRET: z.string().min(32),
|
||||
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
|
||||
});
|
||||
|
||||
// Validar al inicio — fallar rápido si la configuración es incorrecta
|
||||
export const env = envSchema.parse(process.env);
|
||||
```
|
||||
|
||||
## Estrategia de Rollback
|
||||
|
||||
### Rollback Instantáneo
|
||||
|
||||
```bash
|
||||
# Docker/Kubernetes: apuntar a imagen anterior
|
||||
kubectl rollout undo deployment/app
|
||||
|
||||
# Vercel: promover despliegue anterior
|
||||
vercel rollback
|
||||
|
||||
# Railway: volver a desplegar commit anterior
|
||||
railway up --commit <previous-sha>
|
||||
|
||||
# Base de datos: revertir migración (si es reversible)
|
||||
npx prisma migrate resolve --rolled-back <migration-name>
|
||||
```
|
||||
|
||||
### Lista de Verificación de Rollback
|
||||
|
||||
- [ ] La imagen/artefacto anterior está disponible y etiquetado
|
||||
- [ ] Las migraciones de base de datos son compatibles hacia atrás (sin cambios destructivos)
|
||||
- [ ] Los feature flags pueden deshabilitar nuevas funciones sin despliegue
|
||||
- [ ] Alertas de monitoreo configuradas para picos de tasa de error
|
||||
- [ ] Rollback probado en staging antes del lanzamiento a producción
|
||||
|
||||
## Lista de Verificación de Preparación para Producción
|
||||
|
||||
Antes de cualquier despliegue a producción:
|
||||
|
||||
### Aplicación
|
||||
- [ ] Todas las pruebas pasan (unitarias, integración, E2E)
|
||||
- [ ] Sin secretos hardcodeados en código o archivos de configuración
|
||||
- [ ] El manejo de errores cubre todos los casos límite
|
||||
- [ ] El logging es estructurado (JSON) y no contiene PII
|
||||
- [ ] El endpoint de health check retorna estado significativo
|
||||
|
||||
### Infraestructura
|
||||
- [ ] La imagen Docker se construye de forma reproducible (versiones fijadas)
|
||||
- [ ] Las variables de entorno están documentadas y validadas al inicio
|
||||
- [ ] Límites de recursos establecidos (CPU, memoria)
|
||||
- [ ] Escalado horizontal configurado (instancias mín/máx)
|
||||
- [ ] SSL/TLS habilitado en todos los endpoints
|
||||
|
||||
### Monitoreo
|
||||
- [ ] Métricas de aplicación exportadas (tasa de requests, latencia, errores)
|
||||
- [ ] Alertas configuradas para tasa de error > umbral
|
||||
- [ ] Agregación de logs configurada (logs estructurados, con búsqueda)
|
||||
- [ ] Monitoreo de uptime en endpoint de health
|
||||
|
||||
### Seguridad
|
||||
- [ ] Dependencias escaneadas en busca de CVEs
|
||||
- [ ] CORS configurado solo para orígenes permitidos
|
||||
- [ ] Rate limiting habilitado en endpoints públicos
|
||||
- [ ] Autenticación y autorización verificadas
|
||||
- [ ] Headers de seguridad establecidos (CSP, HSTS, X-Frame-Options)
|
||||
|
||||
### Operaciones
|
||||
- [ ] Plan de rollback documentado y probado
|
||||
- [ ] Migración de base de datos probada contra datos de tamaño de producción
|
||||
- [ ] Runbook para escenarios de fallo comunes
|
||||
- [ ] Rotación de on-call y ruta de escalación definida
|
||||
Reference in New Issue
Block a user