9.1 KiB
Scripts de despliegue
Guía de uso de los scripts de este directorio.
build-and-push.sh
Construye la imagen nativa de Quarkus y la envía al daemon Docker de un host remoto por SSH, sin usar un registry externo (unregistry / docker pussh). Solo se transfieren las capas que el remoto aún no tiene.
Qué hace el flujo
- Toma el nombre de la imagen de la última carpeta de la ubicación del servicio y lee
versiondepom.xmlpara el tag, salvo que uses--nameo--tag. Si no haypom.xml, el tag es1.0.0-SNAPSHOT. - Ejecuta
docker buildpara la plataforma fijalinux/amd64(útil si construyes desde un Mac arm64). Con--type java(el valor por defecto) usasrc/main/docker/Dockerfile. Con--type webusaDockerfileen la raíz del servicio. - Ejecuta
docker pusshhacia el destino SSH indicado. - Comprueba por SSH que la imagen existe en el remoto (salvo
--no-verify). - Muestra un comando
docker runsugerido para arrancar el contenedor en el remoto.
Requisitos
| Requisito | Descripción |
|---|---|
| Docker local | Daemon en marcha (docker info debe responder). |
| SSH | Acceso al host remoto; en el remoto debe estar instalado y usable Docker. |
Plugin docker pussh |
CLI plugin de unregistry. |
Si el plugin no está instalado, el script indica cómo añadirlo:
mkdir -p ~/.docker/cli-plugins
curl -fsSL https://raw.githubusercontent.com/psviderski/unregistry/main/docker-pussh \
-o ~/.docker/cli-plugins/docker-pussh
chmod +x ~/.docker/cli-plugins/docker-pussh
xmllint es opcional: si no está en el PATH y existe pom.xml, el script obtiene version del POM con grep/sed.
Invocación
Puedes ejecutar el script desde cualquier directorio. Por defecto usa como raíz del proyecto el directorio padre de scripts/ (donde está pom.xml).
./scripts/build-and-push.sh --remote USER@HOST
Alternativas para la raíz del proyecto:
--project-dir /ruta/al/proyecto- variable de entorno
PROJECT_DIR
Ayuda integrada (en inglés):
./scripts/build-and-push.sh --help
Opciones
Destino (obligatorio)
| Opción | Descripción |
|---|---|
--remote TARGET |
Destino SSH: usuario@host[:puerto] o un alias definido en ~/.ssh/config (sin @). |
Identidad de la imagen (el nombre es la última carpeta del servicio; el tag sale de pom.xml si existe)
| Opción | Descripción |
|---|---|
--name NAME |
Nombre del repositorio de la imagen. |
--tag TAG |
Tag de la imagen. |
Directorio de trabajo
| Opción | Descripción |
|---|---|
--project-dir PATH |
Raíz del servicio. El nombre de la imagen es su última carpeta. |
PROJECT_DIR |
Misma función vía entorno. |
Build
| Opción | Descripción |
|---|---|
--type |
Dónde está el Dockerfile. java (por defecto): src/main/docker/Dockerfile. web: Dockerfile en la raíz del servicio. |
--skip-build |
No construye; solo hace pussh de una imagen que ya exista en local. La plataforma de build sigue siendo linux/amd64 cuando no se omite el build. |
SSH (se reenvían a docker pussh y, en la verificación, a ssh)
| Opción | Descripción |
|---|---|
--ssh-key PATH |
Clave privada; tiene prioridad sobre IdentityFile del config SSH. |
--ssh-config PATH |
Archivo de configuración SSH (por defecto ~/.ssh/config). |
Post-push
| Opción | Descripción |
|---|---|
--no-verify |
Omite la comprobación docker images en el remoto. |
Otros
| Opción | Descripción |
|---|---|
-h, --help |
Muestra la ayuda del script. |
Alias en ~/.ssh/config
Si --remote es un alias sin @, el script resuelve HostName, User, Port e IdentityFile del bloque Host correspondiente. --ssh-key siempre anula IdentityFile.
Ejemplo de configuración:
# ~/.ssh/config
Host prod
HostName prod.example.com
User deploy
Port 22
IdentityFile ~/.ssh/deploy_ed25519
Uso:
./scripts/build-and-push.sh --remote prod
# Equivale a deploy@prod.example.com:22 con la clave del bloque Host prod
Ejemplos
Destino explícito:
./scripts/build-and-push.sh --remote deploy@prod.example.com
Alias SSH:
./scripts/build-and-push.sh --remote prod
Clave explícita:
./scripts/build-and-push.sh --remote ubuntu@1.2.3.4 --ssh-key ~/.ssh/deploy_ed25519
Solo push (imagen ya construida) con otro tag:
./scripts/build-and-push.sh --remote deploy@prod --skip-build --tag 2.0.0
Ruta absoluta al script:
/absolute/path/to/test-quarkus/scripts/build-and-push.sh --remote deploy@prod
Proyecto en otra ruta:
PROJECT_DIR=/srv/proj ./scripts/build-and-push.sh --remote deploy@prod --skip-build
Después del push
Al terminar con éxito, el script sugiere algo equivalente a:
ssh deploy@prod.example.com \
"docker run -d --name <carpeta> --restart unless-stopped -p 8080:8080 <carpeta>:<version>"
Sustituye <carpeta> por la última carpeta de la ubicación del servicio (o el valor de --name) y <version> por el tag del build (el de pom.xml, 1.0.0-SNAPSHOT si no hay POM, o el de --tag).
Solución de problemas
invalid reference format con saltos de línea en el tag
Si docker build falla con un tag parecido a test-quarkus\n1.0.0-SNAPSHOT:test-quarkus\n1.0.0-SNAPSHOT, el checkout del script es anterior al commit 57af30f. En hosts sin xmllint (por ejemplo vm-compilador), el fallback antiguo de read_pom mezclaba artifactId y version en una sola cadena.
En la máquina donde compilas (~/repo u otra ruta del proyecto):
git rev-parse --short HEAD
grep -n 'head -2' scripts/build-and-push.sh || echo "script actualizado"
git pull
git rev-parse --short HEAD # debe ser 57af30f o posterior
./scripts/build-and-push.sh --remote TU_DESTINO
Comprueba que la primera línea del log sea Image: test-quarkus:1.0.0-SNAPSHOT (sin saltos de línea).
Atajo si aún no puedes actualizar el repo: fija nombre y tag explícitos (no usa el fallback roto):
./scripts/build-and-push.sh --remote TU_DESTINO \
--name test-quarkus --tag 1.0.0-SNAPSHOT
Opcional: instala xmllint para que el script lea el POM con XPath (libxml2-utils en Debian/Ubuntu).
deploy-services.sh
Script independiente, en el mismo directorio que build-and-push.sh. No lo modifica: lo ejecuta una vez por cada servicio de un archivo de lista. Si un servicio falla, sigue con el resto y al terminar indica cuáles fallaron. El código de salida es 1 si alguno falló.
Al terminar el lote, ese resumen queda también en deploy-YYYYMMDD-HHMMSS.log en el directorio desde el que se lanzó el script (hora local de inicio). Si ese nombre ya existe, se añade el PID. Si no se puede escribir el archivo, el script avisa y conserva el código de salida del lote.
No hay lista por defecto. --services es obligatorio, así cada proyecto puede tener su propio archivo.
./scripts/deploy-services.sh --remote prod --services /srv/proyecto-a/services.txt
./scripts/deploy-services.sh --remote prod --services /srv/proyecto-b/services.txt --skip-build
Formato del archivo: una ruta por línea y, si hace falta, un segundo campo java o web. Si el tipo falta, es java. Se ignoran las líneas vacías y las que empiezan por #. Una ruta relativa se resuelve desde el directorio del archivo de lista, no desde el directorio donde lanzas el script.
# /srv/proyecto-a/services.txt
./api
./portal web
java usa src/main/docker/Dockerfile. web usa Dockerfile en la raíz del servicio. El nombre de la imagen es la última carpeta de esa ruta. El tag sale de pom.xml si existe; si no, es 1.0.0-SNAPSHOT.
Se reenvían a cada servicio: --ssh-key, --ssh-config, --skip-build, --no-verify y --cleanup, más el --type de esa línea. No se aceptan --name, --tag, --project-dir ni --type.
Ctrl+C interrumpe el lote. Ayuda: ./scripts/deploy-services.sh --help.
update-repos.sh
Actualiza un repositorio git por cada ruta de un archivo de lista. Ejecuta git pull en cada uno. Si alguno falla, sigue con el resto y al terminar indica cuáles fallaron. El código de salida es 1 si alguno falló.
No hay lista por defecto. --repos es obligatorio.
./scripts/update-repos.sh --repos /srv/proyecto/repos.txt
Al arrancar pide Usuario: y Contraseña: en la terminal, una sola vez para todo el lote. Esas credenciales se usan en los remotos HTTPS. No se leen desde la línea de comandos ni desde el archivo, y no se guardan. Un remoto SSH se actualiza con su acceso habitual (clave), sin esa contraseña.
Formato del archivo: una ruta por línea. Se ignoran las líneas vacías y las que empiezan por #. Una ruta relativa se resuelve desde el directorio del archivo de lista, no desde el directorio donde lanzas el script. Cada ruta debe ser la raíz de un repositorio git.
# /srv/proyecto/repos.txt
/srv/repos/api
./portal
Ctrl+C interrumpe el lote. Ayuda: ./scripts/update-repos.sh --help.