swl-ses 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/CLAUDE.md +425 -0
  2. package/_userland/agentes/.gitkeep +0 -0
  3. package/_userland/habilidades/.gitkeep +0 -0
  4. package/agentes/accesibilidad-wcag-swl.md +683 -0
  5. package/agentes/arquitecto-swl.md +210 -0
  6. package/agentes/auto-evolucion-swl.md +408 -0
  7. package/agentes/backend-api-swl.md +442 -0
  8. package/agentes/backend-node-swl.md +439 -0
  9. package/agentes/backend-python-swl.md +469 -0
  10. package/agentes/backend-workers-swl.md +444 -0
  11. package/agentes/cloud-infra-swl.md +466 -0
  12. package/agentes/consolidador-swl.md +487 -0
  13. package/agentes/datos-swl.md +568 -0
  14. package/agentes/depurador-swl.md +301 -0
  15. package/agentes/devops-ci-swl.md +352 -0
  16. package/agentes/disenador-ui-swl.md +546 -0
  17. package/agentes/documentador-swl.md +323 -0
  18. package/agentes/frontend-angular-swl.md +603 -0
  19. package/agentes/frontend-css-swl.md +700 -0
  20. package/agentes/frontend-react-swl.md +672 -0
  21. package/agentes/frontend-swl.md +483 -0
  22. package/agentes/frontend-tailwind-swl.md +808 -0
  23. package/agentes/implementador-swl.md +235 -0
  24. package/agentes/investigador-swl.md +274 -0
  25. package/agentes/investigador-ux-swl.md +482 -0
  26. package/agentes/migrador-swl.md +389 -0
  27. package/agentes/mobile-android-swl.md +473 -0
  28. package/agentes/mobile-cross-swl.md +501 -0
  29. package/agentes/mobile-ios-swl.md +464 -0
  30. package/agentes/notificador-swl.md +886 -0
  31. package/agentes/observabilidad-swl.md +408 -0
  32. package/agentes/orquestador-swl.md +490 -0
  33. package/agentes/planificador-swl.md +222 -0
  34. package/agentes/producto-prd-swl.md +565 -0
  35. package/agentes/release-manager-swl.md +545 -0
  36. package/agentes/rendimiento-swl.md +691 -0
  37. package/agentes/revisor-codigo-swl.md +254 -0
  38. package/agentes/revisor-seguridad-swl.md +316 -0
  39. package/agentes/tdd-qa-swl.md +323 -0
  40. package/agentes/ux-disenador-swl.md +498 -0
  41. package/bin/swl-ses.js +119 -0
  42. package/comandos/swl/actualizar.md +117 -0
  43. package/comandos/swl/aprender.md +348 -0
  44. package/comandos/swl/auditar-deps.md +390 -0
  45. package/comandos/swl/autoresearch.md +346 -0
  46. package/comandos/swl/checkpoint.md +296 -0
  47. package/comandos/swl/compactar.md +283 -0
  48. package/comandos/swl/crear-skill.md +609 -0
  49. package/comandos/swl/discutir-fase.md +230 -0
  50. package/comandos/swl/ejecutar-fase.md +302 -0
  51. package/comandos/swl/evolucionar.md +377 -0
  52. package/comandos/swl/instalar.md +220 -0
  53. package/comandos/swl/mapear-codebase.md +205 -0
  54. package/comandos/swl/nuevo-proyecto.md +154 -0
  55. package/comandos/swl/planear-fase.md +221 -0
  56. package/comandos/swl/release.md +405 -0
  57. package/comandos/swl/salud.md +382 -0
  58. package/comandos/swl/verificar.md +292 -0
  59. package/habilidades/accesibilidad-a11y/SKILL.md +584 -0
  60. package/habilidades/angular-avanzado/SKILL.md +491 -0
  61. package/habilidades/angular-moderno/SKILL.md +326 -0
  62. package/habilidades/api-rest-diseno/SKILL.md +302 -0
  63. package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
  64. package/habilidades/aprendizaje-continuo/SKILL.md +369 -0
  65. package/habilidades/async-python/SKILL.md +474 -0
  66. package/habilidades/auth-patrones/SKILL.md +488 -0
  67. package/habilidades/auto-evolucion-protocolo/SKILL.md +376 -0
  68. package/habilidades/autoresearch/SKILL.md +248 -0
  69. package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
  70. package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
  71. package/habilidades/checklist-calidad/SKILL.md +247 -0
  72. package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
  73. package/habilidades/checklist-seguridad/SKILL.md +224 -0
  74. package/habilidades/checkpoints-verificacion/SKILL.md +309 -0
  75. package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
  76. package/habilidades/ci-cd-pipelines/SKILL.md +583 -0
  77. package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
  78. package/habilidades/cloud-aws/SKILL.md +497 -0
  79. package/habilidades/compactacion-contexto/SKILL.md +201 -0
  80. package/habilidades/contenedores-docker/SKILL.md +453 -0
  81. package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
  82. package/habilidades/css-moderno/SKILL.md +463 -0
  83. package/habilidades/datos-etl/SKILL.md +486 -0
  84. package/habilidades/dependencias-auditoria/SKILL.md +293 -0
  85. package/habilidades/deprecacion-migracion/SKILL.md +485 -0
  86. package/habilidades/design-tokens/SKILL.md +519 -0
  87. package/habilidades/discutir-fase/SKILL.md +167 -0
  88. package/habilidades/diseno-responsivo/SKILL.md +326 -0
  89. package/habilidades/django-experto/SKILL.md +395 -0
  90. package/habilidades/doc-sync/SKILL.md +259 -0
  91. package/habilidades/ejecutar-fase/SKILL.md +199 -0
  92. package/habilidades/estructura-proyecto-claude/SKILL.md +459 -0
  93. package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
  94. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +213 -0
  95. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
  96. package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
  97. package/habilidades/event-driven/SKILL.md +580 -0
  98. package/habilidades/extractor-de-aprendizajes/SKILL.md +234 -0
  99. package/habilidades/fastapi-experto/SKILL.md +368 -0
  100. package/habilidades/frontend-avanzado/SKILL.md +555 -0
  101. package/habilidades/git-worktrees-paralelo/SKILL.md +246 -0
  102. package/habilidades/iam-secretos/SKILL.md +511 -0
  103. package/habilidades/instalar-sistema/SKILL.md +140 -0
  104. package/habilidades/kubernetes-orquestacion/SKILL.md +549 -0
  105. package/habilidades/manejo-errores/SKILL.md +512 -0
  106. package/habilidades/mapear-codebase/SKILL.md +199 -0
  107. package/habilidades/microservicios/SKILL.md +473 -0
  108. package/habilidades/mobile-flutter/SKILL.md +566 -0
  109. package/habilidades/mobile-react-native/SKILL.md +493 -0
  110. package/habilidades/monitoring-alertas/SKILL.md +447 -0
  111. package/habilidades/node-experto/SKILL.md +521 -0
  112. package/habilidades/notificaciones-multicanal/SKILL.md +448 -0
  113. package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
  114. package/habilidades/nuevo-proyecto/SKILL.md +183 -0
  115. package/habilidades/patrones-python/SKILL.md +381 -0
  116. package/habilidades/performance-baseline/SKILL.md +243 -0
  117. package/habilidades/planear-fase/SKILL.md +184 -0
  118. package/habilidades/postgresql-experto/SKILL.md +379 -0
  119. package/habilidades/react-experto/SKILL.md +434 -0
  120. package/habilidades/react-optimizacion/SKILL.md +328 -0
  121. package/habilidades/release-semver/SKILL.md +226 -0
  122. package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
  123. package/habilidades/sql-optimizacion/SKILL.md +314 -0
  124. package/habilidades/tailwind-experto/SKILL.md +412 -0
  125. package/habilidades/tdd-workflow/SKILL.md +267 -0
  126. package/habilidades/testing-python/SKILL.md +350 -0
  127. package/habilidades/threat-model-lite/SKILL.md +218 -0
  128. package/habilidades/typescript-avanzado/SKILL.md +454 -0
  129. package/habilidades/ux-diseno/SKILL.md +488 -0
  130. package/habilidades/validacion-ci-sistema/SKILL.md +543 -0
  131. package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
  132. package/habilidades/verificar-trabajo/SKILL.md +208 -0
  133. package/habilidades/wireframes-flujos/SKILL.md +396 -0
  134. package/habilidades/workflow-claude-code/SKILL.md +359 -0
  135. package/hooks/calidad-pre-commit.js +578 -0
  136. package/hooks/escaneo-secretos.js +302 -0
  137. package/hooks/extraccion-aprendizajes.js +550 -0
  138. package/hooks/linea-estado.js +249 -0
  139. package/hooks/monitor-contexto.js +230 -0
  140. package/hooks/proteccion-rutas.js +249 -0
  141. package/manifiestos/hooks-config.json +41 -0
  142. package/manifiestos/modulos.json +318 -0
  143. package/manifiestos/perfiles.json +189 -0
  144. package/package.json +45 -0
  145. package/plantillas/PROJECT.md +122 -0
  146. package/plantillas/REQUIREMENTS.md +132 -0
  147. package/plantillas/ROADMAP.md +143 -0
  148. package/plantillas/STATE.md +109 -0
  149. package/plantillas/research/ARCHITECTURE.md +220 -0
  150. package/plantillas/research/FEATURES.md +175 -0
  151. package/plantillas/research/PITFALLS.md +299 -0
  152. package/plantillas/research/STACK.md +233 -0
  153. package/plantillas/research/SUMMARY.md +165 -0
  154. package/plugin.json +144 -0
  155. package/reglas/accesibilidad.md +269 -0
  156. package/reglas/api-diseno.md +400 -0
  157. package/reglas/arquitectura.md +183 -0
  158. package/reglas/cloud-infra.md +247 -0
  159. package/reglas/docs.md +245 -0
  160. package/reglas/estilo-codigo.md +179 -0
  161. package/reglas/git-workflow.md +186 -0
  162. package/reglas/performance.md +195 -0
  163. package/reglas/pruebas.md +159 -0
  164. package/reglas/seguridad.md +151 -0
  165. package/reglas/skills-estandar.md +473 -0
  166. package/scripts/actualizar.js +51 -0
  167. package/scripts/desinstalar.js +86 -0
  168. package/scripts/doctor.js +222 -0
  169. package/scripts/inicializar.js +89 -0
  170. package/scripts/instalador.js +333 -0
  171. package/scripts/lib/detectar-runtime.js +177 -0
  172. package/scripts/lib/estado.js +112 -0
  173. package/scripts/lib/hooks-settings.js +283 -0
  174. package/scripts/lib/manifiestos.js +138 -0
  175. package/scripts/lib/seguridad.js +160 -0
  176. package/scripts/publicar.js +209 -0
  177. package/scripts/validar.js +120 -0
