From 72975e44ae42c24cd0d842f05ddd8585389d56da Mon Sep 17 00:00:00 2001 From: vjrj Date: Tue, 28 Jul 2026 12:28:29 +0200 Subject: [PATCH] ci: construir la imagen de la web en el runner, no en el host de despliegue groucho (5,9 GB, compartidos con Mongo 7 + web + notifications + redis + node-red) se quedo sin ssh compilando un `meteor build` y hubo que reiniciarlo. El host de despliegue no debe compilar: debe recibir una imagen. Workflow para el runner de Forgejo en aaron. Dos decisiones que conviene no deshacer sin leer fase-9-ci-imagenes.md: - Kaniko en vez de `docker build`: aaron es host COMPARTIDO (git.comunes.org, Jenkins, GlitchTip). `docker build` obligaria a montar /var/run/docker.sock en el job (root equivalente sobre aaron) y ademas el limite de memoria del job no serviria de nada, porque quien construye es el demonio, fuera del contenedor. Kaniko construye DENTRO del job: sin socket y con `--memory` que si acota al que come la RAM. - `--memory=4g --memory-swap=4g`: swap a cero adrede. Preferimos que muera el build a que aaron pagine y se lleve la forja por delante. De momento solo `workflow_dispatch`. El disparo por push queda comentado hasta que git.comunes.org salga de detras de Cloudflare (la capa del bundle son 508 MB contra un tope de 100 MB del plan gratuito: el push se queda en Retrying eterno) y existan los secretos REGISTRY_USER/REGISTRY_TOKEN. --- .forgejo/workflows/build-image.yml | 97 ++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 .forgejo/workflows/build-image.yml diff --git a/.forgejo/workflows/build-image.yml b/.forgejo/workflows/build-image.yml new file mode 100644 index 0000000..ffdc59b --- /dev/null +++ b/.forgejo/workflows/build-image.yml @@ -0,0 +1,97 @@ +# Construye la imagen Docker de la web y la sube al registry de Forgejo. +# +# POR QUÉ: antes el build corría en groucho, el host de despliegue (5,9 GB de RAM +# compartidos con Mongo 7 + web + notifications + redis + node-red). Un `meteor build` +# lo asfixiaba hasta dejarlo sin ssh. A partir de aquí groucho **no compila**: hace +# `docker compose pull && up -d web` y ya. +# +# runs-on: docker → el runner de aaron (forge.yml, label `docker`, capacity 1). +# +# ⚠️ POR QUÉ KANIKO Y NO `docker build`: +# aaron es un host COMPARTIDO — aloja git.comunes.org, Jenkins y GlitchTip. Construir con +# `docker build` exige montar /var/run/docker.sock en el job, que es poder +# root-equivalente sobre aaron; y además el límite de memoria del contenedor del job NO +# afectaría al build, porque quien construye es el demonio, fuera del job. Kaniko +# construye DENTRO del contenedor del job: no hace falta socket y `--memory` sí acota al +# proceso que se come la RAM. Si el `meteor build` muere por memoria, sube el `--memory` +# de `container.options` (y mira qué más está corriendo en aaron), no lo quites. + +name: build-image + +# De momento SOLO manual. El disparo por push está comentado a propósito: hasta que +# `git.comunes.org` salga de detrás de Cloudflare (capa de 508 MB contra un tope de 100 MB, +# ver plan-modernizacion/fase-9-ci-imagenes.md) y existan los secretos REGISTRY_*, cada push +# lanzaría un `meteor build` de ~30 min en aaron para morir al subir. Descomentar cuando +# la primera pasada manual esté verde. +on: + workflow_dispatch: + # push: + # branches: [meteor3-wip, tcef-master] + # paths-ignore: ['**.md'] + +jobs: + build: + runs-on: docker + container: + # `:debug` trae busybox: el runner necesita una shell para ejecutar los `run:`. + image: gcr.io/kaniko-project/executor:v1.23.2-debug + # Tope duro para no asfixiar aaron. memory-swap == memory ⇒ swap 0: preferimos que + # muera el build a que el host empiece a paginar y se lleve por delante la forja. + options: --memory=4g --memory-swap=4g --cpus=3 + env: + IMAGE: git.comunes.org/comunes/tcef-web + steps: + # Checkout a mano contra el Forgejo interno, igual que el CI de fires_flutter: + # la imagen de kaniko no tiene Node, así que las actions basadas en JS no valen. + - name: Checkout + shell: sh + env: + TOKEN: ${{ github.token }} + run: | + set -e + export PATH=/busybox:/kaniko:$PATH + git config --global --add safe.directory '*' + git init -q . + git remote add origin "http://x-access-token:${TOKEN}@forgejo:3000/${GITHUB_REPOSITORY}.git" + git fetch -q --depth 1 origin "${GITHUB_SHA}" + git checkout -q FETCH_HEAD + + - name: Credenciales del registry + shell: sh + env: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + set -e + export PATH=/busybox:/kaniko:$PATH + mkdir -p /kaniko/.docker + AUTH=$(printf '%s:%s' "$REGISTRY_USER" "$REGISTRY_TOKEN" | base64 | tr -d '\n') + printf '{"auths":{"git.comunes.org":{"auth":"%s"}}}' "$AUTH" > /kaniko/.docker/config.json + + - name: Build y push + shell: sh + run: | + set -e + export PATH=/busybox:/kaniko:$PATH + SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-12) + BRANCH_TAG=$(echo "$GITHUB_REF_NAME" | tr '/' '-') + # --cache: reutiliza capas entre builds (apt, meteor-tool, npm install) contra + # el propio registry; sin esto cada push recompila el mundo. + # --single-snapshot y --compressed-caching=false bajan mucho el pico de RAM, + # que es justo lo que nos importa en un host compartido. + /kaniko/executor \ + --context "dir:///$(pwd)" \ + --dockerfile Dockerfile \ + --destination "${IMAGE}:${BRANCH_TAG}" \ + --destination "${IMAGE}:${SHORT_SHA}" \ + --cache=true \ + --cache-repo "${IMAGE}/cache" \ + --compressed-caching=false \ + --snapshot-mode=redo \ + --verbosity=info + echo "Publicado ${IMAGE}:${BRANCH_TAG} y :${SHORT_SHA}" + + - name: Cómo desplegar + shell: sh + run: | + echo "En groucho: cd /data/tcef-staging && docker compose pull web && docker compose up -d web"