[{"data":1,"prerenderedAt":205},["ShallowReactive",2],{"seo-verification":3,"blog-harbor-registry-self-hosted-en-vps-guia-completa-es":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-harbor-registry-self-hosted-en-vps-guia-completa-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":150,"ctaBody":151,"ctaButton":152,"ctaUrl":153,"relatedPosts":154},439,"harbor-registry-self-hosted-en-vps-guia-completa",{"fr":12,"en":13,"ar":14,"es":10},"self-host-harbor-registry-vps","self-host-harbor-registry-on-a-vps-complete-guide","استضافة-harbor-على-vps-سجل-حاويات-docker-خاص","Harbor Registry self-hosted en VPS: guía completa","Despliega Harbor v2.15 en tu VPS: registro Docker privado con escaneo Trivy, firma Cosign, RBAC y conformidad NIS2\u002FGDPR. Guía paso a paso.",8,0,false,"2026-10-13T00:00:00+00:00","2026-10-13T14:10:28+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},3,"Despliegue","deploiement","bg-success\u002F10 text-success",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-harbor-registry-vps-poster.svg","Desde que CVE-2026-21589 sacudió la cadena de suministro de Atlassian, los equipos DevOps buscan recuperar el control sobre cada artefacto que fluye por su pipeline. Docker Hub impone un límite de 100 pulls\u002F6h en cuentas gratuitas, GHCR vincula tus imágenes a la política de retención de GitHub, y ninguno firma ni escanea imágenes por defecto. Harbor, el registro open source de la CNCF, resuelve los tres problemas en un único despliegue: escaneo de vulnerabilidades Trivy integrado, firma Cosign, RBAC granular y logs de auditoría completos. Esta guía te lleva desde la instalación con Docker Compose hasta las políticas de admisión en producción, en un VPS de 4 vCPU \u002F 8 GB de RAM.",[34,38,49,52,77,80,83,87,90],{"type":35,"title":36,"body":37},"h2","Por qué un registro Docker privado con Harbor","Docker Hub y GHCR son servicios públicos convenientes, pero plantean tres problemas reales a medida que tu organización crece o debe cumplir con NIS2 (art. 21 § 2 f – seguridad de la cadena de suministro) o GDPR (datos de infraestructura alojados fuera de la UE). Harbor aborda cada punto directamente.",{"type":39,"title":40,"items":41},"ul","Beneficios clave de Harbor",[42,43,44,45,46,47,48],"**Escaneo Trivy integrado** — cada push dispara un análisis CVE; las políticas de admisión bloquean el despliegue de imágenes que superen el umbral de criticidad configurado.","**Firma Cosign \u002F Notary** — cadena de confianza desde el build CI hasta el clúster Kubernetes; solo pasan las imágenes firmadas con tu clave.","**RBAC multi-proyecto** — aislamiento por equipo, entorno (dev\u002Fstaging\u002Fprod) o cliente, con roles Guest, Developer, Maintainer y ProjectAdmin.","**Replicación entre registros** — sincroniza con un segundo VPS, AWS ECR o Docker Hub para distribución CDN.","**Logs de auditoría inmutables** — cada pull, push, eliminación e inicio de sesión queda registrado con la IP de origen; conformidad con NIS2 artículo 21 § 2 d.","**Sin límite de pulls** — tus runners CI descargan tantas imágenes como necesiten sin retrasos ni cuotas.","**OIDC nativo** — conecta Harbor a ZITADEL o cualquier proveedor OpenID Connect; cero cuentas locales que gestionar.",{"type":35,"title":50,"body":51},"Prerrequisitos cuantificados","Harbor funciona cómodamente en un VPS con la siguiente configuración:\n\n- **CPU**: 4 vCPU (mínimo 2 vCPU, pero Trivy consume 1–2 núcleos durante el escaneo)\n- **RAM**: 8 GB (mínimo 4 GB; reserva 2 GB para PostgreSQL, 1 GB para Redis, 2 GB para Harbor core, 1 GB de margen)\n- **Disco**: 100 GB SSD (las capas Docker se acumulan rápido; reserva 40 GB para el registro, 20 GB para los logs de Trivy, 20 GB para el sistema)\n- **SO**: Debian 12 o Ubuntu 22.04 LTS\n- **Docker**: ≥ 24.0, **Docker Compose**: ≥ 2.20\n- **DNS**: un subdominio apuntando a tu VPS (`registry.ejemplo.com`), ya resolviendo\n- **TLS**: certificado válido — Let's Encrypt via Certbot o Traefik ACME",{"type":53,"title":54,"steps":55},"steps","Instalación de Harbor v2.15 con Docker Compose",[56,59,62,65,68,71,74],{"title":57,"body":58},"Descargar el instalador offline","Conéctate por SSH a tu VPS. Descarga el paquete offline Harbor v2.15.4 (el más estable a 2026-10-13) desde GitHub:\n\n```bash\nexport HARBOR_VERSION=v2.15.4\nwget https:\u002F\u002Fgithub.com\u002Fgoharbor\u002Fharbor\u002Freleases\u002Fdownload\u002F${HARBOR_VERSION}\u002Fharbor-offline-installer-${HARBOR_VERSION}.tgz\nwget https:\u002F\u002Fgithub.com\u002Fgoharbor\u002Fharbor\u002Freleases\u002Fdownload\u002F${HARBOR_VERSION}\u002Fharbor-offline-installer-${HARBOR_VERSION}.tgz.asc\n# Verificar la firma GPG\ngpg --keyserver keyserver.ubuntu.com --recv-keys 7722D168DAEC457894C2988818B80B4B2D318C8A\ngpg --verify harbor-offline-installer-${HARBOR_VERSION}.tgz.asc\ntar xvf harbor-offline-installer-${HARBOR_VERSION}.tgz\ncd harbor\n```",{"title":60,"body":61},"Preparar los certificados TLS","Harbor requiere TLS. Con Certbot:\n\n```bash\napt install -y certbot\ncertbot certonly --standalone -d registry.ejemplo.com\n# Los certificados están en \u002Fetc\u002Fletsencrypt\u002Flive\u002Fregistry.ejemplo.com\u002F\nmkdir -p \u002Fdata\u002Fcert\ncp \u002Fetc\u002Fletsencrypt\u002Flive\u002Fregistry.ejemplo.com\u002Ffullchain.pem \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.crt\ncp \u002Fetc\u002Fletsencrypt\u002Flive\u002Fregistry.ejemplo.com\u002Fprivkey.pem  \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.key\n```\n\nSi usas Traefik como reverse proxy (ver el artículo de Traefik v3), delega la terminación TLS a Traefik y configura Harbor en HTTP interno en el puerto 8080.",{"title":63,"body":64},"Configurar ‎harbor.yml","Copia la plantilla y ajusta los valores esenciales:\n\n```bash\ncp harbor.yml.tmpl harbor.yml\n```\n\nEdita `harbor.yml`:\n\n```yaml\nhostname: registry.ejemplo.com\n\nhttps:\n  port: 443\n  certificate: \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.crt\n  private_key: \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.key\n\nharbor_admin_password: CambiaEstaContrasena!\n\ndatabase:\n  password: CambiaEstasTambien!\n\ndata_volume: \u002Fdata\n\ntrivy:\n  ignore_unfixed: false\n  skip_update: false\n  offline_scan: false\n  security_check: vuln\n  insecure: false\n```",{"title":66,"body":67},"Ejecutar el instalador","Harbor ofrece componentes opcionales. Activa Trivy (escáner) y Notary (firmas):\n\n```bash\n.\u002Finstall.sh --with-trivy --with-notary\n```\n\nEl instalador genera un `docker-compose.yml` y arranca todos los contenedores. Verifica que todos estén `healthy`:\n\n```bash\ndocker compose ps\n# STATUS esperado para cada servicio: healthy\n```",{"title":69,"body":70},"Primer inicio de sesión y cambio de contraseña","Abre `https:\u002F\u002Fregistry.ejemplo.com` en tu navegador. Inicia sesión con `admin` \u002F la contraseña de `harbor.yml`. Ve a **Administration → Users → admin** y cambia la contraseña inmediatamente.\n\nDesde tu estación de trabajo o runner CI:\n\n```bash\ndocker login registry.ejemplo.com\n# Introduce tus credenciales de admin o una cuenta de servicio\n```",{"title":72,"body":73},"Crear un proyecto y hacer push de la primera imagen","En la interfaz de Harbor, crea un proyecto `mi-proyecto` (privado). Luego desde tu máquina de build:\n\n```bash\ndocker pull nginx:alpine\ndocker tag nginx:alpine registry.ejemplo.com\u002Fmi-proyecto\u002Fnginx:1.27-alpine\ndocker push registry.ejemplo.com\u002Fmi-proyecto\u002Fnginx:1.27-alpine\n# En Harbor → mi-proyecto → Repositories: la imagen aparece con su estado Trivy\n```",{"title":75,"body":76},"Habilitar la renovación automática de TLS","Crea un hook post-renovación de Certbot para recargar Harbor:\n\n```bash\ncat > \u002Fetc\u002Fletsencrypt\u002Frenewal-hooks\u002Fpost\u002Fharbor-reload.sh \u003C\u003C 'EOF'\n#!\u002Fbin\u002Fbash\ncp \u002Fetc\u002Fletsencrypt\u002Flive\u002Fregistry.ejemplo.com\u002Ffullchain.pem \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.crt\ncp \u002Fetc\u002Fletsencrypt\u002Flive\u002Fregistry.ejemplo.com\u002Fprivkey.pem  \u002Fdata\u002Fcert\u002Fregistry.ejemplo.com.key\ncd \u002Fopt\u002Fharbor && docker compose restart proxy\nEOF\nchmod +x \u002Fetc\u002Fletsencrypt\u002Frenewal-hooks\u002Fpost\u002Fharbor-reload.sh\n```",{"type":35,"title":78,"body":79},"Configuración: proyectos, usuarios y OIDC (ZITADEL)","**Proyectos y RBAC**\n\nHarbor organiza las imágenes por proyectos. Cada proyecto puede ser público o privado, con una política de retención independiente. Crea un proyecto por equipo o entorno: `frontend`, `backend`, `infra`. Asigna miembros con roles granulares:\n\n- **Guest**: solo pull\n- **Developer**: push + pull\n- **Maintainer**: gestión de tags, webhooks y políticas de retención\n- **ProjectAdmin**: gestión de miembros\n\n**Integración OIDC con ZITADEL**\n\nSi ya has desplegado ZITADEL (ver el artículo dedicado), conectar Harbor es cuestión de unos pocos clics. En ZITADEL, crea una aplicación `harbor` de tipo *Web*, anota el `Client ID` y el `Client Secret`. En Harbor → **Administration → Configuration → Authentication**:\n\n- Auth Mode: `OIDC`\n- OIDC Provider Name: `ZITADEL`\n- OIDC Endpoint: `https:\u002F\u002Fsso.ejemplo.com`\n- OIDC Client ID \u002F Secret: los de ZITADEL\n- OIDC Scope: `openid profile email groups`\n- Marca **Verify Certificate**\n\nEn el primer inicio de sesión OIDC, Harbor crea automáticamente la cuenta de usuario. Luego desactiva la creación de cuentas locales (**Administration → Configuration → Allow Self-Registration → Off**).",{"type":35,"title":81,"body":82},"Escanear imágenes con Trivy","Harbor embebe Trivy directamente en el pipeline de push. En cuanto se hace push de una imagen, Harbor lanza un escaneo asíncrono que consulta la base CVE de Trivy (actualizada diariamente). El resultado aparece en la interfaz: número de vulnerabilidades por gravedad (CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN).\n\n**Activar el escaneo automático en push**: en Harbor → **Administration → Configuration → Vulnerability** → marca *Automatically scan images on push*.\n\n**Consultar un informe**: abre un repositorio, haz clic en un tag → pestaña *Vulnerabilities*. Cada CVE lista el paquete afectado, la versión corregida y un enlace a la NVD.\n\n**Versión de Trivy en Harbor v2.15**: Harbor v2.15.4 incluye `trivy-adapter` alineado con Trivy v0.55.x, con soporte para bases OS (Alpine, Debian, RHEL, Ubuntu), gestores de paquetes de aplicación (npm, pip, cargo, ‎go.mod) y archivos de lock.\n\n**Políticas de conformidad por proyecto**: en Harbor → *Tu proyecto* → **Policy** → *Deployment Security* → elige el nivel de gravedad que bloquea el pull. Por ejemplo, bloquear cualquier pull de una imagen con al menos una CVE CRITICAL no corregida.",{"type":84,"title":85,"body":86},"tip","Consejo de seguridad: políticas de admisión en Kubernetes","Combina Harbor con el controlador de admisión **Cosign** (vía Kyverno o Connaisseur) para que ninguna imagen sin firmar o con una CVE CRITICAL pueda entrar en tu clúster. En tu pipeline CI:\n\n```bash\n# Firmar la imagen con Cosign después del build\ncosign sign --key cosign.key registry.ejemplo.com\u002Fmi-proyecto\u002Fnginx:1.27-alpine\n# Verificar en CI antes del despliegue\ncosign verify --key cosign.pub registry.ejemplo.com\u002Fmi-proyecto\u002Fnginx:1.27-alpine\n```\n\nConfigura una política Kyverno que exija la firma de Harbor: cualquier pod cuya imagen no esté firmada por tu clave es rechazado en la admisión. Esto cierra la brecha más explotada en los ataques a la cadena de suministro tras CVE-2026-21589.",{"type":35,"title":88,"body":89},"Solución de problemas: 5 errores reales con sus causas","**1. `Error response from daemon: Get https:\u002F\u002Fregistry.ejemplo.com\u002Fv2\u002F: x509: certificate signed by unknown authority`**\nCausa: el certificado Let's Encrypt no se ha propagado aún o estás usando un certificado auto-firmado.\nSolución: en cada nodo Docker cliente, copia `fullchain.pem` a `\u002Fetc\u002Fdocker\u002Fcerts.d\u002Fregistry.ejemplo.com\u002Fca.crt` y luego `systemctl restart docker`.\n\n**2. `harbor-core` reiniciando en bucle con `Error 1045 (28000): Access denied for user 'root'@'localhost'`**\nCausa: el volumen PostgreSQL contiene datos de una instalación anterior con una contraseña diferente.\nSolución: `docker compose down -v` (⚠️ borra los datos), modifica la contraseña en `harbor.yml`, vuelve a ejecutar `.\u002Fprepare && docker compose up -d`.\n\n**3. Escaneo Trivy bloqueado en `Fetching vulnerability DB` durante más de 10 minutos**\nCausa: el VPS no puede acceder a `ghcr.io` (firewall de salida restrictivo) para descargar la base de Trivy.\nSolución: permite la salida HTTPS hacia `ghcr.io` y `pkg.dev`, o activa `offline_scan: true` tras precargar la base con `trivy image --download-db-only`.\n\n**4. `unauthorized: unauthorized to access repository` en CI pese a un `docker login` exitoso**\nCausa: la cuenta de servicio no tiene el rol Developer en el proyecto destino.\nSolución: en Harbor → *Tu proyecto* → **Members** → añade la cuenta robot o usuario con el rol Developer o superior.\n\n**5. Interfaz de Harbor inaccesible tras la renovación del certificado Let's Encrypt**\nCausa: el contenedor `proxy` (nginx) sigue sirviendo el antiguo certificado cargado en memoria.\nSolución: `docker compose restart proxy` desde la carpeta de instalación de Harbor. Lo ideal es automatizarlo mediante el hook post-renovación descrito en el paso 7.",{"type":91,"title":92,"headers":93,"rows":99},"comparison","Harbor vs Docker Hub vs GHCR vs Gitea Registry",[94,95,96,97,98],"Criterio","Harbor self-hosted","Docker Hub","GHCR","Gitea Registry",[100,106,111,116,122,127,133,138,144],[101,102,103,104,105],"Alojamiento","Tu VPS (datos en la UE)","Servidores Docker Inc. (EE.UU.)","Servidores GitHub\u002FMicrosoft (EE.UU.\u002FUE opt.)","Tu VPS",[107,108,109,110,110],"Escaneo de vulnerabilidades","Trivy integrado, auto en push","Docker Scout (de pago)","Ninguno nativo",[112,113,114,115,110],"Firma de imágenes","Cosign + Notary v2","DCT (obsoleto)","Cosign externo",[117,118,119,120,121],"RBAC granular","5 roles por proyecto","Roles de organización limitados","Roles GitHub (gruesos)","Roles básicos de Gitea",[123,124,125,126,124],"Límite de pulls","Ninguno","100\u002F6h (gratis), 5000\u002Fdía (Pro)","Vinculado a límites de GitHub",[128,129,130,131,132],"OIDC\u002FSSO nativo","Sí (LDAP, OIDC, SAML)","No (SSO empresarial de pago)","Solo SSO de GitHub","OIDC parcial",[134,135,136,137,136],"Logs de auditoría completos","Sí (IP, usuario, acción, tag)","Limitado","Parcial vía auditoría GitHub",[139,140,141,142,143],"Conformidad NIS2\u002FGDPR","Total (datos on-premise)","Solo contractual","DPA Microsoft disponible","Total (on-premise)",[145,146,147,148,149],"Coste","VPS (~15–30 €\u002Fmes)","Gratis \u002F Pro ~5$\u002Fmes","Incluido en GitHub Free\u002FPro","VPS compartido con Gitea","Despliega tu registro Harbor en un VPS ServOrbit","Un VPS de 4 vCPU \u002F 8 GB RAM es suficiente para ejecutar Harbor en producción para un equipo de 10 desarrolladores. ServOrbit entrega la VM en menos de 90 segundos, con acceso root SSH y snapshots automáticos incluidos.","Ver planes para agencias","\u002Fsolutions\u002Fagences",[155,170,191],{"id":156,"slug":157,"slugs":158,"title":162,"excerpt":163,"readTime":164,"views":18,"isPinned":19,"publishedAt":165,"updatedAt":21,"category":166,"categories":167,"featuredImage":29,"bgImage":30,"posterImage":169,"relatedSolution":29},434,"traefik-v3-vps-reverse-proxy-docker-https",{"fr":159,"en":160,"ar":161,"es":157},"traefik-v3-vps-reverse-proxy","traefik-v3-vps-docker-reverse-proxy-https","traefik-v3-على-vps-ريفرس-بروكسي-docker","Traefik v3 en VPS: reverse proxy Docker con HTTPS automático","Despliega Traefik v3 en tu VPS: HTTPS automático con Let's Encrypt, enrutamiento por etiquetas Docker, dashboard seguro.",9,"2026-10-12T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[168],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Ftraefik-v3-vps-reverse-proxy-poster.svg",{"id":171,"slug":172,"slugs":173,"title":177,"excerpt":178,"readTime":179,"views":18,"isPinned":19,"publishedAt":165,"updatedAt":21,"category":180,"categories":185,"featuredImage":29,"bgImage":30,"posterImage":187,"relatedSolution":188},435,"zitadel-vps-sso-multi-tenant-sin-keycloak",{"fr":174,"en":175,"ar":176,"es":172},"zitadel-sso-self-hosted-vps","self-hosting-zitadel-vps-multi-tenant-sso","استضافة-zitadel-على-vps-sso-متعدد-المستأجرين","Alojar ZITADEL en un VPS: SSO multi-tenant sin Keycloak","Despliega ZITADEL en tu VPS con Docker Compose: IAM cloud-native en Go, multi-tenancy nativo, OIDC, OAuth2, SAML y Passkeys, sin la complejidad de Keycloak.",14,{"id":17,"name":181,"slug":182,"color":183,"icon":184},"Seguridad y monitorización","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[186],{"id":17,"name":181,"slug":182,"color":183,"icon":184},"\u002Fblog\u002Fcovers\u002Fzitadel-sso-self-hosted-vps-poster.svg",{"categorySlug":189,"appSlug":190},"ciberseguridad-bastion","zitadel",{"id":192,"slug":193,"slugs":194,"title":198,"excerpt":199,"readTime":164,"views":18,"isPinned":19,"publishedAt":200,"updatedAt":21,"category":201,"categories":202,"featuredImage":29,"bgImage":30,"posterImage":204,"relatedSolution":29},431,"cve-2026-21589-parche-atlassian-jira-confluence",{"fr":195,"en":196,"ar":197,"es":193},"atlassian-cve-2026-21589-patch-jira-confluence-self-hosted","cve-2026-21589-patch-atlassian-jira-confluence-self-hosted","cve-2026-21589-patch-atlassian-jira-confluence","CVE-2026-21589: parchea Atlassian sin esperar","CVE-2026-21589 es un path traversal no autenticado (CVSS 9.3) que afecta todos los productos Atlassian Data Center. Versiones a parchear, comandos de verificación.","2026-10-11T00:00:00+00:00",{"id":17,"name":181,"slug":182,"color":183,"icon":184},[203],{"id":17,"name":181,"slug":182,"color":183,"icon":184},"\u002Fblog\u002Fcovers\u002Fatlassian-cve-2026-21589-patch-jira-confluence-self-hosted-poster.svg",1791901101528]