@@ -0,0 +1,453 @@
1
+ ---
2
+ name: contenedores-docker
3
+ description: Docker y containerización. Dockerfiles optimizados con multi-stage builds, docker-compose, volúmenes, networking, health checks, security scanning, build caching, distroless images. Anti-patrones comunes.
4
+ ---
5
+
6
+ # Docker y Containerización — Producción
7
+
8
+ Docker en producción requiere imágenes seguras, pequeñas y reproducibles.
9
+ Este skill cubre desde Dockerfiles hasta orquestación con Compose.
10
+
11
+ ---
12
+
13
+ ## 1. Dockerfile Base — Python API
14
+
15
+ ```dockerfile
16
+ # =====================================================================
17
+ # Etapa 1: Dependencias (caché eficiente)
18
+ # =====================================================================
19
+ FROM python:3.12-slim AS deps
20
+
21
+ # Instalar dependencias del sistema (solo las necesarias)
22
+ RUN apt-get update && apt-get install -y --no-install-recommends \
23
+ build-essential \
24
+ libpq-dev \
25
+ && rm -rf /var/lib/apt/lists/* # SIEMPRE limpiar en misma capa
26
+
27
+ WORKDIR /app
28
+
29
+ # Copiar SOLO archivos de dependencias primero (mejor caché)
30
+ COPY pyproject.toml uv.lock* requirements*.txt ./
31
+
32
+ # pip sin caché ni warnings innecesarios
33
+ RUN pip install --no-cache-dir --upgrade pip && \
34
+ pip install --no-cache-dir -r requirements.txt
35
+
36
+ # =====================================================================
37
+ # Etapa 2: Build (compilar assets si los hay)
38
+ # =====================================================================
39
+ FROM deps AS builder
40
+
41
+ COPY . .
42
+ RUN python -m compileall -q /app # Precompilar .pyc
43
+
44
+ # =====================================================================
45
+ # Etapa 3: Producción (imagen final mínima)
46
+ # =====================================================================
47
+ FROM python:3.12-slim AS production
48
+
49
+ # Seguridad: NO correr como root
50
+ RUN groupadd --gid 1001 appuser && \
51
+ useradd --uid 1001 --gid appuser --shell /bin/bash --create-home appuser
52
+
53
+ WORKDIR /app
54
+
55
+ # Copiar solo lo necesario desde la etapa de build
56
+ COPY --from=builder --chown=appuser:appuser /usr/local/lib/python3.12/site-packages \
57
+ /usr/local/lib/python3.12/site-packages
58
+ COPY --from=builder --chown=appuser:appuser /app /app
59
+
60
+ # Instalar dependencias de sistema mínimas para runtime
61
+ RUN apt-get update && apt-get install -y --no-install-recommends \
62
+ libpq5 \
63
+ curl \
64
+ && rm -rf /var/lib/apt/lists/*
65
+
66
+ USER appuser
67
+
68
+ # Variables de entorno para Python en contenedor
69
+ ENV PYTHONDONTWRITEBYTECODE=1 \
70
+ PYTHONUNBUFFERED=1 \
71
+ PYTHONFAULTHANDLER=1 \
72
+ PORT=8000
73
+
74
+ EXPOSE 8000
75
+
76
+ # Health check integrado en la imagen
77
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
78
+ CMD curl -f http://localhost:8000/health || exit 1
79
+
80
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", \
81
+ "--workers", "2", "--log-level", "info"]
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 2. Multi-stage Build — Node.js + Angular
87
+
88
+ ```dockerfile
89
+ # Etapa 1: Dependencias npm (caché por package-lock.json)
90
+ FROM node:20-alpine AS npm-deps
91
+ WORKDIR /app
92
+ COPY package.json package-lock.json ./
93
+ RUN npm ci --only=production
94
+
95
+ # Etapa 2: Build Angular
96
+ FROM node:20-alpine AS angular-builder
97
+ WORKDIR /app
98
+ COPY package.json package-lock.json ./
99
+ RUN npm ci # Incluye devDependencies para build
100
+ COPY . .
101
+ RUN npm run build -- --configuration=production --output-path=dist
102
+
103
+ # Etapa 3: Nginx para servir el SPA
104
+ FROM nginx:1.25-alpine AS production
105
+
106
+ # Configuración de Nginx optimizada
107
+ COPY nginx.conf /etc/nginx/nginx.conf
108
+ COPY --from=angular-builder /app/dist /usr/share/nginx/html
109
+
110
+ # Usuario no-root para nginx
111
+ RUN chown -R nginx:nginx /usr/share/nginx/html && \
112
+ chown -R nginx:nginx /var/cache/nginx && \
113
+ touch /var/run/nginx.pid && \
114
+ chown nginx:nginx /var/run/nginx.pid
115
+
116
+ USER nginx
117
+
118
+ EXPOSE 80
119
+
120
+ HEALTHCHECK --interval=30s --timeout=5s \
121
+ CMD curl -f http://localhost/health || exit 1
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 3. .dockerignore — Crítico para el Contexto de Build
127
+
128
+ ```dockerignore
129
+ # Control de versiones
130
+ .git
131
+ .gitignore
132
+
133
+ # Dependencias locales (nunca copiar node_modules o venv)
134
+ node_modules
135
+ __pycache__
136
+ *.pyc
137
+ *.pyo
138
+ .venv
139
+ venv
140
+ env
141
+
142
+ # Tests y documentación
143
+ tests/
144
+ docs/
145
+ *.md
146
+ !README.md
147
+
148
+ # Archivos de configuración de desarrollo
149
+ .env
150
+ .env.*
151
+ *.env
152
+ docker-compose.override.yml
153
+ .editorconfig
154
+ .eslintrc*
155
+ .prettierrc*
156
+
157
+ # IDE
158
+ .vscode
159
+ .idea
160
+ *.swp
161
+
162
+ # Build outputs locales
163
+ dist/
164
+ build/
165
+ .angular/
166
+ coverage/
167
+ .pytest_cache/
168
+
169
+ # CI/CD
170
+ .github/
171
+ .gitlab-ci.yml
172
+ Dockerfile*
173
+ docker-compose*.yml
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 4. docker-compose — Entorno de Desarrollo Completo
179
+
180
+ ```yaml
181
+ # docker-compose.yml
182
+ version: '3.9'
183
+
184
+ services:
185
+ api:
186
+ build:
187
+ context: .
188
+ dockerfile: Dockerfile
189
+ target: deps # Etapa de desarrollo (no producción)
190
+ command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
191
+ volumes:
192
+ - .:/app # Hot reload en desarrollo
193
+ - /app/.venv # Excluir venv del host
194
+ ports:
195
+ - "8000:8000"
196
+ environment:
197
+ - DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/appdb
198
+ - REDIS_URL=redis://redis:6379/0
199
+ - DEBUG=true
200
+ env_file:
201
+ - .env.local # Variables de entorno sensibles
202
+ depends_on:
203
+ db:
204
+ condition: service_healthy
205
+ redis:
206
+ condition: service_healthy
207
+ networks:
208
+ - app-network
209
+ restart: unless-stopped
210
+
211
+ db:
212
+ image: postgres:15-alpine
213
+ volumes:
214
+ - postgres_data:/var/lib/postgresql/data
215
+ - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
216
+ environment:
217
+ POSTGRES_DB: appdb
218
+ POSTGRES_USER: postgres
219
+ POSTGRES_PASSWORD: postgres
220
+ ports:
221
+ - "5432:5432" # Solo exponer en desarrollo
222
+ healthcheck:
223
+ test: ["CMD-SHELL", "pg_isready -U postgres -d appdb"]
224
+ interval: 10s
225
+ timeout: 5s
226
+ retries: 5
227
+ start_period: 30s
228
+ networks:
229
+ - app-network
230
+
231
+ redis:
232
+ image: redis:7-alpine
233
+ command: redis-server --appendonly yes --requirepass "${REDIS_PASSWORD:-dev_password}"
234
+ volumes:
235
+ - redis_data:/data
236
+ ports:
237
+ - "6379:6379"
238
+ healthcheck:
239
+ test: ["CMD", "redis-cli", "ping"]
240
+ interval: 10s
241
+ timeout: 3s
242
+ retries: 3
243
+ networks:
244
+ - app-network
245
+
246
+ nginx:
247
+ image: nginx:1.25-alpine
248
+ volumes:
249
+ - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
250
+ - ./nginx/ssl:/etc/nginx/ssl:ro
251
+ ports:
252
+ - "80:80"
253
+ - "443:443"
254
+ depends_on:
255
+ - api
256
+ networks:
257
+ - app-network
258
+
259
+ volumes:
260
+ postgres_data:
261
+ driver: local
262
+ redis_data:
263
+ driver: local
264
+
265
+ networks:
266
+ app-network:
267
+ driver: bridge
268
+ ipam:
269
+ config:
270
+ - subnet: 172.20.0.0/16
271
+ ```
272
+
273
+ ---
274
+
275
+ ## 5. Networking en Docker
276
+
277
+ ```bash
278
+ # Crear red personalizada (mejores nombres DNS internos)
279
+ docker network create --driver bridge --subnet 172.21.0.0/16 mi-red
280
+
281
+ # Inspeccionar red
282
+ docker network inspect mi-red
283
+
284
+ # Contenedores en la misma red se comunican por nombre
285
+ # api puede conectarse a "db" por nombre → postgresql://db:5432/appdb
286
+
287
+ # MAL: usar --link (obsoleto)
288
+ docker run --link db:database api
289
+
290
+ # BIEN: red compartida
291
+ docker run --network mi-red --name api mi-imagen-api
292
+ docker run --network mi-red --name db postgres:15
293
+ ```
294
+
295
+ ---
296
+
297
+ ## 6. Volúmenes — Persistencia Correcta
298
+
299
+ ```yaml
300
+ # Tipos de volúmenes y cuándo usar cada uno
301
+
302
+ # 1. Named volumes (RECOMENDADO para datos de BD)
303
+ volumes:
304
+ postgres_data: # Docker administra la ubicación
305
+
306
+ # 2. Bind mounts (SOLO para desarrollo — hot reload)
307
+ volumes:
308
+ - ./src:/app/src # Código fuente del host → contenedor
309
+
310
+ # 3. tmpfs (datos efímeros — sesiones, caché temporal)
311
+ tmpfs:
312
+ - /tmp
313
+ - /run
314
+
315
+ # MAL: montar directorio completo en producción
316
+ volumes:
317
+ - .:/app # ¡Incluye .git, node_modules, .env!
318
+
319
+ # BIEN: montar solo lo necesario
320
+ volumes:
321
+ - ./config:/app/config:ro # :ro = solo lectura
322
+ - ./logs:/app/logs # Solo el directorio de logs
323
+ ```
324
+
325
+ ---
326
+
327
+ ## 7. Variables de Entorno y Secrets
328
+
329
+ ```bash
330
+ # MAL: secrets en variables de entorno del Dockerfile
331
+ ENV DATABASE_PASSWORD=supersecreta123
332
+
333
+ # MAL: pasar secrets en build args (aparecen en capas)
334
+ docker build --build-arg DB_PASS=secreto .
335
+
336
+ # BIEN: runtime environment variables (nunca en imagen)
337
+ docker run -e DATABASE_URL="postgresql://..." mi-imagen
338
+
339
+ # BIEN: Docker Secrets (en Swarm)
340
+ docker secret create db_password ./db_password.txt
341
+
342
+ # BIEN: En docker-compose con .env (nunca commitar .env real)
343
+ # .env.example (sí commitear)
344
+ DATABASE_URL=postgresql://usuario:password@localhost:5432/db
345
+ SECRET_KEY=cambiar-en-produccion
346
+
347
+ # docker-compose.yml
348
+ env_file:
349
+ - .env
350
+ ```
351
+
352
+ ---
353
+
354
+ ## 8. Security Scanning — Pipeline de CI
355
+
356
+ ```yaml
357
+ # .github/workflows/security.yml
358
+ name: Security Scan
359
+
360
+ on: [push, pull_request]
361
+
362
+ jobs:
363
+ scan:
364
+ runs-on: ubuntu-latest
365
+ steps:
366
+ - uses: actions/checkout@v4
367
+
368
+ - name: Build imagen
369
+ run: docker build -t mi-app:${{ github.sha }} .
370
+
371
+ # Trivy — escaneo de vulnerabilidades en imagen
372
+ - name: Trivy scan
373
+ uses: aquasecurity/trivy-action@master
374
+ with:
375
+ image-ref: mi-app:${{ github.sha }}
376
+ format: 'sarif'
377
+ output: 'trivy-results.sarif'
378
+ severity: 'CRITICAL,HIGH'
379
+ exit-code: '1' # Fallar el pipeline si hay vulns críticas
380
+
381
+ # Hadolint — linter de Dockerfile
382
+ - name: Hadolint
383
+ uses: hadolint/hadolint-action@v3.1.0
384
+ with:
385
+ dockerfile: Dockerfile
386
+
387
+ # Dockle — mejores prácticas de imagen
388
+ - name: Dockle
389
+ run: |
390
+ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
391
+ goodwithtech/dockle:latest --exit-code 1 mi-app:${{ github.sha }}
392
+ ```
393
+
394
+ ---
395
+
396
+ ## 9. Optimización de Build Cache
397
+
398
+ ```dockerfile
399
+ # ORDEN CRÍTICO para maximizar caché:
400
+ # 1. Lo que cambia MENOS al inicio
401
+ # 2. Lo que cambia MÁS al final
402
+
403
+ # MAL: copiar todo antes de instalar dependencias
404
+ COPY . .
405
+ RUN pip install -r requirements.txt # Invalida caché con CUALQUIER cambio
406
+
407
+ # BIEN: dependencias antes que código
408
+ COPY requirements.txt .
409
+ RUN pip install -r requirements.txt # Se cachea hasta que requirements.txt cambie
410
+ COPY . . # Aquí va el código que cambia frecuentemente
411
+
412
+ # BuildKit — caché de montaje (pip, npm, apt)
413
+ # syntax=docker/dockerfile:1
414
+ FROM python:3.12-slim
415
+
416
+ RUN --mount=type=cache,target=/root/.cache/pip \
417
+ pip install -r requirements.txt
418
+
419
+ RUN --mount=type=cache,target=/var/cache/apt \
420
+ apt-get update && apt-get install -y libpq-dev
421
+ ```
422
+
423
+ ---
424
+
425
+ ## 10. Anti-patrones Comunes
426
+
427
+ | Anti-patrón | Consecuencia | Corrección |
428
+ |-------------|-------------|------------|
429
+ | `FROM python:3.12` (imagen completa) | Imagen 1GB+ innecesaria | `python:3.12-slim` o `distroless` |
430
+ | Correr como `root` en contenedor | Escalación de privilegios | `USER 1001` en Dockerfile |
431
+ | `COPY . .` antes de dependencias | Invalidar caché en cada cambio | Copiar deps primero |
432
+ | Sin `.dockerignore` | Contexto enorme, secretos incluidos | `.dockerignore` siempre |
433
+ | `apt-get` sin `rm -rf /var/lib/apt/lists/*` | Imagen más grande | Limpiar en misma `RUN` |
434
+ | Secrets en `ARG` o `ENV` | Visibles en `docker history` | Runtime env o secrets |
435
+ | Latest tag en producción | No reproducible, puede romper | Tag de versión exacta |
436
+ | Sin `HEALTHCHECK` | Orquestador no sabe si está sano | `HEALTHCHECK` siempre |
437
+ | `CMD` como shell string | Signals no llegan al proceso | `CMD ["ejecutable", "arg"]` forma exec |
438
+ | Múltiples procesos en un contenedor | Viola principio de responsabilidad única | Un proceso por contenedor |
439
+
440
+ ---
441
+
442
+ ## 11. Checklist de Imagen Productiva
443
+
444
+ - [ ] Multi-stage build — imagen final < 200MB si posible
445
+ - [ ] Usuario no-root definido
446
+ - [ ] Variables sensibles fuera de la imagen
447
+ - [ ] `HEALTHCHECK` definido
448
+ - [ ] `.dockerignore` presente y completo
449
+ - [ ] Dependencias del sistema limpiadas en misma capa de RUN
450
+ - [ ] Tag de versión semántica (no `latest`) en producción
451
+ - [ ] Escaneo de vulnerabilidades en CI/CD
452
+ - [ ] `CMD` en forma exec (array), no shell
453
+ - [ ] `PYTHONUNBUFFERED=1` y `PYTHONDONTWRITEBYTECODE=1` para Python
@@ -0,0 +1,160 @@
1
+ # ═══════════════════════════════════════════════════════════════════════════════
2
+ # Dockerfile multi-stage para aplicaciones Python (FastAPI / Django)
3
+ # Optimizado para producción: imagen pequeña, sin root, sin caché innecesario.
4
+ #
5
+ # USO:
6
+ # docker build -t mi-app:1.0.0 .
7
+ # docker build --target deps -t mi-app:deps . # solo la etapa de dependencias
8
+ #
9
+ # VARIABLES DE BUILD (--build-arg):
10
+ # PYTHON_VERSION Versión de Python (default: 3.12)
11
+ # APP_PORT Puerto expuesto (default: 8000)
12
+ # APP_USER_UID UID del usuario sin privilegios (default: 1001)
13
+ #
14
+ # INSTRUCCIÓN: Reemplazar todos los valores entre [corchetes] con los reales.
15
+ # ═══════════════════════════════════════════════════════════════════════════════
16
+
17
+ ARG PYTHON_VERSION=3.12
18
+ ARG APP_PORT=8000
19
+ ARG APP_USER_UID=1001
20
+
21
+ # ─────────────────────────────────────────────────────────────────────────────
22
+ # Etapa 1: deps — instalar dependencias Python (máximo cache hit en rebuilds)
23
+ # ─────────────────────────────────────────────────────────────────────────────
24
+ FROM python:${PYTHON_VERSION}-slim AS deps
25
+
26
+ # Dependencias del sistema mínimas (solo las necesarias para compilar wheels)
27
+ # INSTRUCCIÓN: ajustar según las librerías Python que uses
28
+ # psycopg2 → libpq-dev
29
+ # Pillow → libjpeg-dev zlib1g-dev
30
+ # lxml → libxml2-dev libxslt-dev
31
+ # cryptography → libssl-dev
32
+ RUN apt-get update \
33
+ && apt-get install -y --no-install-recommends \
34
+ build-essential \
35
+ libpq-dev \
36
+ && rm -rf /var/lib/apt/lists/*
37
+
38
+ WORKDIR /app
39
+
40
+ # Copiar SOLO los archivos de dependencias primero.
41
+ # Esto permite que Docker reutilice la capa de pip install si el código cambia
42
+ # pero las dependencias no cambian.
43
+ COPY pyproject.toml uv.lock* requirements*.txt ./
44
+
45
+ # Actualizar pip e instalar dependencias sin caché
46
+ RUN pip install --no-cache-dir --upgrade pip==24.* \
47
+ && pip install --no-cache-dir -r requirements.txt
48
+
49
+ # ─────────────────────────────────────────────────────────────────────────────
50
+ # Etapa 2: builder — copiar código y precompilar bytecode
51
+ # ─────────────────────────────────────────────────────────────────────────────
52
+ FROM deps AS builder
53
+
54
+ # Copiar el código fuente DESPUÉS de instalar dependencias (mejor cache hit)
55
+ COPY . .
56
+
57
+ # Precompilar .pyc — reduce el tiempo de arranque del contenedor en producción
58
+ # -q suprime output, -b escribe .pyc junto a los .py
59
+ RUN python -m compileall -q /app
60
+
61
+ # ─────────────────────────────────────────────────────────────────────────────
62
+ # Etapa 3: production — imagen final mínima sin herramientas de build
63
+ # ─────────────────────────────────────────────────────────────────────────────
64
+ FROM python:${PYTHON_VERSION}-slim AS production
65
+
66
+ ARG APP_PORT
67
+ ARG APP_USER_UID
68
+
69
+ # Instalar SOLO dependencias de runtime (sin herramientas de compilación)
70
+ # INSTRUCCIÓN: ajustar según las librerías que uses en runtime
71
+ RUN apt-get update \
72
+ && apt-get install -y --no-install-recommends \
73
+ libpq5 \
74
+ curl \
75
+ && rm -rf /var/lib/apt/lists/* \
76
+ && apt-get clean
77
+
78
+ # ── Seguridad: usuario sin privilegios ────────────────────────────────────────
79
+ # NUNCA correr como root en producción
80
+ RUN groupadd --gid ${APP_USER_UID} appuser \
81
+ && useradd \
82
+ --uid ${APP_USER_UID} \
83
+ --gid ${APP_USER_UID} \
84
+ --no-create-home \
85
+ --shell /sbin/nologin \
86
+ appuser
87
+
88
+ WORKDIR /app
89
+
90
+ # Copiar dependencias instaladas y código compilado desde las etapas anteriores
91
+ COPY --from=builder /usr/local/lib/python*/site-packages /usr/local/lib/python3.12/site-packages/
92
+ COPY --from=builder /usr/local/bin /usr/local/bin/
93
+ COPY --from=builder /app /app
94
+
95
+ # Establecer permisos correctos ANTES de cambiar de usuario
96
+ RUN chown -R appuser:appuser /app
97
+
98
+ # Cambiar al usuario sin privilegios
99
+ USER appuser
100
+
101
+ # ── Variables de entorno de runtime ───────────────────────────────────────────
102
+ # INSTRUCCIÓN: estas son las variables mínimas recomendadas para Python en producción
103
+ ENV PYTHONDONTWRITEBYTECODE=1 \
104
+ PYTHONUNBUFFERED=1 \
105
+ PYTHONFAULTHANDLER=1 \
106
+ PYTHONHASHSEED=random \
107
+ # FastAPI/Uvicorn
108
+ PORT=${APP_PORT} \
109
+ # INSTRUCCIÓN: agregar variables de entorno propias de la aplicación
110
+ # Las variables con valores sensibles deben venir de secrets, NO hardcodeadas aquí
111
+ APP_ENV=production
112
+
113
+ EXPOSE ${APP_PORT}
114
+
115
+ # ── Health check ──────────────────────────────────────────────────────────────
116
+ # INSTRUCCIÓN: reemplazar /health con el endpoint real de health check
117
+ # interval: frecuencia del check
118
+ # timeout: tiempo máximo de respuesta
119
+ # start_period: tiempo antes del primer check (para que la app arranque)
120
+ # retries: intentos fallidos antes de marcar como unhealthy
121
+ HEALTHCHECK \
122
+ --interval=30s \
123
+ --timeout=10s \
124
+ --start-period=15s \
125
+ --retries=3 \
126
+ CMD curl -f http://localhost:${APP_PORT}/health || exit 1
127
+
128
+ # ── Comando de inicio ─────────────────────────────────────────────────────────
129
+ # INSTRUCCIÓN: ajustar según el framework que uses
130
+ #
131
+ # FastAPI con Uvicorn:
132
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]
133
+ #
134
+ # FastAPI con Gunicorn + Uvicorn workers (para producción con múltiples CPUs):
135
+ # CMD ["gunicorn", "app.main:app", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
136
+ #
137
+ # Django con Gunicorn:
138
+ # CMD ["gunicorn", "[nombre_proyecto].wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
139
+
140
+ # ═══════════════════════════════════════════════════════════════════════════════
141
+ # .dockerignore recomendado (crear en la raíz del proyecto):
142
+ # ───────────────────────────────────────────────────────────────────────────────
143
+ # __pycache__/
144
+ # *.pyc
145
+ # *.pyo
146
+ # .pytest_cache/
147
+ # .mypy_cache/
148
+ # .ruff_cache/
149
+ # .git/
150
+ # .gitignore
151
+ # .env
152
+ # .env.*
153
+ # !.env.example
154
+ # tests/
155
+ # docs/
156
+ # *.md
157
+ # docker-compose*.yml
158
+ # Dockerfile*
159
+ # .github/
160
+ # ═══════════════════════════════════════════════════════════════════════════════