Saltar a contenido

ADR-0001 · Build en GitHub Actions e imagen en GHCR; deploy en runners self-hosted

  • Estado: aceptado
  • Decisores: no registrado en el repositorio (reconstruido del historial de commits)
  • Fecha de la decisión: 2026-06-17 (commits 3124390, 1a65de0, 98e09fb, 4ef7c9e)

Contexto y problema

Los servidores de staging y producción son máquinas privadas sin exposición pública, así que GitHub no puede desplegar por SSH desde un runner alojado. Al mismo tiempo, compilar la imagen en esas máquinas competía por CPU con la aplicación (la de producción tiene 2 cores). Se necesitaba un mecanismo que permitiera desplegar la misma imagen a los dos ambientes y volver atrás por tag.

Opciones consideradas

  1. Build en runners de GitHub (ubuntu-latest) → push a GHCR → deploy en runners self-hosted que solo hacen pull y docker compose up (elegida).
  2. Build y deploy en el runner self-hosted de staging — se probó (98e09fb) y se revirtió el mismo día (4ef7c9e, "volver a ubuntu-latest para mejor velocidad de npm").
  3. Build local y push manual a un registry externo (sirhugh/medusa-backend), como describe el plan de upgrade a 2.15.5 — descartado al estandarizar en GHCR.

Decisión

El build corre en ubuntu-latest con caché de buildx y publica en ghcr.io/compulandiati/ecommercev2backend. Los runners self-hosted, con labels staging y ecommerce-srv-production, solo hacen docker login, pull y ejecutan deploy.sh. Los tags son inmutables por commit (staging-sha-<7> / sha-<7>) más un móvil por ambiente (staging-latest / latest), lo que hace que el rollback sea "desplegar otro tag".

Consecuencias

Positivas

  • Lo probado en staging y lo desplegado en producción son el mismo artefacto binario.
  • El servidor no gasta CPU compilando; el build aprovecha la caché de GitHub Actions.
  • Rollback trivial por tag, y deploy.sh puede automatizarlo con rollback-prev.

Negativas / deuda asumida

  • Dependencia dura de GHCR y del secret GHCR_PAT: si el token vence, no se puede desplegar ni revertir (la falla #1 del runbook).
  • Hay que mantener runners self-hosted (systemd, SSH keys, pertenencia al grupo docker), con su propia clase de fallas.
  • El nombre del repositorio tiene mayúsculas y GHCR no las acepta: obliga a un step de normalización que ya rompió el pipeline dos veces (7c32137, 7312888).