
Colección de imágenes de contenedor mínimas y endurecidas contra CVE
Imágenes de contenedor pequeñas, reforzadas, gratuitas y con licencia MIT.
Construidas desde el código fuente con apko de Chainguard y paquetes Wolfi, reconstruidas cada seis horas.
Cada imagen está firmada con cosign, incluye una atestación SPDX SBOM y cuenta con una procedencia de compilación SLSA Nivel 3. Puedes verificar todo sin necesidad de una cuenta.
El objetivo de estas imágenes es que no tienes que confiar en mí. Descarga una y luego comprueba la procedencia tú mismo:```bash
docker pull ghcr.io/rtvkiz/minimal-python:latest
gh attestation verify oci://ghcr.io/rtvkiz/minimal-python:latest --owner rtvkiz
cosign verify-attestation --type spdxjson
--certificate-identity-regexp='https://github.com/rtvkiz/minimal/'
--certificate-oidc-issuer='https://token.actions.githubusercontent.com'
ghcr.io/rtvkiz/minimal-python:latest
| jq -r '.payload | @base64d | fromjson | .predicate' > python-sbom.spdx.json
Más recetas de verificación (firma cosign, SBOM, procedencia SLSA) viven en [`.github/SECURITY.md`](https://github.com/rtvkiz/minimal/blob/main/.github/SECURITY.md).
## Cómo `minimal` es diferente
| | minimal | Chainguard | Docker Hardened | Minimus / RapidFort |
|---|:---:|:---:|:---:|:---:|
| **Licencia** | MIT | Propietario | Apache-2.0 | Propietario |
| **Costo** | $0 | ~$30k/imagen/año | Gratuito + soporte de pago | Llamada comercial |
| **Autenticación para pull** | No | Sí | Sí | Sí |
| **Límites de tasa** | Ninguno | Sí | Sí | Sí |
| **Recetas de compilación públicas** | Sí, cada `melange.yaml` | No | Sí, Dockerfiles | No |
| **Firma Cosign + SBOM + SLSA L3** | Sí | Sí | Sí | Sí |
| **SLA del proveedor, FedRAMP/STIG** | No | Sí (pago) | Sí (pago) | Sí (pago) |
Opta por `minimal` si deseas imágenes endurecidas sin pagar ni registrarte, si deseas leer cada receta de compilación de principio a fin, o si deseas una plantilla funcional para bifurcar en tu propio catálogo interno.
Probablemente no sea la opción adecuada si necesitas un contrato con un proveedor, papeleo de acreditación FedRAMP o STIG, o más de mil imágenes desde el primer día — esas son cosas reales que este proyecto no intenta resolver.
## Lo que incluye cada imagen
- Una firma sin clave de cosign, verificable contra el registro de transparencia público de Rekor.
- Un SBOM SPDX adjunto como una atestación in-toto — cada paquete, versión y licencia.
- Procedencia de compilación SLSA v1.0 — prueba criptográfica de qué flujo de trabajo, qué commit y qué runner produjo la imagen.
- Un escaneo diario de Grype, con resultados en el [catálogo público](https://minimalcontainers.com) y en la pestaña de Seguridad de GitHub.
- Compilaciones nativas `linux/amd64` y `linux/arm64`.
- Un usuario no root por defecto (UID 65532), a menos que el upstream insista en lo contrario.
- Sin shell cuando sea posible — la mayoría de las imágenes no incluyen `/bin/sh`.
- Una cadencia de reconstrucción de seis horas, para que los parches de CVE de Wolfi lleguen en horas, no en días.
## Imágenes disponibles — 57 en total
| Categoría | Cantidad | Destacados |
|---|---|---|
| **Lenguajes y tiempos de ejecución** | 9 | python, node-slim, bun, go, java, ruby, php, dotnet, deno |
| **Bases de datos** | 5 | mysql, mariadb, postgres-slim, sqlite, opensearch |
| **Cachés, colas, mensajería** | 7 | redis-slim, valkey, memcached, kafka, rabbitmq, nats, mosquitto |
| **Servidores web y proxies** | 6 | nginx, httpd, caddy, haproxy, traefik, envoy |
| **Observabilidad** | 14 | prometheus, alertmanager, victoria-metrics, thanos, mimir, jaeger, loki, tempo, otelcol, fluent-bit, telegraf, node-exporter, blackbox-exporter, pushgateway |
| **Infraestructura** | 7 | coredns, etcd, openbao, keycloak, qdrant, registry, consul |
| **Kubernetes, CI e IaC** | 4 | helm, kubectl, opentofu, trivy |
| **Aplicaciones** | 5 | jenkins, gitea, minio, rails, mailpit |
Explora cada imagen — con escaneos de CVE en vivo, todas las etiquetas, SBOMs y procedencia de compilación — en **[minimalcontainers.com](https://minimalcontainers.com)**, o expande la lista completa de comandos de pull a continuación.
<details>
<summary><strong>Catálogo completo de imágenes con comandos de pull</strong></summary>
<br>
| Imagen | Comando de pull | Shell | Caso de uso |
|-------|--------------|-------|----------|
| | | **Lenguajes** | |
| Python | `docker pull ghcr.io/rtvkiz/minimal-python:latest` | No | Aplicaciones Python, microservicios |
| Node.js-slim | `docker pull ghcr.io/rtvkiz/minimal-node-slim:latest` | No | Aplicaciones Node.js, JavaScript |
| Bun | `docker pull ghcr.io/rtvkiz/minimal-bun:latest` | No | Entorno de ejecución rápido para JavaScript/TypeScript |
| Go | `docker pull ghcr.io/rtvkiz/minimal-go:latest` | No | Desarrollo de Go, compilaciones CGO |
| .NET Runtime | `docker pull ghcr.io/rtvkiz/minimal-dotnet:latest` | No | Entorno de ejecución .NET 10 para aplicaciones |
| Java | `docker pull ghcr.io/rtvkiz/minimal-java:latest` | No | OpenJDK 26 JRE para aplicaciones Java |
| Ruby | `docker pull ghcr.io/rtvkiz/minimal-ruby:latest` | No | Entorno de ejecución Ruby 4.0 (compilado desde fuente) |
| PHP | `docker pull ghcr.io/rtvkiz/minimal-php:latest` | No | PHP 8.5 CLI (compilado desde fuente) |
| Rails | `docker pull ghcr.io/rtvkiz/minimal-rails:latest` | No | Ruby 4.0 + Rails 8.1 (compilado desde fuente) |
| Deno | `docker pull ghcr.io/rtvkiz/minimal-deno:latest` | No | Entorno de ejecución seguro para TypeScript/JavaScript |
| | | **Bases de datos** | |
| MySQL | `docker pull ghcr.io/rtvkiz/minimal-mysql:latest` | Sí | MySQL LTS 8.4.x, compilado desde fuente |
| MariaDB | `docker pull ghcr.io/rtvkiz/minimal-mariadb:latest` | Sí | MariaDB LTS 11.4.x, compilado desde fuente |
| PostgreSQL-slim | `docker pull ghcr.io/rtvkiz/minimal-postgres-slim:latest` | No | Base de datos relacional |
| SQLite | `docker pull ghcr.io/rtvkiz/minimal-sqlite:latest` | No | CLI de base de datos SQL embebida |
| OpenSearch | `docker pull ghcr.io/rtvkiz/minimal-opensearch:latest` | No* | OpenSearch 3.x — búsqueda y análisis |
| | | **Cachés, Colas, Mensajería** | |
| Redis-slim | `docker pull ghcr.io/rtvkiz/minimal-redis-slim:latest` | No | Almacén de datos en memoria |
| Memcached | `docker pull ghcr.io/rtvkiz/minimal-memcached:latest` | No | Caché en memoria (compilado desde fuente) |
| Valkey | `docker pull ghcr.io/rtvkiz/minimal-valkey:latest` | No | Fork de Redis con licencia BSD (LF) |
| Kafka | `docker pull ghcr.io/rtvkiz/minimal-kafka:latest` | Sí | Apache Kafka 4.x, modo KRaft |
| RabbitMQ | `docker pull ghcr.io/rtvkiz/minimal-rabbitmq:latest` | Sí | Broker AMQP RabbitMQ 4.x |
| NATS | `docker pull ghcr.io/rtvkiz/minimal-nats:latest` | No | Servidor NATS con JetStream |
| Mosquitto | `docker pull ghcr.io/rtvkiz/minimal-mosquitto:latest` | No | Broker MQTT Eclipse Mosquitto (EPL-2.0/EDL-1.0) |
| | | **Servidores web y proxies** | |
| Nginx | `docker pull ghcr.io/rtvkiz/minimal-nginx:latest` | No | Proxy inverso, archivos estáticos |
| HTTPD | `docker pull ghcr.io/rtvkiz/minimal-httpd:latest` | Quizás* | Servidor web Apache |
| Caddy | `docker pull ghcr.io/rtvkiz/minimal-caddy:latest` | No | Servidor web HTTPS automático |
| HAProxy | `docker pull ghcr.io/rtvkiz/minimal-haproxy:latest` | No | Balanceador de carga TCP/HTTP |
| Traefik | `docker pull ghcr.io/rtvkiz/minimal-traefik:latest` | No | Proxy inverso nativo de la nube |
| Envoy | `docker pull ghcr.io/rtvkiz/minimal-envoy:latest` | No | Proxy de servicio y balanceador de carga |
| | | **Observabilidad** | |
| Prometheus | `docker pull ghcr.io/rtvkiz/minimal-prometheus:latest` | No | Recolección de métricas y alertas |
| VictoriaMetrics | `docker pull ghcr.io/rtvkiz/minimal-victoria-metrics:latest` | No | Almacenamiento de métricas de alto rendimiento |
| Jaeger | `docker pull ghcr.io/rtvkiz/minimal-jaeger:latest` | No | Trazado distribuido (v2) |
| Loki | `docker pull ghcr.io/rtvkiz/minimal-loki:latest` | No | Agregación de registros (Grafana Labs) |
| Tempo | `docker pull ghcr.io/rtvkiz/minimal-tempo:latest` | No | Backend de trazado distribuido (Grafana Labs, AGPL) |
| OTel Collector | `docker pull ghcr.io/rtvkiz/minimal-otelcol:latest` | No | Núcleo del colector OpenTelemetry |
| Fluent Bit | `docker pull ghcr.io/rtvkiz/minimal-fluent-bit:latest` | No | Procesador de registros ligero |
| Node Exporter | `docker pull ghcr.io/rtvkiz/minimal-node-exporter:latest` | No | Métricas de hardware y SO del host de Prometheus |
| Blackbox Exporter | `docker pull ghcr.io/rtvkiz/minimal-blackbox-exporter:latest` | No | Sondeo de endpoints de Prometheus (HTTP/DNS/TCP/ICMP) |
| Pushgateway | `docker pull ghcr.io/rtvkiz/minimal-pushgateway:latest` | No | Push de métricas de Prometheus para trabajos por lotes |
| | | **Infraestructura** | |
| CoreDNS | `docker pull ghcr.io/rtvkiz/minimal-coredns:latest` | No | DNS predeterminado de Kubernetes |
| etcd | `docker pull ghcr.io/rtvkiz/minimal-etcd:latest` | No | Almacén clave-valor distribuido |
| OpenBao | `docker pull ghcr.io/rtvkiz/minimal-openbao:latest` | No | Gestión de secretos (fork de Vault) |
| Keycloak | `docker pull ghcr.io/rtvkiz/minimal-keycloak:latest` | Sí | Gestión de identidad y acceso |
| Qdrant | `docker pull ghcr.io/rtvkiz/minimal-qdrant:latest` | No | Base de datos vectorial para IA/ML (Rust) |
| Registry | `docker pull ghcr.io/rtvkiz/minimal-registry:latest` | No | Registro de distribución OCI (Docker Registry v2), compilado desde fuente |
| Consul | `docker pull ghcr.io/rtvkiz/minimal-consul:latest` | No | Descubrimiento de servicios de HashiCorp Consul + KV (BUSL-1.1) |
| | | **Kubernetes y CI** | |
| Helm | `docker pull ghcr.io/rtvkiz/minimal-helm:latest` | No | CLI de Helm 3 para despliegue de charts de Kubernetes |
| kubectl | `docker pull ghcr.io/rtvkiz/minimal-kubectl:latest` | No | CLI de kubectl para operaciones de clúster Kubernetes |
| | | **Aplicaciones** | |
| Jenkins | `docker pull ghcr.io/rtvkiz/minimal-jenkins:latest` | Sí | Automatización de CI/CD |
| Gitea | `docker pull ghcr.io/rtvkiz/minimal-gitea:latest` | Sí | Servicio Git auto-alojado |
| MinIO | `docker pull ghcr.io/rtvkiz/minimal-minio:latest` | No | Almacenamiento de objetos compatible con S3 |
| Mailpit | `docker pull ghcr.io/rtvkiz/minimal-mailpit:latest` | No | Pruebas de SMTP y correo electrónico para desarrolladores, compilado desde fuente |
| | | **IA / ML** | |
| CUDA Python | *deshabilitado* | No | Python + CUDA 12.9 + cuDNN 9.10 (compilación en pausa, código retenido) |
*\*HTTPD, Jenkins, Kafka, MySQL, OpenSearch, Gitea, Keycloak incluyen shell (`sh`/`busybox`/`bash`) a través de dependencias transitivas de Wolfi o porque el punto de entrada (entrypoint) del upstream lo requiere. CI trata la presencia de shell como informativo.*
</details>
## Inicio rápido```bash
# Python app
docker run --rm -v $(pwd):/app ghcr.io/rtvkiz/minimal-python:latest /app/main.py
# Nginx reverse proxy
docker run -d -p 8080:80 ghcr.io/rtvkiz/minimal-nginx:latest
# PostgreSQL
docker run -d -p 5432:5432 -v pgdata:/var/lib/postgresql/data \
ghcr.io/rtvkiz/minimal-postgres-slim:latest
# Redis
docker run -d -p 6379:6379 ghcr.io/rtvkiz/minimal-redis-slim:latest
# Kafka (KRaft mode — auto-initializes storage on first boot)
docker run -d -p 9092:9092 -v kafkadata:/var/kafka/data \
ghcr.io/rtvkiz/minimal-kafka:latest
docker run (Node, Go, MySQL, MariaDB, Java, .NET, PHP, Rails, RabbitMQ, Gitea, …)
```bash
docker run --rm -v $(pwd):/app -w /app ghcr.io/rtvkiz/minimal-node-slim:latest index.js
docker run --rm ghcr.io/rtvkiz/minimal-bun:latest --version
docker run --rm -v $(pwd):/app -w /app ghcr.io/rtvkiz/minimal-go:latest build -o /tmp/app .
docker run -d -p 8080:80 ghcr.io/rtvkiz/minimal-httpd:latest
docker run -d -p 8080:8080 -v jenkins_home:/var/jenkins_home ghcr.io/rtvkiz/minimal-jenkins:latest
docker run -d -p 3306:3306 -v mysqldata:/var/lib/mysql ghcr.io/rtvkiz/minimal-mysql:latest
docker run -d -p 11211:11211 ghcr.io/rtvkiz/minimal-memcached:latest
docker run --rm -v $(pwd):/data ghcr.io/rtvkiz/minimal-sqlite:latest /data/mydb.sqlite "SELECT sqlite_version();"
docker run --rm -v $(pwd):/app ghcr.io/rtvkiz/minimal-dotnet:latest /app/myapp.dll
docker run --rm -v $(pwd):/app ghcr.io/rtvkiz/minimal-java:latest -jar /app/myapp.jar
docker run --rm -v $(pwd):/app ghcr.io/rtvkiz/minimal-php:latest /app/index.php
docker run --rm -v $(pwd):/app ghcr.io/rtvkiz/minimal-rails:latest -e "require 'rails'; puts Rails.version"
docker run -d -p 5672:5672 -v rabbitmqdata:/var/lib/rabbitmq ghcr.io/rtvkiz/minimal-rabbitmq:latest
docker run -d -p 3000:3000 -v giteadata:/data/gitea ghcr.io/rtvkiz/minimal-gitea:latest
</details>
## Uso en producción
**Fija etiquetas de versión inmutables.** Cada imagen se publica con dos etiquetas:
| Etiqueta | Formato | Ejemplo | Mutable |
|---|---|---|---|
| Versión | `VERSION-rEPOCH` | `ghcr.io/rtvkiz/minimal-redis-slim:8.4.1-r0` | No |
| Latest | `latest` | `ghcr.io/rtvkiz/minimal-redis-slim:latest` | Sí |
### Variantes de desarrollo (`:latest-dev`)
La mayoría de las imágenes publican un acompañante `-dev` construido a partir de la **misma fuente que la versión de producción** — misma versión de runtime, mismo conjunto de paquetes seleccionados — además de un shell, gestor de paquetes, cadena de herramientas de compilación y herramientas de depuración adecuadas para la imagen. Diseñado para etapas de compilación de CI y depuración en pods, **no para implementación en producción**.
Uso típico en múltiples etapas:```dockerfile
FROM ghcr.io/rtvkiz/minimal-ruby:latest-dev AS build
WORKDIR /work
COPY Gemfile Gemfile.lock ./
RUN bundle install
FROM ghcr.io/rtvkiz/minimal-ruby:latest
COPY --from=build /work /work
Para obtener un shell interactivo, sobrescribe el entrypoint (las imágenes dev conservan el entrypoint de producción para compatibilidad de inserción directa):```bash docker run -it --entrypoint /bin/sh ghcr.io/rtvkiz/minimal-:latest-dev docker run -it --entrypoint /bin/bash ghcr.io/rtvkiz/minimal-:latest-dev
Las variantes de desarrollo comparten la firma, la SBOM y la cadena de procedencia SLSA de la imagen de producción. No están **registradas en el panel público de CVE** — expresamente tienen una superficie de ataque mayor. Consulte [`.github/SECURITY.md`](https://github.com/rtvkiz/minimal/blob/main/.github/SECURITY.md#dev-variants--dev-tags) para la política y [`docs/dev-variants/CONVENTIONS.md`](https://github.com/rtvkiz/minimal/blob/main/docs/dev-variants/CONVENTIONS.md) para las reglas de composición de paquetes.
**Envío hoy:** 57 de 57 variantes de desarrollo — cada imagen del catálogo ahora incluye un acompañante `:latest-dev` construido desde la misma fuente que la de producción.
<details>
<summary><strong>Estado de variante de desarrollo por imagen</strong></summary>
<br>
Leyenda: ✅ con envío de `:latest-dev` · 🚧 en progreso · 📝 planificado
Las categorías siguen las tres plantillas en [`docs/dev-variants/templates/`](https://github.com/rtvkiz/minimal/blob/main/docs/dev-variants/templates) (runtime / daemon / server). La columna "Referencia" muestra dónde reflejamos el conjunto de paquetes públicos de Chainguard `<image>-public/devConfigs`; **interno** significa que Chainguard envía una imagen solo para Enterprise y nosotros diseñamos la composición de desarrollo internamente.
| Imagen | Categoría | Referencia | Estado |
|---|---|---|---|
| ruby | runtime | Chainguard `ruby-public` | ✅ |
| python | runtime | Chainguard `python-public` | ✅ |
| node-slim | runtime | Chainguard `node-public` | ✅ |
| go | runtime | Chainguard `go-public` | ✅ |
| java | runtime | Chainguard `jdk-public` | ✅ |
| dotnet | runtime | Chainguard `dotnet-runtime-10-public` | ✅ |
| php | runtime | interno (composer diferido — ver PR) | ✅ |
| rails | runtime | interno (derivado de ruby) | ✅ |
| bun | runtime | interno | ✅ |
| deno | runtime | interno | ✅ |
| postgres-slim | daemon | Chainguard `postgres-public` | ✅ |
| mariadb | daemon | Chainguard `mariadb-public` | ✅ |
| mysql | daemon | interno | ✅ |
| redis-slim | daemon | Chainguard `redis-public` | ✅ |
| valkey | daemon | Chainguard `valkey-public` | ✅ |
| memcached | daemon | interno | ✅ |
| sqlite | daemon | interno | ✅ |
| opensearch | daemon | interno | ✅ |
| kafka | daemon | interno | ✅ |
| rabbitmq | daemon | interno | ✅ |
| nats | daemon | interno | ✅ |
| etcd | daemon | interno | ✅ |
| qdrant | daemon | interno | ✅ |
| nginx | server | Chainguard `nginx-public` | ✅ |
| haproxy | server | Chainguard `haproxy-public` | ✅ |
| minio | server | Chainguard `minio-client-public` (server interno) | ✅ |
| httpd | server | interno | ✅ |
| caddy | server | interno | ✅ |
| traefik | server | interno | ✅ |
| envoy | server | interno | ✅ |
| prometheus | server | interno | ✅ |
| victoria-metrics | server | interno | ✅ |
| jaeger | server | interno | ✅ |
| otelcol | server | interno | ✅ |
| loki | server | interno | ✅ |
| fluent-bit | server | interno | ✅ |
| node-exporter | server | interno | ✅ |
| blackbox-exporter | server | interno | ✅ |
| pushgateway | server | interno | ✅ |
| coredns | server | interno | ✅ |
| gitea | server | interno | ✅ |
| jenkins | server | interno | ✅ |
| keycloak | server | interno | ✅ |
| openbao | server | interno | ✅ |
| registry | server | Chainguard `registry-public` | ✅ |
| mailpit | server | interno (Chainguard no envía ningún mailpit público) | ✅ |
| consul | server | interno (Chainguard no envía ningún consul público; BUSL-1.1) | ✅ |
| tempo | server | interno (Chainguard no envía ningún tempo público; AGPL-3.0) | ✅ |
| mosquitto | daemon | interno (Chainguard no envía ningún mosquitto público; EPL-2.0/EDL-1.0) | ✅ |
</details>```dockerfile
# Production Dockerfile — pin by version tag, ideally by digest
FROM ghcr.io/rtvkiz/minimal-go:1.26.0-r0 AS build
WORKDIR /src
COPY . .
RUN go build -o /out/app
FROM ghcr.io/rtvkiz/minimal-python:3.14.0-r0
COPY --from=build /out/app /usr/bin/app
ENTRYPOINT ["/usr/bin/app"]
Aplicar firma + procedencia en Kubernetes con sigstore-policy-controller o Kyverno:```yaml
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: verify-minimal-images spec: validationFailureAction: Enforce rules: - name: check-signature match: any: - resources: kinds: [Pod] verifyImages: - imageReferences: - "ghcr.io/rtvkiz/minimal-" attestors: - entries: - keyless: subject: "https://github.com/rtvkiz/minimal/" issuer: "https://token.actions.githubusercontent.com"
The `-r0` suffix es el número de revisión — se reinicia a `r0` en cada incremento de versión upstream, se incrementa (`r1`, `r2`, …) para reconstrucciones de la misma versión upstream (por ejemplo, parches de dependencias). Las etiquetas de versiones antiguas se conservan entre reconstrucciones.
## Pipeline de construcción
<details>
<summary><strong>Diagrama del pipeline</strong></summary>
<br>```
┌─────────────────────────────────────────────────────────────────────────────┐
│ BUILD PIPELINE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Signing Keys: │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ PRs: keygen job (ephemeral) │ Main: repository secrets (persistent)│ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────────────┐ │
│ │ melange-build │ │ build-apko │ │
│ │ Native ARM64 runners │ │ Wolfi pre-built packages │ │
│ │ ┌────────┐ ┌────────────┐ │ │ ┌─────────┐ ┌───────────────┐ │ │
│ │ │ x86_64 │ │ aarch64 │ │ │ │ Wolfi │────►│ apko publish │ │ │
│ │ │ ubuntu │ │ ubuntu-arm │ │ │ │ packages│ │ (multi-arch) │ │ │
│ │ └────┬───┘ └─────┬──────┘ │ │ └─────────┘ └───────┬───────┘ │ │
│ │ └─────┬──────┘ │ │ │ │ │
│ │ ▼ │ └──────────────────────────│──────────┘ │
│ │ ┌──────────────┐ │ │ │
│ │ │ artifacts │ │ │ │
│ │ │ (x86+arm64) │ │ │ │
│ │ └──────┬───────┘ │ │ │
│ └────────────│────────────────┘ │ │
│ ▼ │ │
│ ┌─────────────────────────────┐ │ │
│ │ build-melange │ │ │
│ │ ┌─────────┐ ┌────────────┐ │ │ │
│ │ │ merge │►│ apko │─┼───────────────────────────────┤ │
│ │ │ packages│ │ publish │ │ │ │
│ │ └─────────┘ └────────────┘ │ │ │
│ └─────────────────────────────┘ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Verification & Attestation │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────────────┐ │ │
│ │ │ Grype │─►│ Test │─►│ cosign │─►│ SBOM + SLSA L3 │ │ │
│ │ │ CVE scan │ │ image │ │ sign │ │ attestations │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └─────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ Note: PRs build and test but do not publish. Only main branch publishes. │
└─────────────────────────────────────────────────────────────────────────────┘
| Disparador | Cuándo | Propósito |
|---|---|---|
| Scheduled | Cada 6 horas | Obtener los últimos parches de CVE de Wolfi |
| Push | Al fusionar en main | Implementar cambios de configuración |
| Manual | Workflow dispatch | Reconstrucciones de emergencia |
Los resultados del escaneo de vulnerabilidades aparecen en el catálogo en vivo, el resumen del trabajo y la pestaña de Seguridad de GitHub.
Las imágenes compiladas desde el origen son rastreadas por flujos de trabajo dedicados que verifican el upstream diariamente y abren PRs:
| Flujo de trabajo | Supervisa | Qué hace |
|---|---|---|
update-jenkins.yml | Versiones LTS de Jenkins | Actualiza la versión en la configuración de melange, Makefile, build.yml |
update-redis.yml | Lanzamientos de Redis en GitHub | Actualiza la versión y SHA256 |
update-mysql.yml | Etiquetas de GitHub de MySQL LTS (8.4.x) | Actualiza la versión y SHA256 |
update-memcached.yml | Lanzamientos de Memcached en GitHub | Actualiza la versión y SHA256 |
update-kafka.yml | Etiquetas de GitHub de Apache Kafka 4.x | Actualiza la versión y SHA512 |
update-php.yml | API de lanzamientos de php.net | Actualiza la versión y SHA256; abre un issue para nuevas series menores/principales |
update-rails.yml | API de RubyGems + etiquetas de GitHub de Ruby | Actualiza la gema Rails y las versiones fuente de Ruby de forma independiente |
update-rabbitmq.yml | Lanzamientos de RabbitMQ en GitHub | Actualiza la versión y SHA256 |
update-minio.yml | Lanzamientos de MinIO en GitHub | Actualiza la etiqueta de lanzamiento, versión basada en fecha y SHA256 |
update-victoria-metrics.yml | Lanzamientos de VictoriaMetrics en GitHub | Actualiza la versión y SHA256 |
update-jaeger.yml | Lanzamientos de Jaeger v2.x en GitHub | Actualiza la versión y SHA256; advierte sobre cambios de versión principal |
update-otelcol.yml | Lanzamientos estables de OTel Collector | Actualiza la versión y SHA256; omite prelanzamientos |
update-qdrant.yml | Lanzamientos de Qdrant v1.x en GitHub | Actualiza la versión y SHA256 |
update-etcd.yml | Lanzamientos de etcd v3.x en GitHub | Actualiza la versión y SHA256 |
update-opensearch.yml | Lanzamientos de OpenSearch 3.x en GitHub | Actualiza la versión en Makefile y README |
Las actualizaciones de parches se auto-PR y validan por CI. Los incrementos menores/principales crean un Issue de GitHub con una lista de verificación de actualización manual.
| Imagen | Versión | Usuario | Punto de entrada | Directorio de trabajo |
|---|---|---|---|---|
| Python | 3.14.x | nonroot (65532) | /usr/bin/python3 | /app |
| Node.js-slim | 25.x | nonroot (65532) | /usr/bin/dumb-init -- /usr/bin/node | /app |
| Bun | latest | nonroot (65532) | /usr/bin/bun | /app |
| Go | 1.26.x | nonroot (65532) | /usr/bin/go | /app |
| Nginx | mainline | nginx (65532) | /usr/sbin/nginx -g "daemon off;" | / |
| HTTPD | 2.4.x | www-data (65532) | /usr/sbin/httpd -DFOREGROUND | /var/www/localhost/htdocs |
| Jenkins | 2.555.x LTS | jenkins (1000) | tini -- java -jar jenkins.war | /var/jenkins_home |
| Redis | 8.6.x | redis (65532) | /usr/bin/redis-server | / |
| MySQL | 8.4.x | mysql (65532) | /usr/bin/docker-entrypoint.sh | / |
| MariaDB | 11.4.x | mariadb (65532) | /usr/bin/mariadbd | /var/lib/mysql |
| Memcached | 1.6.x | memcached (65532) | /usr/bin/memcached | / |
| PostgreSQL | 18.x | postgres (70) | /usr/bin/postgres | / |
| SQLite | 3.51.x | nonroot (65532) | /usr/bin/sqlite3 | /data |
| .NET Runtime | 10.x |
go install chainguard.dev/apko@latest go install chainguard.dev/melange@latest brew install anchore/grype/grype
make python make test-python
make build
make scan
Consulta el [Makefile](https://github.com/rtvkiz/minimal/blob/main/Makefile) para la lista completa de objetivos.
## Estructura del proyecto
<details>
<summary><strong>Estructura del repositorio</strong></summary>
<br>```
minimal/
├── <image>/
│ ├── apko/<name>.yaml # final image config
│ ├── melange.yaml # source build (optional)
│ └── test.sh # smoke test
├── .github/
│ ├── SECURITY.md # disclosure policy + verification recipes
│ └── workflows/
│ ├── build.yml # main CI pipeline (6h rebuilds)
│ ├── patch-go-deps.yml # daily Go transitive CVE patching
│ ├── update-<image>.yml # per-image upstream version tracking
│ └── update-wolfi-packages.yml
├── Makefile
├── README.md
├── CONTRIBUTING.md
└── LICENSE
Recientemente implementado:
cosign verify-attestation.gh attestation verify.Próximamente:
Qué no es este proyecto:
Se aceptan PRs. CONTRIBUTING.md tiene la configuración de compilación, las convenciones de imágenes y la lista de verificación de validación local que ejecuto antes de subir cambios.
Si encuentra un problema de seguridad, utilice el informe privado de vulnerabilidades de GitHub en lugar de abrir un informe público. La política de divulgación y el cronograma de respuesta están en .github/SECURITY.md.
MIT — ver LICENSE.
Las imágenes de contenedor incluyen paquetes de Wolfi y otras fuentes, cada una con sus propias licencias (Apache-2.0, MIT, GPL, LGPL, BSD, etc.). La información completa de licencias está en el SBOM de cada imagen:```bash cosign download sbom ghcr.io/rtvkiz/minimal-python:latest | jq '.packages[].licenseConcluded'
update-gitea.yml | Etiquetas de GitHub de Gitea v1.x | Actualiza la versión y SHA256 |
update-coredns.yml | Etiquetas de GitHub de CoreDNS v1.x | Actualiza la versión y SHA256 |
update-openbao.yml | Etiquetas de GitHub de OpenBao v2.x | Actualiza la versión y SHA256 |
update-loki.yml | Etiquetas de GitHub de Loki v3.x | Actualiza la versión y SHA256 |
update-fluent-bit.yml | Etiquetas de GitHub de Fluent Bit v5.x | Actualiza la versión y SHA256 |
update-keycloak.yml | Etiquetas de GitHub de Keycloak 26.x | Actualiza la versión y SHA256 |
update-wolfi-packages.yml | APKINDEX de Wolfi | Detecta nuevas versiones de Python, Node, Go, .NET, Java, PostgreSQL, Deno |
| nonroot (65532) |
/usr/bin/dotnet |
/app |
| Java | 26.x | nonroot (65532) | /usr/bin/java | /app |
| Ruby | 4.0.x | nonroot (65532) | /usr/bin/ruby | /work |
| PHP | 8.5.x | nonroot (65532) | /usr/bin/php | /app |
| Rails | Ruby 4.0.x + Rails 8.1.x | nonroot (65532) | /usr/bin/ruby | /app |
| Kafka | 4.2.x | kafka (65532) | /usr/bin/kafka-entrypoint.sh | / |
| RabbitMQ | 4.3.x | rabbitmq (65532) | /opt/rabbitmq/sbin/rabbitmq-server | / |
| NATS | latest | nonroot (65532) | /usr/bin/nats-server | / |
| Valkey | latest | nonroot (65532) | /usr/bin/valkey-server | / |
| MinIO | RELEASE.2025-10-15 | minio (65532) | /usr/bin/minio server --console-address :9001 /data | /data |
| OpenSearch | 3.7.0 | opensearch (65532) | /usr/share/opensearch/opensearch-docker-entrypoint.sh | /usr/share/opensearch/data |
| etcd | 3.6.x | nonroot (65532) | /usr/bin/etcd | /var/lib/etcd |
| VictoriaMetrics | 1.142.x | nonroot (65532) | /usr/bin/victoria-metrics | / |
| Jaeger | 2.18.x | nonroot (65532) | /usr/bin/jaeger | / |
| OTel Collector | 0.151.x | nonroot (65532) | /usr/bin/otelcol | / |
| Qdrant | 1.17.x | nonroot (65532) | /usr/bin/qdrant | /qdrant |
| Deno | 2.x | nonroot (65532) | /usr/bin/deno | /app |
| Gitea | 1.26.x | gitea (65532) | /usr/bin/gitea web --config /etc/gitea/app.ini | /var/lib/gitea |
| CoreDNS | 1.14.x | nonroot (65532) | /usr/bin/coredns | / |
| OpenBao | 2.5.x | openbao (65532) | /usr/bin/bao server | /openbao/data |
| Keycloak | 26.6.x | keycloak (65532) | /opt/keycloak/bin/kc.sh start-dev | /opt/keycloak/data |
| Loki | 3.6.x | loki (65532) | /usr/bin/loki | /loki |
| Fluent Bit | 5.0.x | nonroot (65532) | /usr/bin/fluent-bit | / |